diff options
author | Stephen Hines <srhines@google.com> | 2014-07-21 00:45:20 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-07-21 00:45:20 -0700 |
commit | c6a4f5e819217e1e12c458aed8e7b122e23a3a58 (patch) | |
tree | 81b7dd2bb4370a392f31d332a566c903b5744764 /lib/Support | |
parent | 19c6fbb3e8aaf74093afa08013134b61fa08f245 (diff) | |
download | external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.zip external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.gz external_llvm-c6a4f5e819217e1e12c458aed8e7b122e23a3a58.tar.bz2 |
Update LLVM for rebase to r212749.
Includes a cherry-pick of:
r212948 - fixes a small issue with atomic calls
Change-Id: Ib97bd980b59f18142a69506400911a6009d9df18
Diffstat (limited to 'lib/Support')
53 files changed, 1624 insertions, 1117 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index f9fe095..7989e30 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1372,7 +1372,9 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): - sign = false; + // We need to be sure to flip the sign here for subtraction because we + // don't have a separate negate operation so -NaN becomes 0 - NaN here. + sign = rhs.sign ^ subtract; category = fcNaN; copySignificand(rhs); return opOK; diff --git a/lib/Support/ARMWinEH.cpp b/lib/Support/ARMWinEH.cpp new file mode 100644 index 0000000..03c150f --- /dev/null +++ b/lib/Support/ARMWinEH.cpp @@ -0,0 +1,38 @@ +//===-- ARMWinEH.cpp - Windows on ARM EH Support Functions ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ARMWinEH.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace ARM { +namespace WinEH { +std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF) { + uint8_t NumRegisters = RF.Reg(); + uint8_t RegistersVFP = RF.R(); + uint8_t LinkRegister = RF.L(); + uint8_t ChainedFrame = RF.C(); + + uint16_t GPRMask = (ChainedFrame << 11) | (LinkRegister << 14); + uint32_t VFPMask = 0; + + if (RegistersVFP) + VFPMask |= (((1 << ((NumRegisters + 1) % 8)) - 1) << 8); + else + GPRMask |= (((1 << (NumRegisters + 1)) - 1) << 4); + + if (PrologueFolding(RF)) + GPRMask |= (((1 << (NumRegisters + 1)) - 1) << (~RF.StackAdjust() & 0x3)); + + return std::make_pair(GPRMask, VFPMask); +} +} +} +} + diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk index 6efccf5..5de8d3f 100644 --- a/lib/Support/Android.mk +++ b/lib/Support/Android.mk @@ -6,6 +6,7 @@ support_SRC_FILES := \ APInt.cpp \ APSInt.cpp \ ARMBuildAttrs.cpp \ + ARMWinEH.cpp \ Atomic.cpp \ BlockFrequency.cpp \ BranchProbability.cpp \ @@ -49,13 +50,16 @@ support_SRC_FILES := \ PrettyStackTrace.cpp \ Process.cpp \ Program.cpp \ + RandomNumberGenerator.cpp \ Regex.cpp \ RWMutex.cpp \ + ScaledNumber.cpp \ SearchForAddressOfSpecialSymbol.cpp \ Signals.cpp \ SmallPtrSet.cpp \ SmallVector.cpp \ SourceMgr.cpp \ + SpecialCaseList.cpp \ Statistic.cpp \ StreamableMemoryObject.cpp \ StringExtras.cpp \ @@ -84,8 +88,7 @@ support_SRC_FILES := \ regerror.c \ regexec.c \ regfree.c \ - regstrlcpy.c \ - system_error.cpp + regstrlcpy.c # For the host diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp index 2ef32b0..ac4ff3e 100644 --- a/lib/Support/Atomic.cpp +++ b/lib/Support/Atomic.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This header file implements atomic operations. +// This file implements atomic operations. // //===----------------------------------------------------------------------===// diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index b4c674d..9ecd559 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -3,6 +3,7 @@ add_llvm_library(LLVMSupport APInt.cpp APSInt.cpp ARMBuildAttrs.cpp + ARMWinEH.cpp Allocator.cpp BlockFrequency.cpp BranchProbability.cpp @@ -40,10 +41,13 @@ add_llvm_library(LLVMSupport MD5.cpp PluginLoader.cpp PrettyStackTrace.cpp + RandomNumberGenerator.cpp Regex.cpp + ScaledNumber.cpp SmallPtrSet.cpp SmallVector.cpp SourceMgr.cpp + SpecialCaseList.cpp Statistic.cpp StreamableMemoryObject.cpp StringExtras.cpp @@ -82,7 +86,6 @@ add_llvm_library(LLVMSupport RWMutex.cpp SearchForAddressOfSpecialSymbol.cpp Signals.cpp - system_error.cpp TargetRegistry.cpp ThreadLocal.cpp Threading.cpp @@ -99,7 +102,6 @@ add_llvm_library(LLVMSupport Unix/Program.inc Unix/RWMutex.inc Unix/Signals.inc - Unix/system_error.inc Unix/ThreadLocal.inc Unix/TimeValue.inc Unix/Watchdog.inc @@ -112,7 +114,6 @@ add_llvm_library(LLVMSupport Windows/Program.inc Windows/RWMutex.inc Windows/Signals.inc - Windows/system_error.inc Windows/ThreadLocal.inc Windows/TimeValue.inc Windows/Watchdog.inc diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 37bbf48..87348f7 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -31,10 +31,10 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" #include <cerrno> #include <cstdlib> #include <map> +#include <system_error> using namespace llvm; using namespace cl; @@ -145,6 +145,7 @@ void OptionCategory::registerCategory() { static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, SmallVectorImpl<Option*> &SinkOpts, StringMap<Option*> &OptionsMap) { + bool HadErrors = false; SmallVector<const char*, 16> OptionNames; Option *CAOpt = nullptr; // The ConsumeAfter option if it exists. for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) { @@ -158,8 +159,9 @@ static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, for (size_t i = 0, e = OptionNames.size(); i != e; ++i) { // Add argument to the argument map! if (OptionsMap.GetOrCreateValue(OptionNames[i], O).second != O) { - errs() << ProgramName << ": CommandLine Error: Argument '" - << OptionNames[i] << "' defined more than once!\n"; + errs() << ProgramName << ": CommandLine Error: Option '" + << OptionNames[i] << "' registered more than once!\n"; + HadErrors = true; } } @@ -171,8 +173,10 @@ static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, else if (O->getMiscFlags() & cl::Sink) // Remember sink options SinkOpts.push_back(O); else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) { - if (CAOpt) + if (CAOpt) { O->error("Cannot specify more than one option with cl::ConsumeAfter!"); + HadErrors = true; + } CAOpt = O; } } @@ -182,6 +186,12 @@ static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, // Make sure that they are in order of registration not backwards. std::reverse(PositionalOpts.begin(), PositionalOpts.end()); + + // Fail hard if there were errors. These are strictly unrecoverable and + // indicate serious issues such as conflicting option names or an incorrectly + // linked LLVM distribution. + if (HadErrors) + report_fatal_error("inconsistency in registered CommandLine options"); } @@ -621,9 +631,11 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, static bool ExpandResponseFile(const char *FName, StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &NewArgv) { - std::unique_ptr<MemoryBuffer> MemBuf; - if (MemoryBuffer::getFile(FName, MemBuf)) + ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = + MemoryBuffer::getFile(FName); + if (!MemBufOrErr) return false; + std::unique_ptr<MemoryBuffer> MemBuf = std::move(MemBufOrErr.get()); StringRef Str(MemBuf->getBufferStart(), MemBuf->getBufferSize()); // If we have a UTF-16 byte order mark, convert to UTF-8 for parsing. @@ -1699,7 +1711,7 @@ public: OS << "LLVM (http://llvm.org/):\n" << " " << PACKAGE_NAME << " version " << PACKAGE_VERSION; #ifdef LLVM_VERSION_INFO - OS << LLVM_VERSION_INFO; + OS << " " << LLVM_VERSION_INFO; #endif OS << "\n "; #ifndef __OPTIMIZE__ diff --git a/lib/Support/ConvertUTF.c b/lib/Support/ConvertUTF.c index 23f17ca..128459a 100644 --- a/lib/Support/ConvertUTF.c +++ b/lib/Support/ConvertUTF.c @@ -51,6 +51,7 @@ #ifdef CVTUTF_DEBUG #include <stdio.h> #endif +#include <assert.h> static const int halfShift = 10; /* used for shifting by 10 bits */ @@ -392,6 +393,99 @@ Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { /* --------------------------------------------------------------------- */ +static unsigned +findMaximalSubpartOfIllFormedUTF8Sequence(const UTF8 *source, + const UTF8 *sourceEnd) { + UTF8 b1, b2, b3; + + assert(!isLegalUTF8Sequence(source, sourceEnd)); + + /* + * Unicode 6.3.0, D93b: + * + * Maximal subpart of an ill-formed subsequence: The longest code unit + * subsequence starting at an unconvertible offset that is either: + * a. the initial subsequence of a well-formed code unit sequence, or + * b. a subsequence of length one. + */ + + if (source == sourceEnd) + return 0; + + /* + * Perform case analysis. See Unicode 6.3.0, Table 3-7. Well-Formed UTF-8 + * Byte Sequences. + */ + + b1 = *source; + ++source; + if (b1 >= 0xC2 && b1 <= 0xDF) { + /* + * First byte is valid, but we know that this code unit sequence is + * invalid, so the maximal subpart has to end after the first byte. + */ + return 1; + } + + if (source == sourceEnd) + return 1; + + b2 = *source; + ++source; + + if (b1 == 0xE0) { + return (b2 >= 0xA0 && b2 <= 0xBF) ? 2 : 1; + } + if (b1 >= 0xE1 && b1 <= 0xEC) { + return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1; + } + if (b1 == 0xED) { + return (b2 >= 0x80 && b2 <= 0x9F) ? 2 : 1; + } + if (b1 >= 0xEE && b1 <= 0xEF) { + return (b2 >= 0x80 && b2 <= 0xBF) ? 2 : 1; + } + if (b1 == 0xF0) { + if (b2 >= 0x90 && b2 <= 0xBF) { + if (source == sourceEnd) + return 2; + + b3 = *source; + return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; + } + return 1; + } + if (b1 >= 0xF1 && b1 <= 0xF3) { + if (b2 >= 0x80 && b2 <= 0xBF) { + if (source == sourceEnd) + return 2; + + b3 = *source; + return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; + } + return 1; + } + if (b1 == 0xF4) { + if (b2 >= 0x80 && b2 <= 0x8F) { + if (source == sourceEnd) + return 2; + + b3 = *source; + return (b3 >= 0x80 && b3 <= 0xBF) ? 3 : 2; + } + return 1; + } + + assert((b1 >= 0x80 && b1 <= 0xC1) || b1 >= 0xF5); + /* + * There are no valid sequences that start with these bytes. Maximal subpart + * is defined to have length 1 in these cases. + */ + return 1; +} + +/* --------------------------------------------------------------------- */ + /* * Exported function to return the total number of bytes in a codepoint * represented in UTF-8, given the value of the first byte. @@ -491,9 +585,10 @@ ConversionResult ConvertUTF8toUTF16 ( /* --------------------------------------------------------------------- */ -ConversionResult ConvertUTF8toUTF32 ( +static ConversionResult ConvertUTF8toUTF32Impl( const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { + UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags, + Boolean InputIsPartial) { ConversionResult result = conversionOK; const UTF8* source = *sourceStart; UTF32* target = *targetStart; @@ -501,12 +596,42 @@ ConversionResult ConvertUTF8toUTF32 ( UTF32 ch = 0; unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; + if (flags == strictConversion || InputIsPartial) { + result = sourceExhausted; + break; + } else { + result = sourceIllegal; + + /* + * Replace the maximal subpart of ill-formed sequence with + * replacement character. + */ + source += findMaximalSubpartOfIllFormedUTF8Sequence(source, + sourceEnd); + *target++ = UNI_REPLACEMENT_CHAR; + continue; + } } + if (target >= targetEnd) { + result = targetExhausted; break; + } + /* Do this check whether lenient or strict */ if (!isLegalUTF8(source, extraBytesToRead+1)) { result = sourceIllegal; - break; + if (flags == strictConversion) { + /* Abort conversion. */ + break; + } else { + /* + * Replace the maximal subpart of ill-formed sequence with + * replacement character. + */ + source += findMaximalSubpartOfIllFormedUTF8Sequence(source, + sourceEnd); + *target++ = UNI_REPLACEMENT_CHAR; + continue; + } } /* * The cases all fall through. See "Note A" below. @@ -521,10 +646,6 @@ ConversionResult ConvertUTF8toUTF32 ( } ch -= offsetsFromUTF8[extraBytesToRead]; - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } if (ch <= UNI_MAX_LEGAL_UTF32) { /* * UTF-16 surrogate values are illegal in UTF-32, and anything @@ -551,6 +672,22 @@ ConversionResult ConvertUTF8toUTF32 ( return result; } +ConversionResult ConvertUTF8toUTF32Partial(const UTF8 **sourceStart, + const UTF8 *sourceEnd, + UTF32 **targetStart, + UTF32 *targetEnd, + ConversionFlags flags) { + return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd, + flags, /*InputIsPartial=*/true); +} + +ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart, + const UTF8 *sourceEnd, UTF32 **targetStart, + UTF32 *targetEnd, ConversionFlags flags) { + return ConvertUTF8toUTF32Impl(sourceStart, sourceEnd, targetStart, targetEnd, + flags, /*InputIsPartial=*/false); +} + /* --------------------------------------------------------------------- Note A. diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index a426377..9b0e443 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -22,7 +22,8 @@ namespace { struct CrashRecoveryContextImpl; -static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext; +static ManagedStatic< + sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext; struct CrashRecoveryContextImpl { CrashRecoveryContext *CRC; @@ -231,7 +232,8 @@ void CrashRecoveryContext::Disable() { #include <signal.h> -static const int Signals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP }; +static const int Signals[] = + { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP }; static const unsigned NumSignals = sizeof(Signals) / sizeof(Signals[0]); static struct sigaction PrevActions[NumSignals]; @@ -330,12 +332,26 @@ const std::string &CrashRecoveryContext::getBacktrace() const { return CRC->Backtrace; } -// +// FIXME: Portability. +static void setThreadBackgroundPriority() { +#ifdef __APPLE__ + setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG); +#endif +} + +static bool hasThreadBackgroundPriority() { +#ifdef __APPLE__ + return getpriority(PRIO_DARWIN_THREAD, 0) == 1; +#else + return false; +#endif +} namespace { struct RunSafelyOnThreadInfo { function_ref<void()> Fn; CrashRecoveryContext *CRC; + bool UseBackgroundPriority; bool Result; }; } @@ -343,11 +359,16 @@ struct RunSafelyOnThreadInfo { static void RunSafelyOnThread_Dispatch(void *UserData) { RunSafelyOnThreadInfo *Info = reinterpret_cast<RunSafelyOnThreadInfo*>(UserData); + + if (Info->UseBackgroundPriority) + setThreadBackgroundPriority(); + Info->Result = Info->CRC->RunSafely(Info->Fn); } bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn, unsigned RequestedStackSize) { - RunSafelyOnThreadInfo Info = { Fn, this, false }; + bool UseBackgroundPriority = hasThreadBackgroundPriority(); + RunSafelyOnThreadInfo Info = { Fn, this, UseBackgroundPriority, false }; llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize); if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl) CRC->setSwitchedThread(); diff --git a/lib/Support/DataExtractor.cpp b/lib/Support/DataExtractor.cpp index 7b82921..5d6d60a 100644 --- a/lib/Support/DataExtractor.cpp +++ b/lib/Support/DataExtractor.cpp @@ -21,7 +21,7 @@ static T getU(uint32_t *offset_ptr, const DataExtractor *de, if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) { std::memcpy(&val, &Data[offset], sizeof(val)); if (sys::IsLittleEndianHost != isLittleEndian) - val = sys::SwapByteOrder(val); + sys::swapByteOrder(val); // Advance the offset *offset_ptr += sizeof(val); diff --git a/lib/Support/DataStream.cpp b/lib/Support/DataStream.cpp index eec8584..32653de 100644 --- a/lib/Support/DataStream.cpp +++ b/lib/Support/DataStream.cpp @@ -18,10 +18,10 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" -#include "llvm/Support/system_error.h" #include <cerrno> #include <cstdio> #include <string> +#include <system_error> #if !defined(_MSC_VER) && !defined(__MINGW32__) #include <unistd.h> #else @@ -64,11 +64,11 @@ public: return read(Fd, buf, len); } - error_code OpenFile(const std::string &Filename) { + std::error_code OpenFile(const std::string &Filename) { if (Filename == "-") { Fd = 0; sys::ChangeStdinToBinary(); - return error_code::success(); + return std::error_code(); } return sys::fs::openFileForRead(Filename, Fd); @@ -81,7 +81,7 @@ namespace llvm { DataStreamer *getDataFileStreamer(const std::string &Filename, std::string *StrError) { DataFileStreamer *s = new DataFileStreamer(); - if (error_code e = s->OpenFile(Filename)) { + if (std::error_code e = s->OpenFile(Filename)) { *StrError = std::string("Could not open ") + Filename + ": " + e.message() + "\n"; return nullptr; diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp index 82d7c0c..d2b551e 100644 --- a/lib/Support/DynamicLibrary.cpp +++ b/lib/Support/DynamicLibrary.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This header file implements the operating system DynamicLibrary concept. +// This file implements the operating system DynamicLibrary concept. // // FIXME: This file leaks ExplicitSymbols and OpenedHandles! // diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp index 342c4f0..c36007f 100644 --- a/lib/Support/ErrorHandling.cpp +++ b/lib/Support/ErrorHandling.cpp @@ -18,8 +18,12 @@ #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/Support/Threading.h" +#include "llvm/Support/WindowsError.h" #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdlib> @@ -37,17 +41,20 @@ using namespace llvm; static fatal_error_handler_t ErrorHandler = nullptr; static void *ErrorHandlerUserData = nullptr; +static sys::Mutex ErrorHandlerMutex; + void llvm::install_fatal_error_handler(fatal_error_handler_t handler, void *user_data) { - assert(!llvm_is_multithreaded() && - "Cannot register error handlers after starting multithreaded mode!\n"); + llvm::MutexGuard Lock(ErrorHandlerMutex); assert(!ErrorHandler && "Error handler already registered!\n"); ErrorHandler = handler; ErrorHandlerUserData = user_data; } void llvm::remove_fatal_error_handler() { + llvm::MutexGuard Lock(ErrorHandlerMutex); ErrorHandler = nullptr; + ErrorHandlerUserData = nullptr; } void llvm::report_fatal_error(const char *Reason, bool GenCrashDiag) { @@ -63,8 +70,18 @@ void llvm::report_fatal_error(StringRef Reason, bool GenCrashDiag) { } void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { - if (ErrorHandler) { - ErrorHandler(ErrorHandlerUserData, Reason.str(), GenCrashDiag); + llvm::fatal_error_handler_t handler = nullptr; + void* handlerData = nullptr; + { + // Only acquire the mutex while reading the handler, so as not to invoke a + // user-supplied callback under a lock. + llvm::MutexGuard Lock(ErrorHandlerMutex); + handler = ErrorHandler; + handlerData = ErrorHandlerUserData; + } + + if (handler) { + handler(handlerData, Reason.str(), GenCrashDiag); } else { // Blast the result out to stderr. We don't try hard to make sure this // succeeds (e.g. handling EINTR) and we can't use errs() here because @@ -119,3 +136,70 @@ void LLVMInstallFatalErrorHandler(LLVMFatalErrorHandler Handler) { void LLVMResetFatalErrorHandler() { remove_fatal_error_handler(); } + +#ifdef LLVM_ON_WIN32 + +#include <winerror.h> + +// I'd rather not double the line count of the following. +#define MAP_ERR_TO_COND(x, y) \ + case x: \ + return make_error_code(errc::y) + +std::error_code llvm::mapWindowsError(unsigned EV) { + switch (EV) { + MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied); + MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists); + MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device); + MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long); + MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied); + MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error); + MAP_ERR_TO_COND(ERROR_CANTREAD, io_error); + MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error); + MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied); + MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device); + MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty); + MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument); + MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device); + MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists); + MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory); + MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device); + MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied); + MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device); + MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported); + MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument); + MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument); + MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available); + MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available); + MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument); + MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied); + MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory); + MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again); + MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error); + MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy); + MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory); + MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory); + MAP_ERR_TO_COND(ERROR_BAD_NETPATH, no_such_file_or_directory); + MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error); + MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again); + MAP_ERR_TO_COND(ERROR_SEEK, io_error); + MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied); + MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open); + MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error); + MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied); + MAP_ERR_TO_COND(WSAEACCES, permission_denied); + MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor); + MAP_ERR_TO_COND(WSAEFAULT, bad_address); + MAP_ERR_TO_COND(WSAEINTR, interrupted); + MAP_ERR_TO_COND(WSAEINVAL, invalid_argument); + MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open); + MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long); + default: + return std::error_code(EV, std::system_category()); + } +} + +#endif diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp index 49311c2..2e740ca 100644 --- a/lib/Support/FileOutputBuffer.cpp +++ b/lib/Support/FileOutputBuffer.cpp @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" +#include <system_error> using llvm::sys::fs::mapped_file_region; @@ -30,13 +31,13 @@ FileOutputBuffer::~FileOutputBuffer() { sys::fs::remove(Twine(TempPath)); } -error_code FileOutputBuffer::create(StringRef FilePath, - size_t Size, - std::unique_ptr<FileOutputBuffer> &Result, - unsigned Flags) { +std::error_code +FileOutputBuffer::create(StringRef FilePath, size_t Size, + std::unique_ptr<FileOutputBuffer> &Result, + unsigned Flags) { // If file already exists, it must be a regular file (to be mappable). sys::fs::file_status Stat; - error_code EC = sys::fs::status(FilePath, Stat); + std::error_code EC = sys::fs::status(FilePath, Stat); switch (Stat.type()) { case sys::fs::file_type::file_not_found: // If file does not exist, we'll create one. @@ -81,16 +82,16 @@ error_code FileOutputBuffer::create(StringRef FilePath, if (Result) MappedFile.release(); - return error_code::success(); + return std::error_code(); } -error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { +std::error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { // Unmap buffer, letting OS flush dirty pages to file on disk. Region.reset(nullptr); // If requested, resize file as part of commit. if ( NewSmallerSize != -1 ) { - error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); + std::error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); if (EC) return EC; } diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp index b2dc47d..8a23491 100644 --- a/lib/Support/FileUtilities.cpp +++ b/lib/Support/FileUtilities.cpp @@ -17,10 +17,10 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" #include <cctype> #include <cstdlib> #include <cstring> +#include <system_error> using namespace llvm; static bool isSignedChar(char C) { @@ -176,18 +176,21 @@ int llvm::DiffFilesWithTolerance(StringRef NameA, std::string *Error) { // Now its safe to mmap the files into memory because both files // have a non-zero size. - std::unique_ptr<MemoryBuffer> F1; - if (error_code ec = MemoryBuffer::getFile(NameA, F1)) { + ErrorOr<std::unique_ptr<MemoryBuffer>> F1OrErr = MemoryBuffer::getFile(NameA); + if (std::error_code EC = F1OrErr.getError()) { if (Error) - *Error = ec.message(); + *Error = EC.message(); return 2; } - std::unique_ptr<MemoryBuffer> F2; - if (error_code ec = MemoryBuffer::getFile(NameB, F2)) { + std::unique_ptr<MemoryBuffer> F1 = std::move(F1OrErr.get()); + + ErrorOr<std::unique_ptr<MemoryBuffer>> F2OrErr = MemoryBuffer::getFile(NameB); + if (std::error_code EC = F2OrErr.getError()) { if (Error) - *Error = ec.message(); + *Error = EC.message(); return 2; } + std::unique_ptr<MemoryBuffer> F2 = std::move(F2OrErr.get()); // Okay, now that we opened the files, scan them for the first difference. const char *File1Start = F1->getBufferStart(); diff --git a/lib/Support/GraphWriter.cpp b/lib/Support/GraphWriter.cpp index f5b2943..e68ee43 100644 --- a/lib/Support/GraphWriter.cpp +++ b/lib/Support/GraphWriter.cpp @@ -68,7 +68,7 @@ StringRef llvm::DOT::getColorString(unsigned ColorNumber) { std::string llvm::createGraphFilename(const Twine &Name, int &FD) { FD = -1; SmallString<128> Filename; - error_code EC = sys::fs::createTemporaryFile(Name, "dot", FD, Filename); + std::error_code EC = sys::fs::createTemporaryFile(Name, "dot", FD, Filename); if (EC) { errs() << "Error: " << EC.message() << "\n"; return ""; @@ -78,148 +78,165 @@ std::string llvm::createGraphFilename(const Twine &Name, int &FD) { return Filename.str(); } -// Execute the graph viewer. Return true if successful. -static bool LLVM_ATTRIBUTE_UNUSED -ExecGraphViewer(StringRef ExecPath, std::vector<const char*> &args, - StringRef Filename, bool wait, std::string &ErrMsg) { +// Execute the graph viewer. Return true if there were errors. +static bool ExecGraphViewer(StringRef ExecPath, std::vector<const char *> &args, + StringRef Filename, bool wait, + std::string &ErrMsg) { + assert(args.back() == nullptr); if (wait) { - if (sys::ExecuteAndWait(ExecPath, &args[0],nullptr,nullptr,0,0,&ErrMsg)) { + if (sys::ExecuteAndWait(ExecPath, args.data(), nullptr, nullptr, 0, 0, + &ErrMsg)) { errs() << "Error: " << ErrMsg << "\n"; - return false; + return true; } sys::fs::remove(Filename); errs() << " done. \n"; - } - else { - sys::ExecuteNoWait(ExecPath, &args[0],nullptr,nullptr,0,&ErrMsg); + } else { + sys::ExecuteNoWait(ExecPath, args.data(), nullptr, nullptr, 0, &ErrMsg); errs() << "Remember to erase graph file: " << Filename.str() << "\n"; } - return true; + return false; +} + +struct GraphSession { + std::string LogBuffer; + bool TryFindProgram(StringRef Names, std::string &ProgramPath) { + raw_string_ostream Log(LogBuffer); + SmallVector<StringRef, 8> parts; + Names.split(parts, "|"); + for (auto Name : parts) { + ProgramPath = sys::FindProgramByName(Name); + if (!ProgramPath.empty()) + return true; + Log << " Tried '" << Name << "'\n"; + } + return false; + } +}; + +static const char *getProgramName(GraphProgram::Name program) { + switch (program) { + case GraphProgram::DOT: + return "dot"; + case GraphProgram::FDP: + return "fdp"; + case GraphProgram::NEATO: + return "neato"; + case GraphProgram::TWOPI: + return "twopi"; + case GraphProgram::CIRCO: + return "circo"; + } + llvm_unreachable("bad kind"); } -void llvm::DisplayGraph(StringRef FilenameRef, bool wait, +bool llvm::DisplayGraph(StringRef FilenameRef, bool wait, GraphProgram::Name program) { std::string Filename = FilenameRef; wait &= !ViewBackground; std::string ErrMsg; -#if HAVE_GRAPHVIZ - std::string Graphviz(LLVM_PATH_GRAPHVIZ); - - std::vector<const char*> args; - args.push_back(Graphviz.c_str()); - args.push_back(Filename.c_str()); - args.push_back(nullptr); - - errs() << "Running 'Graphviz' program... "; - if (!ExecGraphViewer(Graphviz, args, Filename, wait, ErrMsg)) - return; - -#elif HAVE_XDOT - std::vector<const char*> args; - args.push_back(LLVM_PATH_XDOT); - args.push_back(Filename.c_str()); - - switch (program) { - case GraphProgram::DOT: args.push_back("-f"); args.push_back("dot"); break; - case GraphProgram::FDP: args.push_back("-f"); args.push_back("fdp"); break; - case GraphProgram::NEATO: args.push_back("-f"); args.push_back("neato");break; - case GraphProgram::TWOPI: args.push_back("-f"); args.push_back("twopi");break; - case GraphProgram::CIRCO: args.push_back("-f"); args.push_back("circo");break; + std::string ViewerPath; + GraphSession S; + + // Graphviz + if (S.TryFindProgram("Graphviz", ViewerPath)) { + std::vector<const char *> args; + args.push_back(ViewerPath.c_str()); + args.push_back(Filename.c_str()); + args.push_back(nullptr); + + errs() << "Running 'Graphviz' program... "; + return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg); } - args.push_back(0); + // xdot + if (S.TryFindProgram("xdot|xdot.py", ViewerPath)) { + std::vector<const char *> args; + args.push_back(ViewerPath.c_str()); + args.push_back(Filename.c_str()); - errs() << "Running 'xdot.py' program... "; - if (!ExecGraphViewer(LLVM_PATH_XDOT, args, Filename, wait, ErrMsg)) - return; + args.push_back("-f"); + args.push_back(getProgramName(program)); -#elif (HAVE_GV && (HAVE_DOT || HAVE_FDP || HAVE_NEATO || \ - HAVE_TWOPI || HAVE_CIRCO)) - std::string PSFilename = Filename + ".ps"; - std::string prog; + args.push_back(nullptr); - // Set default grapher -#if HAVE_CIRCO - prog = LLVM_PATH_CIRCO; -#endif -#if HAVE_TWOPI - prog = LLVM_PATH_TWOPI; -#endif -#if HAVE_NEATO - prog = LLVM_PATH_NEATO; -#endif -#if HAVE_FDP - prog = LLVM_PATH_FDP; -#endif -#if HAVE_DOT - prog = LLVM_PATH_DOT; -#endif + errs() << "Running 'xdot.py' program... "; + return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg); + } - // Find which program the user wants -#if HAVE_DOT - if (program == GraphProgram::DOT) - prog = LLVM_PATH_DOT; -#endif -#if (HAVE_FDP) - if (program == GraphProgram::FDP) - prog = LLVM_PATH_FDP; -#endif -#if (HAVE_NEATO) - if (program == GraphProgram::NEATO) - prog = LLVM_PATH_NEATO; -#endif -#if (HAVE_TWOPI) - if (program == GraphProgram::TWOPI) - prog = LLVM_PATH_TWOPI; -#endif -#if (HAVE_CIRCO) - if (program == GraphProgram::CIRCO) - prog = LLVM_PATH_CIRCO; + enum PSViewerKind { PSV_None, PSV_OSXOpen, PSV_XDGOpen, PSV_Ghostview }; + PSViewerKind PSViewer = PSV_None; +#ifdef __APPLE__ + if (!PSViewer && S.TryFindProgram("open", ViewerPath)) + PSViewer = PSV_OSXOpen; #endif + if (!PSViewer && S.TryFindProgram("gv", ViewerPath)) + PSViewer = PSV_Ghostview; + if (!PSViewer && S.TryFindProgram("xdg-open", ViewerPath)) + PSViewer = PSV_XDGOpen; + + // PostScript graph generator + PostScript viewer + std::string GeneratorPath; + if (PSViewer && + (S.TryFindProgram(getProgramName(program), GeneratorPath) || + S.TryFindProgram("dot|fdp|neato|twopi|circo", GeneratorPath))) { + std::string PSFilename = Filename + ".ps"; + + std::vector<const char *> args; + args.push_back(GeneratorPath.c_str()); + args.push_back("-Tps"); + args.push_back("-Nfontname=Courier"); + args.push_back("-Gsize=7.5,10"); + args.push_back(Filename.c_str()); + args.push_back("-o"); + args.push_back(PSFilename.c_str()); + args.push_back(nullptr); + + errs() << "Running '" << GeneratorPath << "' program... "; + + if (ExecGraphViewer(GeneratorPath, args, Filename, wait, ErrMsg)) + return true; + + args.clear(); + args.push_back(ViewerPath.c_str()); + switch (PSViewer) { + case PSV_OSXOpen: + args.push_back("-W"); + args.push_back(PSFilename.c_str()); + break; + case PSV_XDGOpen: + wait = false; + args.push_back(PSFilename.c_str()); + break; + case PSV_Ghostview: + args.push_back("--spartan"); + args.push_back(PSFilename.c_str()); + break; + case PSV_None: + llvm_unreachable("Invalid viewer"); + } + args.push_back(nullptr); - std::vector<const char*> args; - args.push_back(prog.c_str()); - args.push_back("-Tps"); - args.push_back("-Nfontname=Courier"); - args.push_back("-Gsize=7.5,10"); - args.push_back(Filename.c_str()); - args.push_back("-o"); - args.push_back(PSFilename.c_str()); - args.push_back(0); - - errs() << "Running '" << prog << "' program... "; - - if (!ExecGraphViewer(prog, args, Filename, wait, ErrMsg)) - return; - - std::string gv(LLVM_PATH_GV); - args.clear(); - args.push_back(gv.c_str()); - args.push_back(PSFilename.c_str()); - args.push_back("--spartan"); - args.push_back(0); - - ErrMsg.clear(); - if (!ExecGraphViewer(gv, args, PSFilename, wait, ErrMsg)) - return; - -#elif HAVE_DOTTY - std::string dotty(LLVM_PATH_DOTTY); + ErrMsg.clear(); + return ExecGraphViewer(ViewerPath, args, PSFilename, wait, ErrMsg); + } - std::vector<const char*> args; - args.push_back(dotty.c_str()); - args.push_back(Filename.c_str()); - args.push_back(0); + // dotty + if (S.TryFindProgram("dotty", ViewerPath)) { + std::vector<const char *> args; + args.push_back(ViewerPath.c_str()); + args.push_back(Filename.c_str()); + args.push_back(nullptr); // Dotty spawns another app and doesn't wait until it returns -#if defined (__MINGW32__) || defined (_WINDOWS) - wait = false; -#endif - errs() << "Running 'dotty' program... "; - if (!ExecGraphViewer(dotty, args, Filename, wait, ErrMsg)) - return; -#else - (void)Filename; - (void)ErrMsg; +#ifdef LLVM_ON_WIN32 + wait = false; #endif + errs() << "Running 'dotty' program... "; + return ExecGraphViewer(ViewerPath, args, Filename, wait, ErrMsg); + } + + errs() << "Error: Couldn't find a usable graph viewer program:\n"; + errs() << S.LogBuffer << "\n"; + return true; } diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index fd0472e..e2dd6d5 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This header file implements the operating system Host concept. +// This file implements the operating system Host concept. // //===----------------------------------------------------------------------===// @@ -570,6 +570,8 @@ StringRef sys::getHostCPUName() { .Case("A2", "a2") .Case("POWER6", "pwr6") .Case("POWER7", "pwr7") + .Case("POWER8", "pwr8") + .Case("POWER8E", "pwr8") .Default(generic); } #elif defined(__linux__) && defined(__arm__) @@ -744,7 +746,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { .Default(""); #if defined(__aarch64__) - // We need to check crypto seperately since we need all of the crypto + // We need to check crypto separately since we need all of the crypto // extensions to enable the subtarget feature if (CPUFeatures[I] == "aes") crypto |= CAP_AES; diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp index 9b4bfbe..3f224e0 100644 --- a/lib/Support/LockFileManager.cpp +++ b/lib/Support/LockFileManager.cpp @@ -9,6 +9,7 @@ #include "llvm/Support/LockFileManager.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -32,11 +33,13 @@ Optional<std::pair<std::string, int> > LockFileManager::readLockFile(StringRef LockFileName) { // Read the owning host and PID out of the lock file. If it appears that the // owning process is dead, the lock file is invalid. - std::unique_ptr<MemoryBuffer> MB; - if (MemoryBuffer::getFile(LockFileName, MB)) { + ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = + MemoryBuffer::getFile(LockFileName); + if (!MBOrErr) { sys::fs::remove(LockFileName); return None; } + std::unique_ptr<MemoryBuffer> MB = std::move(MBOrErr.get()); StringRef Hostname; StringRef PIDStr; @@ -71,7 +74,7 @@ bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { LockFileManager::LockFileManager(StringRef FileName) { this->FileName = FileName; - if (error_code EC = sys::fs::make_absolute(this->FileName)) { + if (std::error_code EC = sys::fs::make_absolute(this->FileName)) { Error = EC; return; } @@ -87,10 +90,8 @@ LockFileManager::LockFileManager(StringRef FileName) UniqueLockFileName = LockFileName; UniqueLockFileName += "-%%%%%%%%"; int UniqueLockFileID; - if (error_code EC - = sys::fs::createUniqueFile(UniqueLockFileName.str(), - UniqueLockFileID, - UniqueLockFileName)) { + if (std::error_code EC = sys::fs::createUniqueFile( + UniqueLockFileName.str(), UniqueLockFileID, UniqueLockFileName)) { Error = EC; return; } @@ -122,9 +123,9 @@ LockFileManager::LockFileManager(StringRef FileName) while (1) { // Create a link from the lock file name. If this succeeds, we're done. - error_code EC = + std::error_code EC = sys::fs::create_link(UniqueLockFileName.str(), LockFileName.str()); - if (EC == errc::success) + if (!EC) return; if (EC != errc::file_exists) { diff --git a/lib/Support/Makefile b/lib/Support/Makefile index 4a2185d..39426aa 100644 --- a/lib/Support/Makefile +++ b/lib/Support/Makefile @@ -17,3 +17,7 @@ include $(LEVEL)/Makefile.common CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) + +ifdef LLVM_VERSION_INFO +CompileCommonOpts += -DLLVM_VERSION_INFO='"$(LLVM_VERSION_INFO)"' +endif diff --git a/lib/Support/ManagedStatic.cpp b/lib/Support/ManagedStatic.cpp index 6a1c2a5..b8fb284 100644 --- a/lib/Support/ManagedStatic.cpp +++ b/lib/Support/ManagedStatic.cpp @@ -14,16 +14,26 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Config/config.h" #include "llvm/Support/Atomic.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #include <cassert> using namespace llvm; static const ManagedStaticBase *StaticList = nullptr; +static sys::Mutex& getManagedStaticMutex() { + // We need to use a function local static here, since this can get called + // during a static constructor and we need to guarantee that it's initialized + // correctly. + static sys::Mutex ManagedStaticMutex; + return ManagedStaticMutex; +} + void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), void (*Deleter)(void*)) const { assert(Creator); if (llvm_is_multithreaded()) { - llvm_acquire_global_lock(); + MutexGuard Lock(getManagedStaticMutex()); if (!Ptr) { void* tmp = Creator(); @@ -43,8 +53,6 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), Next = StaticList; StaticList = this; } - - llvm_release_global_lock(); } else { assert(!Ptr && !DeleterFn && !Next && "Partially initialized ManagedStatic!?"); @@ -75,8 +83,8 @@ void ManagedStaticBase::destroy() const { /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. void llvm::llvm_shutdown() { + MutexGuard Lock(getManagedStaticMutex()); + while (StaticList) StaticList->destroy(); - - if (llvm_is_multithreaded()) llvm_stop_multithreaded(); } diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index 629d885..5f4b7da 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -14,19 +14,20 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" +#include "llvm/Support/Errc.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" -#include "llvm/Support/system_error.h" #include <cassert> #include <cerrno> #include <cstdio> #include <cstring> #include <new> #include <sys/types.h> +#include <system_error> #if !defined(_MSC_VER) && !defined(__MINGW32__) #include <unistd.h> #else @@ -151,17 +152,11 @@ MemoryBuffer *MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { return SB; } - -/// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin -/// if the Filename is "-". If an error occurs, this returns null and fills -/// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) -/// returns an empty buffer. -error_code MemoryBuffer::getFileOrSTDIN(StringRef Filename, - std::unique_ptr<MemoryBuffer> &Result, - int64_t FileSize) { +ErrorOr<std::unique_ptr<MemoryBuffer>> +MemoryBuffer::getFileOrSTDIN(StringRef Filename, int64_t FileSize) { if (Filename == "-") - return getSTDIN(Result); - return getFile(Filename, Result, FileSize); + return getSTDIN(); + return getFile(Filename, FileSize); } @@ -190,7 +185,7 @@ class MemoryBufferMMapFile : public MemoryBuffer { public: MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len, - uint64_t Offset, error_code EC) + uint64_t Offset, std::error_code EC) : MFR(FD, false, sys::fs::mapped_file_region::readonly, getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) { if (!EC) { @@ -210,9 +205,8 @@ public: }; } -static error_code getMemoryBufferForStream(int FD, - StringRef BufferName, - std::unique_ptr<MemoryBuffer> &Result) { +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getMemoryBufferForStream(int FD, StringRef BufferName) { const ssize_t ChunkSize = 4096*4; SmallString<ChunkSize> Buffer; ssize_t ReadBytes; @@ -222,52 +216,48 @@ static error_code getMemoryBufferForStream(int FD, ReadBytes = read(FD, Buffer.end(), ChunkSize); if (ReadBytes == -1) { if (errno == EINTR) continue; - return error_code(errno, posix_category()); + return std::error_code(errno, std::generic_category()); } Buffer.set_size(Buffer.size() + ReadBytes); } while (ReadBytes != 0); - Result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); - return error_code::success(); + std::unique_ptr<MemoryBuffer> Ret( + MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); + return std::move(Ret); } -static error_code getFileAux(const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, - int64_t FileSize, - bool RequiresNullTerminator, - bool IsVolatileSize); - -error_code MemoryBuffer::getFile(Twine Filename, - std::unique_ptr<MemoryBuffer> &Result, - int64_t FileSize, - bool RequiresNullTerminator, - bool IsVolatileSize) { +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getFileAux(const char *Filename, int64_t FileSize, bool RequiresNullTerminator, + bool IsVolatileSize); + +ErrorOr<std::unique_ptr<MemoryBuffer>> +MemoryBuffer::getFile(Twine Filename, int64_t FileSize, + bool RequiresNullTerminator, bool IsVolatileSize) { // Ensure the path is null terminated. SmallString<256> PathBuf; StringRef NullTerminatedName = Filename.toNullTerminatedStringRef(PathBuf); - return getFileAux(NullTerminatedName.data(), Result, FileSize, - RequiresNullTerminator, IsVolatileSize); + return getFileAux(NullTerminatedName.data(), FileSize, RequiresNullTerminator, + IsVolatileSize); } -static error_code getOpenFileImpl(int FD, const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, - uint64_t FileSize, uint64_t MapSize, - int64_t Offset, bool RequiresNullTerminator, - bool IsVolatileSize); +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getOpenFileImpl(int FD, const char *Filename, uint64_t FileSize, + uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, + bool IsVolatileSize); -static error_code getFileAux(const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, int64_t FileSize, - bool RequiresNullTerminator, - bool IsVolatileSize) { +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getFileAux(const char *Filename, int64_t FileSize, bool RequiresNullTerminator, + bool IsVolatileSize) { int FD; - error_code EC = sys::fs::openFileForRead(Filename, FD); + std::error_code EC = sys::fs::openFileForRead(Filename, FD); if (EC) return EC; - error_code ret = getOpenFileImpl(FD, Filename, Result, FileSize, FileSize, 0, - RequiresNullTerminator, IsVolatileSize); + ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = + getOpenFileImpl(FD, Filename, FileSize, FileSize, 0, + RequiresNullTerminator, IsVolatileSize); close(FD); - return ret; + return Ret; } static bool shouldUseMmap(int FD, @@ -318,11 +308,10 @@ static bool shouldUseMmap(int FD, return true; } -static error_code getOpenFileImpl(int FD, const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, - uint64_t FileSize, uint64_t MapSize, - int64_t Offset, bool RequiresNullTerminator, - bool IsVolatileSize) { +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getOpenFileImpl(int FD, const char *Filename, uint64_t FileSize, + uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, + bool IsVolatileSize) { static int PageSize = sys::process::get_self()->page_size(); // Default is to map the full file. @@ -331,7 +320,7 @@ static error_code getOpenFileImpl(int FD, const char *Filename, // file descriptor is cheaper than stat on a random path. if (FileSize == uint64_t(-1)) { sys::fs::file_status Status; - error_code EC = sys::fs::status(FD, Status); + std::error_code EC = sys::fs::status(FD, Status); if (EC) return EC; @@ -341,7 +330,7 @@ static error_code getOpenFileImpl(int FD, const char *Filename, sys::fs::file_type Type = Status.type(); if (Type != sys::fs::file_type::regular_file && Type != sys::fs::file_type::block_file) - return getMemoryBufferForStream(FD, Filename, Result); + return getMemoryBufferForStream(FD, Filename); FileSize = Status.getSize(); } @@ -350,11 +339,12 @@ static error_code getOpenFileImpl(int FD, const char *Filename, if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, PageSize, IsVolatileSize)) { - error_code EC; - Result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile( - RequiresNullTerminator, FD, MapSize, Offset, EC)); + std::error_code EC; + std::unique_ptr<MemoryBuffer> Result( + new (NamedBufferAlloc(Filename)) + MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC)); if (!EC) - return error_code::success(); + return std::move(Result); } MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); @@ -370,7 +360,7 @@ static error_code getOpenFileImpl(int FD, const char *Filename, size_t BytesLeft = MapSize; #ifndef HAVE_PREAD if (lseek(FD, Offset, SEEK_SET) == -1) - return error_code(errno, posix_category()); + return std::error_code(errno, std::generic_category()); #endif while (BytesLeft) { @@ -383,7 +373,7 @@ static error_code getOpenFileImpl(int FD, const char *Filename, if (errno == EINTR) continue; // Error while reading. - return error_code(errno, posix_category()); + return std::error_code(errno, std::generic_category()); } if (NumRead == 0) { memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer. @@ -393,37 +383,29 @@ static error_code getOpenFileImpl(int FD, const char *Filename, BufPtr += NumRead; } - Result.swap(SB); - return error_code::success(); + return std::move(SB); } -error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, - uint64_t FileSize, - bool RequiresNullTerminator, - bool IsVolatileSize) { - return getOpenFileImpl(FD, Filename, Result, FileSize, FileSize, 0, +ErrorOr<std::unique_ptr<MemoryBuffer>> +MemoryBuffer::getOpenFile(int FD, const char *Filename, uint64_t FileSize, + bool RequiresNullTerminator, bool IsVolatileSize) { + return getOpenFileImpl(FD, Filename, FileSize, FileSize, 0, RequiresNullTerminator, IsVolatileSize); } -error_code MemoryBuffer::getOpenFileSlice(int FD, const char *Filename, - std::unique_ptr<MemoryBuffer> &Result, - uint64_t MapSize, int64_t Offset, - bool IsVolatileSize) { - return getOpenFileImpl(FD, Filename, Result, -1, MapSize, Offset, false, +ErrorOr<std::unique_ptr<MemoryBuffer>> +MemoryBuffer::getOpenFileSlice(int FD, const char *Filename, uint64_t MapSize, + int64_t Offset, bool IsVolatileSize) { + return getOpenFileImpl(FD, Filename, -1, MapSize, Offset, false, IsVolatileSize); } -//===----------------------------------------------------------------------===// -// MemoryBuffer::getSTDIN implementation. -//===----------------------------------------------------------------------===// - -error_code MemoryBuffer::getSTDIN(std::unique_ptr<MemoryBuffer> &Result) { +ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() { // Read in all of the data from stdin, we cannot mmap stdin. // // FIXME: That isn't necessarily true, we should try to mmap stdin and // fallback if it fails. sys::ChangeStdinToBinary(); - return getMemoryBufferForStream(0, "<stdin>", Result); + return getMemoryBufferForStream(0, "<stdin>"); } diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp index b8d676f..d5a0ec5 100644 --- a/lib/Support/Path.cpp +++ b/lib/Support/Path.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/Path.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" @@ -164,12 +165,12 @@ enum FSEntity { }; // Implemented in Unix/Path.inc and Windows/Path.inc. -static error_code TempDir(SmallVectorImpl<char> &result); +static std::error_code TempDir(SmallVectorImpl<char> &result); -static error_code createUniqueEntity(const Twine &Model, int &ResultFD, - SmallVectorImpl<char> &ResultPath, - bool MakeAbsolute, unsigned Mode, - FSEntity Type) { +static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, + SmallVectorImpl<char> &ResultPath, + bool MakeAbsolute, unsigned Mode, + FSEntity Type) { SmallString<128> ModelStorage; Model.toVector(ModelStorage); @@ -177,7 +178,7 @@ static error_code createUniqueEntity(const Twine &Model, int &ResultFD, // Make model absolute by prepending a temp directory if it's not already. if (!sys::path::is_absolute(Twine(ModelStorage))) { SmallString<128> TDir; - if (error_code EC = TempDir(TDir)) + if (std::error_code EC = TempDir(TDir)) return EC; sys::path::append(TDir, Twine(ModelStorage)); ModelStorage.swap(TDir); @@ -201,7 +202,7 @@ retry_random_path: // Try to open + create the file. switch (Type) { case FS_File: { - if (error_code EC = + if (std::error_code EC = sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD, sys::fs::F_RW | sys::fs::F_Excl, Mode)) { if (EC == errc::file_exists) @@ -209,26 +210,27 @@ retry_random_path: return EC; } - return error_code::success(); + return std::error_code(); } case FS_Name: { bool Exists; - error_code EC = sys::fs::exists(ResultPath.begin(), Exists); + std::error_code EC = sys::fs::exists(ResultPath.begin(), Exists); if (EC) return EC; if (Exists) goto retry_random_path; - return error_code::success(); + return std::error_code(); } case FS_Dir: { - if (error_code EC = sys::fs::create_directory(ResultPath.begin(), false)) { + if (std::error_code EC = + sys::fs::create_directory(ResultPath.begin(), false)) { if (EC == errc::file_exists) goto retry_random_path; return EC; } - return error_code::success(); + return std::error_code(); } } llvm_unreachable("Invalid Type"); @@ -705,29 +707,30 @@ bool is_relative(const Twine &path) { namespace fs { -error_code getUniqueID(const Twine Path, UniqueID &Result) { +std::error_code getUniqueID(const Twine Path, UniqueID &Result) { file_status Status; - error_code EC = status(Path, Status); + std::error_code EC = status(Path, Status); if (EC) return EC; Result = Status.getUniqueID(); - return error_code::success(); + return std::error_code(); } -error_code createUniqueFile(const Twine &Model, int &ResultFd, - SmallVectorImpl<char> &ResultPath, unsigned Mode) { +std::error_code createUniqueFile(const Twine &Model, int &ResultFd, + SmallVectorImpl<char> &ResultPath, + unsigned Mode) { return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File); } -error_code createUniqueFile(const Twine &Model, - SmallVectorImpl<char> &ResultPath) { +std::error_code createUniqueFile(const Twine &Model, + SmallVectorImpl<char> &ResultPath) { int Dummy; return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name); } -static error_code createTemporaryFile(const Twine &Model, int &ResultFD, - llvm::SmallVectorImpl<char> &ResultPath, - FSEntity Type) { +static std::error_code +createTemporaryFile(const Twine &Model, int &ResultFD, + llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) { SmallString<128> Storage; StringRef P = Model.toNullTerminatedStringRef(Storage); assert(P.find_first_of(separators) == StringRef::npos && @@ -737,24 +740,22 @@ static error_code createTemporaryFile(const Twine &Model, int &ResultFD, true, owner_read | owner_write, Type); } -static error_code +static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, - llvm::SmallVectorImpl<char> &ResultPath, - FSEntity Type) { + llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) { const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%."; return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath, Type); } - -error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, - int &ResultFD, - SmallVectorImpl<char> &ResultPath) { +std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, + int &ResultFD, + SmallVectorImpl<char> &ResultPath) { return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File); } -error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, - SmallVectorImpl<char> &ResultPath) { +std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, + SmallVectorImpl<char> &ResultPath) { int Dummy; return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name); } @@ -762,14 +763,14 @@ error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly // for consistency. We should try using mkdtemp. -error_code createUniqueDirectory(const Twine &Prefix, - SmallVectorImpl<char> &ResultPath) { +std::error_code createUniqueDirectory(const Twine &Prefix, + SmallVectorImpl<char> &ResultPath) { int Dummy; return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath, true, 0, FS_Dir); } -error_code make_absolute(SmallVectorImpl<char> &path) { +std::error_code make_absolute(SmallVectorImpl<char> &path) { StringRef p(path.data(), path.size()); bool rootDirectory = path::has_root_directory(p), @@ -781,11 +782,12 @@ error_code make_absolute(SmallVectorImpl<char> &path) { // Already absolute. if (rootName && rootDirectory) - return error_code::success(); + return std::error_code(); // All of the following conditions will need the current directory. SmallString<128> current_dir; - if (error_code ec = current_path(current_dir)) return ec; + if (std::error_code ec = current_path(current_dir)) + return ec; // Relative path. Prepend the current directory. if (!rootName && !rootDirectory) { @@ -793,7 +795,7 @@ error_code make_absolute(SmallVectorImpl<char> &path) { path::append(current_dir, p); // Set path to the result. path.swap(current_dir); - return error_code::success(); + return std::error_code(); } if (!rootName && rootDirectory) { @@ -802,7 +804,7 @@ error_code make_absolute(SmallVectorImpl<char> &path) { path::append(curDirRootName, p); // Set path to the result. path.swap(curDirRootName); - return error_code::success(); + return std::error_code(); } if (rootName && !rootDirectory) { @@ -814,19 +816,19 @@ error_code make_absolute(SmallVectorImpl<char> &path) { SmallString<128> res; path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath); path.swap(res); - return error_code::success(); + return std::error_code(); } llvm_unreachable("All rootName and rootDirectory combinations should have " "occurred above!"); } -error_code create_directories(const Twine &Path, bool IgnoreExisting) { +std::error_code create_directories(const Twine &Path, bool IgnoreExisting) { SmallString<128> PathStorage; StringRef P = Path.toStringRef(PathStorage); // Be optimistic and try to create the directory - error_code EC = create_directory(P, IgnoreExisting); + std::error_code EC = create_directory(P, IgnoreExisting); // If we succeeded, or had any error other than the parent not existing, just // return it. if (EC != errc::no_such_file_or_directory) @@ -844,6 +846,40 @@ error_code create_directories(const Twine &Path, bool IgnoreExisting) { return create_directory(P, IgnoreExisting); } +std::error_code copy_file(const Twine &From, const Twine &To) { + int ReadFD, WriteFD; + if (std::error_code EC = openFileForRead(From, ReadFD)) + return EC; + if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) { + close(ReadFD); + return EC; + } + + const size_t BufSize = 4096; + char *Buf = new char[BufSize]; + int BytesRead = 0, BytesWritten = 0; + for (;;) { + BytesRead = read(ReadFD, Buf, BufSize); + if (BytesRead <= 0) + break; + while (BytesRead) { + BytesWritten = write(WriteFD, Buf, BytesRead); + if (BytesWritten < 0) + break; + BytesRead -= BytesWritten; + } + if (BytesWritten < 0) + break; + } + close(ReadFD); + close(WriteFD); + delete[] Buf; + + if (BytesRead < 0 || BytesWritten < 0) + return std::error_code(errno, std::generic_category()); + return std::error_code(); +} + bool exists(file_status status) { return status_known(status) && status.type() != file_type::file_not_found; } @@ -856,24 +892,24 @@ bool is_directory(file_status status) { return status.type() == file_type::directory_file; } -error_code is_directory(const Twine &path, bool &result) { +std::error_code is_directory(const Twine &path, bool &result) { file_status st; - if (error_code ec = status(path, st)) + if (std::error_code ec = status(path, st)) return ec; result = is_directory(st); - return error_code::success(); + return std::error_code(); } bool is_regular_file(file_status status) { return status.type() == file_type::regular_file; } -error_code is_regular_file(const Twine &path, bool &result) { +std::error_code is_regular_file(const Twine &path, bool &result) { file_status st; - if (error_code ec = status(path, st)) + if (std::error_code ec = status(path, st)) return ec; result = is_regular_file(st); - return error_code::success(); + return std::error_code(); } bool is_other(file_status status) { @@ -890,26 +926,8 @@ void directory_entry::replace_filename(const Twine &filename, file_status st) { Status = st; } -error_code has_magic(const Twine &path, const Twine &magic, bool &result) { - SmallString<32> MagicStorage; - StringRef Magic = magic.toStringRef(MagicStorage); - SmallString<32> Buffer; - - if (error_code ec = get_magic(path, Magic.size(), Buffer)) { - if (ec == errc::value_too_large) { - // Magic.size() > file_size(Path). - result = false; - return error_code::success(); - } - return ec; - } - - result = Magic == Buffer; - return error_code::success(); -} - /// @brief Identify the magic in magic. - file_magic identify_magic(StringRef Magic) { +file_magic identify_magic(StringRef Magic) { if (Magic.size() < 4) return file_magic::unknown; switch ((unsigned char)Magic[0]) { @@ -1040,17 +1058,21 @@ error_code has_magic(const Twine &path, const Twine &magic, bool &result) { return file_magic::unknown; } -error_code identify_magic(const Twine &path, file_magic &result) { - SmallString<32> Magic; - error_code ec = get_magic(path, Magic.capacity(), Magic); - if (ec && ec != errc::value_too_large) - return ec; +std::error_code identify_magic(const Twine &Path, file_magic &Result) { + int FD; + if (std::error_code EC = openFileForRead(Path, FD)) + return EC; + + char Buffer[32]; + int Length = read(FD, Buffer, sizeof(Buffer)); + if (close(FD) != 0 || Length < 0) + return std::error_code(errno, std::generic_category()); - result = identify_magic(Magic); - return error_code::success(); + Result = identify_magic(StringRef(Buffer, Length)); + return std::error_code(); } -error_code directory_entry::status(file_status &result) const { +std::error_code directory_entry::status(file_status &result) const { return fs::status(Path, result); } diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp index 0380ed9..0d42e0e 100644 --- a/lib/Support/Process.cpp +++ b/lib/Support/Process.cpp @@ -7,13 +7,16 @@ // //===----------------------------------------------------------------------===// // -// This header file implements the operating system Process concept. +// This file implements the operating system Process concept. // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Process.h" +#include "llvm/Support/Program.h" using namespace llvm; using namespace sys; @@ -66,6 +69,33 @@ TimeValue self_process::get_wall_time() const { return getElapsedWallTime(); } +Optional<std::string> Process::FindInEnvPath(const std::string& EnvName, + const std::string& FileName) +{ + Optional<std::string> FoundPath; + Optional<std::string> OptPath = Process::GetEnv(EnvName); + if (!OptPath.hasValue()) + return FoundPath; + + const char EnvPathSeparatorStr[] = {EnvPathSeparator, '\0'}; + SmallVector<StringRef, 8> Dirs; + SplitString(OptPath.getValue(), Dirs, EnvPathSeparatorStr); + + for (const auto &Dir : Dirs) { + if (Dir.empty()) + continue; + + SmallString<128> FilePath(Dir); + path::append(FilePath, FileName); + if (fs::exists(Twine(FilePath))) { + FoundPath = FilePath.str(); + break; + } + } + + return FoundPath; +} + #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m" diff --git a/lib/Support/Program.cpp b/lib/Support/Program.cpp index 83f2ec4..b84b82b 100644 --- a/lib/Support/Program.cpp +++ b/lib/Support/Program.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This header file implements the operating system Program concept. +// This file implements the operating system Program concept. // //===----------------------------------------------------------------------===// #include "llvm/Support/Program.h" #include "llvm/Config/config.h" -#include "llvm/Support/system_error.h" +#include <system_error> using namespace llvm; using namespace sys; @@ -34,7 +34,8 @@ int sys::ExecuteAndWait(StringRef Program, const char **args, const char **envp, if (Execute(PI, Program, args, envp, redirects, memoryLimit, ErrMsg)) { if (ExecutionFailed) *ExecutionFailed = false; - ProcessInfo Result = Wait(PI, secondsToWait, true, ErrMsg); + ProcessInfo Result = Wait( + PI, secondsToWait, /*WaitUntilTerminates=*/secondsToWait == 0, ErrMsg); return Result.ReturnCode; } diff --git a/lib/Support/RandomNumberGenerator.cpp b/lib/Support/RandomNumberGenerator.cpp new file mode 100644 index 0000000..c50e7cb --- /dev/null +++ b/lib/Support/RandomNumberGenerator.cpp @@ -0,0 +1,61 @@ +//===-- RandomNumberGenerator.cpp - Implement RNG class -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements random number generation (RNG). +// The current implementation is NOT cryptographically secure as it uses +// the C++11 <random> facilities. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "rng" +#include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; + +// Tracking BUG: 19665 +// http://llvm.org/bugs/show_bug.cgi?id=19665 +// +// Do not change to cl::opt<uint64_t> since this silently breaks argument parsing. +static cl::opt<unsigned long long> +Seed("rng-seed", cl::value_desc("seed"), + cl::desc("Seed for the random number generator"), cl::init(0)); + +RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) { + DEBUG( + if (Seed == 0) + errs() << "Warning! Using unseeded random number generator.\n" + ); + + // Combine seed and salt using std::seed_seq. + // Entropy: Seed-low, Seed-high, Salt... + std::vector<uint32_t> Data; + Data.reserve(2 + Salt.size()/4 + 1); + Data.push_back(Seed); + Data.push_back(Seed >> 32); + + uint32_t Pack = 0; + for (size_t I = 0; I < Salt.size(); ++I) { + Pack <<= 8; + Pack += Salt[I]; + + if (I%4 == 3) + Data.push_back(Pack); + } + Data.push_back(Pack); + + std::seed_seq SeedSeq(Data.begin(), Data.end()); + Generator.seed(SeedSeq); +} + +uint64_t RandomNumberGenerator::next(uint64_t Max) { + std::uniform_int_distribution<uint64_t> distribution(0, Max - 1); + return distribution(Generator); +} diff --git a/lib/Support/ScaledNumber.cpp b/lib/Support/ScaledNumber.cpp new file mode 100644 index 0000000..3fe027b --- /dev/null +++ b/lib/Support/ScaledNumber.cpp @@ -0,0 +1,319 @@ +//==- lib/Support/ScaledNumber.cpp - Support for scaled numbers -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of some scaled number algorithms. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ScaledNumber.h" + +#include "llvm/ADT/APFloat.h" +#include "llvm/Support/Debug.h" + +using namespace llvm; +using namespace llvm::ScaledNumbers; + +std::pair<uint64_t, int16_t> ScaledNumbers::multiply64(uint64_t LHS, + uint64_t RHS) { + // Separate into two 32-bit digits (U.L). + auto getU = [](uint64_t N) { return N >> 32; }; + auto getL = [](uint64_t N) { return N & UINT32_MAX; }; + uint64_t UL = getU(LHS), LL = getL(LHS), UR = getU(RHS), LR = getL(RHS); + + // Compute cross products. + uint64_t P1 = UL * UR, P2 = UL * LR, P3 = LL * UR, P4 = LL * LR; + + // Sum into two 64-bit digits. + uint64_t Upper = P1, Lower = P4; + auto addWithCarry = [&](uint64_t N) { + uint64_t NewLower = Lower + (getL(N) << 32); + Upper += getU(N) + (NewLower < Lower); + Lower = NewLower; + }; + addWithCarry(P2); + addWithCarry(P3); + + // Check whether the upper digit is empty. + if (!Upper) + return std::make_pair(Lower, 0); + + // Shift as little as possible to maximize precision. + unsigned LeadingZeros = countLeadingZeros(Upper); + int Shift = 64 - LeadingZeros; + if (LeadingZeros) + Upper = Upper << LeadingZeros | Lower >> Shift; + return getRounded(Upper, Shift, + Shift && (Lower & UINT64_C(1) << (Shift - 1))); +} + +static uint64_t getHalf(uint64_t N) { return (N >> 1) + (N & 1); } + +std::pair<uint32_t, int16_t> ScaledNumbers::divide32(uint32_t Dividend, + uint32_t Divisor) { + assert(Dividend && "expected non-zero dividend"); + assert(Divisor && "expected non-zero divisor"); + + // Use 64-bit math and canonicalize the dividend to gain precision. + uint64_t Dividend64 = Dividend; + int Shift = 0; + if (int Zeros = countLeadingZeros(Dividend64)) { + Shift -= Zeros; + Dividend64 <<= Zeros; + } + uint64_t Quotient = Dividend64 / Divisor; + uint64_t Remainder = Dividend64 % Divisor; + + // If Quotient needs to be shifted, leave the rounding to getAdjusted(). + if (Quotient > UINT32_MAX) + return getAdjusted<uint32_t>(Quotient, Shift); + + // Round based on the value of the next bit. + return getRounded<uint32_t>(Quotient, Shift, Remainder >= getHalf(Divisor)); +} + +std::pair<uint64_t, int16_t> ScaledNumbers::divide64(uint64_t Dividend, + uint64_t Divisor) { + assert(Dividend && "expected non-zero dividend"); + assert(Divisor && "expected non-zero divisor"); + + // Minimize size of divisor. + int Shift = 0; + if (int Zeros = countTrailingZeros(Divisor)) { + Shift -= Zeros; + Divisor >>= Zeros; + } + + // Check for powers of two. + if (Divisor == 1) + return std::make_pair(Dividend, Shift); + + // Maximize size of dividend. + if (int Zeros = countLeadingZeros(Dividend)) { + Shift -= Zeros; + Dividend <<= Zeros; + } + + // Start with the result of a divide. + uint64_t Quotient = Dividend / Divisor; + Dividend %= Divisor; + + // Continue building the quotient with long division. + while (!(Quotient >> 63) && Dividend) { + // Shift Dividend and check for overflow. + bool IsOverflow = Dividend >> 63; + Dividend <<= 1; + --Shift; + + // Get the next bit of Quotient. + Quotient <<= 1; + if (IsOverflow || Divisor <= Dividend) { + Quotient |= 1; + Dividend -= Divisor; + } + } + + return getRounded(Quotient, Shift, Dividend >= getHalf(Divisor)); +} + +int ScaledNumbers::compareImpl(uint64_t L, uint64_t R, int ScaleDiff) { + assert(ScaleDiff >= 0 && "wrong argument order"); + assert(ScaleDiff < 64 && "numbers too far apart"); + + uint64_t L_adjusted = L >> ScaleDiff; + if (L_adjusted < R) + return -1; + if (L_adjusted > R) + return 1; + + return L > L_adjusted << ScaleDiff ? 1 : 0; +} + +static void appendDigit(std::string &Str, unsigned D) { + assert(D < 10); + Str += '0' + D % 10; +} + +static void appendNumber(std::string &Str, uint64_t N) { + while (N) { + appendDigit(Str, N % 10); + N /= 10; + } +} + +static bool doesRoundUp(char Digit) { + switch (Digit) { + case '5': + case '6': + case '7': + case '8': + case '9': + return true; + default: + return false; + } +} + +static std::string toStringAPFloat(uint64_t D, int E, unsigned Precision) { + assert(E >= ScaledNumbers::MinScale); + assert(E <= ScaledNumbers::MaxScale); + + // Find a new E, but don't let it increase past MaxScale. + int LeadingZeros = ScaledNumberBase::countLeadingZeros64(D); + int NewE = std::min(ScaledNumbers::MaxScale, E + 63 - LeadingZeros); + int Shift = 63 - (NewE - E); + assert(Shift <= LeadingZeros); + assert(Shift == LeadingZeros || NewE == ScaledNumbers::MaxScale); + D <<= Shift; + E = NewE; + + // Check for a denormal. + unsigned AdjustedE = E + 16383; + if (!(D >> 63)) { + assert(E == ScaledNumbers::MaxScale); + AdjustedE = 0; + } + + // Build the float and print it. + uint64_t RawBits[2] = {D, AdjustedE}; + APFloat Float(APFloat::x87DoubleExtended, APInt(80, RawBits)); + SmallVector<char, 24> Chars; + Float.toString(Chars, Precision, 0); + return std::string(Chars.begin(), Chars.end()); +} + +static std::string stripTrailingZeros(const std::string &Float) { + size_t NonZero = Float.find_last_not_of('0'); + assert(NonZero != std::string::npos && "no . in floating point string"); + + if (Float[NonZero] == '.') + ++NonZero; + + return Float.substr(0, NonZero + 1); +} + +std::string ScaledNumberBase::toString(uint64_t D, int16_t E, int Width, + unsigned Precision) { + if (!D) + return "0.0"; + + // Canonicalize exponent and digits. + uint64_t Above0 = 0; + uint64_t Below0 = 0; + uint64_t Extra = 0; + int ExtraShift = 0; + if (E == 0) { + Above0 = D; + } else if (E > 0) { + if (int Shift = std::min(int16_t(countLeadingZeros64(D)), E)) { + D <<= Shift; + E -= Shift; + + if (!E) + Above0 = D; + } + } else if (E > -64) { + Above0 = D >> -E; + Below0 = D << (64 + E); + } else if (E > -120) { + Below0 = D >> (-E - 64); + Extra = D << (128 + E); + ExtraShift = -64 - E; + } + + // Fall back on APFloat for very small and very large numbers. + if (!Above0 && !Below0) + return toStringAPFloat(D, E, Precision); + + // Append the digits before the decimal. + std::string Str; + size_t DigitsOut = 0; + if (Above0) { + appendNumber(Str, Above0); + DigitsOut = Str.size(); + } else + appendDigit(Str, 0); + std::reverse(Str.begin(), Str.end()); + + // Return early if there's nothing after the decimal. + if (!Below0) + return Str + ".0"; + + // Append the decimal and beyond. + Str += '.'; + uint64_t Error = UINT64_C(1) << (64 - Width); + + // We need to shift Below0 to the right to make space for calculating + // digits. Save the precision we're losing in Extra. + Extra = (Below0 & 0xf) << 56 | (Extra >> 8); + Below0 >>= 4; + size_t SinceDot = 0; + size_t AfterDot = Str.size(); + do { + if (ExtraShift) { + --ExtraShift; + Error *= 5; + } else + Error *= 10; + + Below0 *= 10; + Extra *= 10; + Below0 += (Extra >> 60); + Extra = Extra & (UINT64_MAX >> 4); + appendDigit(Str, Below0 >> 60); + Below0 = Below0 & (UINT64_MAX >> 4); + if (DigitsOut || Str.back() != '0') + ++DigitsOut; + ++SinceDot; + } while (Error && (Below0 << 4 | Extra >> 60) >= Error / 2 && + (!Precision || DigitsOut <= Precision || SinceDot < 2)); + + // Return early for maximum precision. + if (!Precision || DigitsOut <= Precision) + return stripTrailingZeros(Str); + + // Find where to truncate. + size_t Truncate = + std::max(Str.size() - (DigitsOut - Precision), AfterDot + 1); + + // Check if there's anything to truncate. + if (Truncate >= Str.size()) + return stripTrailingZeros(Str); + + bool Carry = doesRoundUp(Str[Truncate]); + if (!Carry) + return stripTrailingZeros(Str.substr(0, Truncate)); + + // Round with the first truncated digit. + for (std::string::reverse_iterator I(Str.begin() + Truncate), E = Str.rend(); + I != E; ++I) { + if (*I == '.') + continue; + if (*I == '9') { + *I = '0'; + continue; + } + + ++*I; + Carry = false; + break; + } + + // Add "1" in front if we still need to carry. + return stripTrailingZeros(std::string(Carry, '1') + Str.substr(0, Truncate)); +} + +raw_ostream &ScaledNumberBase::print(raw_ostream &OS, uint64_t D, int16_t E, + int Width, unsigned Precision) { + return OS << toString(D, E, Width, Precision); +} + +void ScaledNumberBase::dump(uint64_t D, int16_t E, int Width) { + print(dbgs(), D, E, Width, 0) << "[" << Width << ":" << D << "*2^" << E + << "]"; +} diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp index acd75fb..003cb56 100644 --- a/lib/Support/SourceMgr.cpp +++ b/lib/Support/SourceMgr.cpp @@ -20,14 +20,14 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" +#include <system_error> using namespace llvm; static const size_t TabStop = 8; namespace { struct LineNoCacheTy { - int LastQueryBufferID; + unsigned LastQueryBufferID; const char *LastQuery; unsigned LineNoOfQuery; }; @@ -49,48 +49,44 @@ SourceMgr::~SourceMgr() { } } -/// AddIncludeFile - Search for a file with the specified name in the current -/// directory or in one of the IncludeDirs. If no file is found, this returns -/// ~0, otherwise it returns the buffer ID of the stacked file. -size_t SourceMgr::AddIncludeFile(const std::string &Filename, - SMLoc IncludeLoc, - std::string &IncludedFile) { - std::unique_ptr<MemoryBuffer> NewBuf; +unsigned SourceMgr::AddIncludeFile(const std::string &Filename, + SMLoc IncludeLoc, + std::string &IncludedFile) { IncludedFile = Filename; - MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf); + ErrorOr<std::unique_ptr<MemoryBuffer>> NewBufOrErr = + MemoryBuffer::getFile(IncludedFile.c_str()); // If the file didn't exist directly, see if it's in an include path. - for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) { - IncludedFile = IncludeDirectories[i] + sys::path::get_separator().data() + Filename; - MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf); + for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBufOrErr; + ++i) { + IncludedFile = + IncludeDirectories[i] + sys::path::get_separator().data() + Filename; + NewBufOrErr = MemoryBuffer::getFile(IncludedFile.c_str()); } - if (!NewBuf) return ~0U; + if (!NewBufOrErr) + return 0; - return AddNewSourceBuffer(NewBuf.release(), IncludeLoc); + return AddNewSourceBuffer(NewBufOrErr.get().release(), IncludeLoc); } - -/// FindBufferContainingLoc - Return the ID of the buffer containing the -/// specified location, returning -1 if not found. -int SourceMgr::FindBufferContainingLoc(SMLoc Loc) const { +unsigned SourceMgr::FindBufferContainingLoc(SMLoc Loc) const { for (unsigned i = 0, e = Buffers.size(); i != e; ++i) if (Loc.getPointer() >= Buffers[i].Buffer->getBufferStart() && // Use <= here so that a pointer to the null at the end of the buffer // is included as part of the buffer. Loc.getPointer() <= Buffers[i].Buffer->getBufferEnd()) - return i; - return -1; + return i + 1; + return 0; } -/// getLineAndColumn - Find the line and column number for the specified -/// location in the specified file. This is not a fast method. std::pair<unsigned, unsigned> -SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const { - if (BufferID == -1) BufferID = FindBufferContainingLoc(Loc); - assert(BufferID != -1 && "Invalid Location!"); +SourceMgr::getLineAndColumn(SMLoc Loc, unsigned BufferID) const { + if (!BufferID) + BufferID = FindBufferContainingLoc(Loc); + assert(BufferID && "Invalid Location!"); - MemoryBuffer *Buff = getBufferInfo(BufferID).Buffer; + const MemoryBuffer *Buff = getMemoryBuffer(BufferID); // Count the number of \n's between the start of the file and the specified // location. @@ -132,8 +128,8 @@ SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const { void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const { if (IncludeLoc == SMLoc()) return; // Top of stack. - int CurBuf = FindBufferContainingLoc(IncludeLoc); - assert(CurBuf != -1 && "Invalid or unspecified location!"); + unsigned CurBuf = FindBufferContainingLoc(IncludeLoc); + assert(CurBuf && "Invalid or unspecified location!"); PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); @@ -143,11 +139,6 @@ void SourceMgr::PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const { } -/// GetMessage - Return an SMDiagnostic at the specified location with the -/// specified string. -/// -/// @param Type - If non-null, the kind of message (e.g., "error") which is -/// prefixed to the message. SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges, @@ -161,10 +152,10 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, std::string LineStr; if (Loc.isValid()) { - int CurBuf = FindBufferContainingLoc(Loc); - assert(CurBuf != -1 && "Invalid or unspecified location!"); + unsigned CurBuf = FindBufferContainingLoc(Loc); + assert(CurBuf && "Invalid or unspecified location!"); - MemoryBuffer *CurMB = getBufferInfo(CurBuf).Buffer; + const MemoryBuffer *CurMB = getMemoryBuffer(CurBuf); BufferID = CurMB->getBufferIdentifier(); // Scan backward to find the start of the line. @@ -211,27 +202,30 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind, LineStr, ColRanges, FixIts); } -void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc, - SourceMgr::DiagKind Kind, - const Twine &Msg, ArrayRef<SMRange> Ranges, - ArrayRef<SMFixIt> FixIts, bool ShowColors) const { - SMDiagnostic Diagnostic = GetMessage(Loc, Kind, Msg, Ranges, FixIts); - +void SourceMgr::PrintMessage(raw_ostream &OS, const SMDiagnostic &Diagnostic, + bool ShowColors) const { // Report the message with the diagnostic handler if present. if (DiagHandler) { DiagHandler(Diagnostic, DiagContext); return; } - if (Loc != SMLoc()) { - int CurBuf = FindBufferContainingLoc(Loc); - assert(CurBuf != -1 && "Invalid or unspecified location!"); + if (Diagnostic.getLoc().isValid()) { + unsigned CurBuf = FindBufferContainingLoc(Diagnostic.getLoc()); + assert(CurBuf && "Invalid or unspecified location!"); PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS); } Diagnostic.print(nullptr, OS, ShowColors); } +void SourceMgr::PrintMessage(raw_ostream &OS, SMLoc Loc, + SourceMgr::DiagKind Kind, + const Twine &Msg, ArrayRef<SMRange> Ranges, + ArrayRef<SMFixIt> FixIts, bool ShowColors) const { + PrintMessage(OS, GetMessage(Loc, Kind, Msg, Ranges, FixIts), ShowColors); +} + void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg, ArrayRef<SMRange> Ranges, ArrayRef<SMFixIt> FixIts, bool ShowColors) const { diff --git a/lib/Support/SpecialCaseList.cpp b/lib/Support/SpecialCaseList.cpp new file mode 100644 index 0000000..21e43c5 --- /dev/null +++ b/lib/Support/SpecialCaseList.cpp @@ -0,0 +1,170 @@ +//===-- SpecialCaseList.cpp - special case list for sanitizers ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a utility class for instrumentation passes (like AddressSanitizer +// or ThreadSanitizer) to avoid instrumenting some functions or global +// variables, or to instrument some functions or global variables in a specific +// way, based on a user-supplied list. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/SpecialCaseList.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Regex.h" +#include "llvm/Support/raw_ostream.h" +#include <string> +#include <system_error> +#include <utility> + +namespace llvm { + +/// Represents a set of regular expressions. Regular expressions which are +/// "literal" (i.e. no regex metacharacters) are stored in Strings, while all +/// others are represented as a single pipe-separated regex in RegEx. The +/// reason for doing so is efficiency; StringSet is much faster at matching +/// literal strings than Regex. +struct SpecialCaseList::Entry { + Entry() {} + Entry(Entry &&Other) + : Strings(std::move(Other.Strings)), RegEx(std::move(Other.RegEx)) {} + + StringSet<> Strings; + std::unique_ptr<Regex> RegEx; + + bool match(StringRef Query) const { + return Strings.count(Query) || (RegEx && RegEx->match(Query)); + } +}; + +SpecialCaseList::SpecialCaseList() : Entries() {} + +SpecialCaseList *SpecialCaseList::create( + const StringRef Path, std::string &Error) { + if (Path.empty()) + return new SpecialCaseList(); + ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = + MemoryBuffer::getFile(Path); + if (std::error_code EC = FileOrErr.getError()) { + Error = (Twine("Can't open file '") + Path + "': " + EC.message()).str(); + return nullptr; + } + return create(FileOrErr.get().get(), Error); +} + +SpecialCaseList *SpecialCaseList::create( + const MemoryBuffer *MB, std::string &Error) { + std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList()); + if (!SCL->parse(MB, Error)) + return nullptr; + return SCL.release(); +} + +SpecialCaseList *SpecialCaseList::createOrDie(const StringRef Path) { + std::string Error; + if (SpecialCaseList *SCL = create(Path, Error)) + return SCL; + report_fatal_error(Error); +} + +bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) { + // Iterate through each line in the blacklist file. + SmallVector<StringRef, 16> Lines; + SplitString(MB->getBuffer(), Lines, "\n\r"); + StringMap<StringMap<std::string> > Regexps; + assert(Entries.empty() && + "parse() should be called on an empty SpecialCaseList"); + int LineNo = 1; + for (SmallVectorImpl<StringRef>::iterator I = Lines.begin(), E = Lines.end(); + I != E; ++I, ++LineNo) { + // Ignore empty lines and lines starting with "#" + if (I->empty() || I->startswith("#")) + continue; + // Get our prefix and unparsed regexp. + std::pair<StringRef, StringRef> SplitLine = I->split(":"); + StringRef Prefix = SplitLine.first; + if (SplitLine.second.empty()) { + // Missing ':' in the line. + Error = (Twine("Malformed line ") + Twine(LineNo) + ": '" + + SplitLine.first + "'").str(); + return false; + } + + std::pair<StringRef, StringRef> SplitRegexp = SplitLine.second.split("="); + std::string Regexp = SplitRegexp.first; + StringRef Category = SplitRegexp.second; + + // Backwards compatibility. + if (Prefix == "global-init") { + Prefix = "global"; + Category = "init"; + } else if (Prefix == "global-init-type") { + Prefix = "type"; + Category = "init"; + } else if (Prefix == "global-init-src") { + Prefix = "src"; + Category = "init"; + } + + // See if we can store Regexp in Strings. + if (Regex::isLiteralERE(Regexp)) { + Entries[Prefix][Category].Strings.insert(Regexp); + continue; + } + + // Replace * with .* + for (size_t pos = 0; (pos = Regexp.find("*", pos)) != std::string::npos; + pos += strlen(".*")) { + Regexp.replace(pos, strlen("*"), ".*"); + } + + // Check that the regexp is valid. + Regex CheckRE(Regexp); + std::string REError; + if (!CheckRE.isValid(REError)) { + Error = (Twine("Malformed regex in line ") + Twine(LineNo) + ": '" + + SplitLine.second + "': " + REError).str(); + return false; + } + + // Add this regexp into the proper group by its prefix. + if (!Regexps[Prefix][Category].empty()) + Regexps[Prefix][Category] += "|"; + Regexps[Prefix][Category] += "^" + Regexp + "$"; + } + + // Iterate through each of the prefixes, and create Regexs for them. + for (StringMap<StringMap<std::string> >::const_iterator I = Regexps.begin(), + E = Regexps.end(); + I != E; ++I) { + for (StringMap<std::string>::const_iterator II = I->second.begin(), + IE = I->second.end(); + II != IE; ++II) { + Entries[I->getKey()][II->getKey()].RegEx.reset(new Regex(II->getValue())); + } + } + return true; +} + +SpecialCaseList::~SpecialCaseList() {} + +bool SpecialCaseList::inSection(const StringRef Section, const StringRef Query, + const StringRef Category) const { + StringMap<StringMap<Entry> >::const_iterator I = Entries.find(Section); + if (I == Entries.end()) return false; + StringMap<Entry>::const_iterator II = I->second.find(Category); + if (II == I->second.end()) return false; + + return II->getValue().match(Query); +} + +} // namespace llvm diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp index 72a6d82..ddb7349 100644 --- a/lib/Support/StringMap.cpp +++ b/lib/Support/StringMap.cpp @@ -181,7 +181,7 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) { /// RehashTable - Grow the table, redistributing values into the buckets with /// the appropriate mod-of-hashtable-size. -void StringMapImpl::RehashTable() { +unsigned StringMapImpl::RehashTable(unsigned BucketNo) { unsigned NewSize; unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1); @@ -193,9 +193,10 @@ void StringMapImpl::RehashTable() { } else if (NumBuckets-(NumItems+NumTombstones) <= NumBuckets/8) { NewSize = NumBuckets; } else { - return; + return BucketNo; } + unsigned NewBucketNo = BucketNo; // Allocate one extra bucket which will always be non-empty. This allows the // iterators to stop at end. StringMapEntryBase **NewTableArray = @@ -215,6 +216,8 @@ void StringMapImpl::RehashTable() { if (!NewTableArray[NewBucket]) { NewTableArray[FullHash & (NewSize-1)] = Bucket; NewHashArray[FullHash & (NewSize-1)] = FullHash; + if (I == BucketNo) + NewBucketNo = NewBucket; continue; } @@ -227,6 +230,8 @@ void StringMapImpl::RehashTable() { // Finally found a slot. Fill it in. NewTableArray[NewBucket] = Bucket; NewHashArray[NewBucket] = FullHash; + if (I == BucketNo) + NewBucketNo = NewBucket; } } @@ -235,4 +240,5 @@ void StringMapImpl::RehashTable() { TheTable = NewTableArray; NumBuckets = NewSize; NumTombstones = 0; + return NewBucketNo; } diff --git a/lib/Support/StringPool.cpp b/lib/Support/StringPool.cpp index ff607cf..76faabc 100644 --- a/lib/Support/StringPool.cpp +++ b/lib/Support/StringPool.cpp @@ -27,7 +27,7 @@ PooledStringPtr StringPool::intern(StringRef Key) { if (I != InternTable.end()) return PooledStringPtr(&*I); - entry_t *S = entry_t::Create(Key.begin(), Key.end()); + entry_t *S = entry_t::Create(Key); S->getValue().Pool = this; InternTable.insert(S); diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index a008831..f691883 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -116,17 +116,6 @@ void TargetRegistry::RegisterTarget(Target &T, T.HasJIT = HasJIT; } -const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) { - const Target *TheTarget = lookupTarget(sys::getDefaultTargetTriple(), Error); - - if (TheTarget && !TheTarget->hasJIT()) { - Error = "No JIT compatible target available for this host"; - return nullptr; - } - - return TheTarget; -} - static int TargetArraySortFn(const std::pair<StringRef, const Target *> *LHS, const std::pair<StringRef, const Target *> *RHS) { return LHS->first.compare(RHS->first); diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp index 1acfa79..ca7f3f6 100644 --- a/lib/Support/Threading.cpp +++ b/lib/Support/Threading.cpp @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file implements llvm_start_multithreaded() and friends. +// This file defines helper functions for running LLVM in a multi-threaded +// environment. // //===----------------------------------------------------------------------===// @@ -19,50 +20,14 @@ using namespace llvm; -static bool multithreaded_mode = false; - -static sys::Mutex* global_lock = nullptr; - -bool llvm::llvm_start_multithreaded() { +bool llvm::llvm_is_multithreaded() { #if LLVM_ENABLE_THREADS != 0 - assert(!multithreaded_mode && "Already multithreaded!"); - multithreaded_mode = true; - global_lock = new sys::Mutex(true); - - // We fence here to ensure that all initialization is complete BEFORE we - // return from llvm_start_multithreaded(). - sys::MemoryFence(); return true; #else return false; #endif } -void llvm::llvm_stop_multithreaded() { -#if LLVM_ENABLE_THREADS != 0 - assert(multithreaded_mode && "Not currently multithreaded!"); - - // We fence here to insure that all threaded operations are complete BEFORE we - // return from llvm_stop_multithreaded(). - sys::MemoryFence(); - - multithreaded_mode = false; - delete global_lock; -#endif -} - -bool llvm::llvm_is_multithreaded() { - return multithreaded_mode; -} - -void llvm::llvm_acquire_global_lock() { - if (multithreaded_mode) global_lock->acquire(); -} - -void llvm::llvm_release_global_lock() { - if (multithreaded_mode) global_lock->release(); -} - #if LLVM_ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) #include <pthread.h> diff --git a/lib/Support/TimeValue.cpp b/lib/Support/TimeValue.cpp index bd8af17..4a70797 100644 --- a/lib/Support/TimeValue.cpp +++ b/lib/Support/TimeValue.cpp @@ -53,7 +53,7 @@ TimeValue::normalize( void ) { } -/// Include the platform specific portion of TimeValue class +/// Include the platform-specific portion of TimeValue class #ifdef LLVM_ON_UNIX #include "Unix/TimeValue.inc" #endif diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp index 61465ae..210bda7 100644 --- a/lib/Support/Timer.cpp +++ b/lib/Support/Timer.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -84,14 +85,13 @@ static TimerGroup *getDefaultTimerGroup() { sys::MemoryFence(); if (tmp) return tmp; - llvm_acquire_global_lock(); + sys::SmartScopedLock<true> Lock(*TimerLock); tmp = DefaultTimerGroup; if (!tmp) { tmp = new TimerGroup("Miscellaneous Ungrouped Timers"); sys::MemoryFence(); DefaultTimerGroup = tmp; } - llvm_release_global_lock(); return tmp; } diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index b3d48fb..b74ee13 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -50,6 +50,7 @@ const char *Triple::getArchTypeName(ArchType Kind) { case amdil: return "amdil"; case spir: return "spir"; case spir64: return "spir64"; + case kalimba: return "kalimba"; } llvm_unreachable("Invalid ArchType!"); @@ -101,6 +102,7 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case amdil: return "amdil"; case spir: return "spir"; case spir64: return "spir"; + case kalimba: return "kalimba"; } } @@ -115,7 +117,9 @@ const char *Triple::getVendorTypeName(VendorType Kind) { case BGQ: return "bgq"; case Freescale: return "fsl"; case IBM: return "ibm"; + case ImaginationTechnologies: return "img"; case NVIDIA: return "nvidia"; + case CSR: return "csr"; } llvm_unreachable("Invalid VendorType!"); @@ -207,6 +211,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("amdil", amdil) .Case("spir", spir) .Case("spir64", spir64) + .Case("kalimba", kalimba) .Default(UnknownArch); } @@ -280,6 +285,7 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("amdil", Triple::amdil) .Case("spir", Triple::spir) .Case("spir64", Triple::spir64) + .Case("kalimba", Triple::kalimba) .Default(Triple::UnknownArch); } @@ -292,7 +298,9 @@ static Triple::VendorType parseVendor(StringRef VendorName) { .Case("bgq", Triple::BGQ) .Case("fsl", Triple::Freescale) .Case("ibm", Triple::IBM) + .Case("img", Triple::ImaginationTechnologies) .Case("nvidia", Triple::NVIDIA) + .Case("csr", Triple::CSR) .Default(Triple::UnknownVendor); } @@ -737,9 +745,8 @@ void Triple::setObjectFormat(ObjectFormatType Kind) { if (Environment == UnknownEnvironment) return setEnvironmentName(getObjectFormatTypeName(Kind)); - Twine Env = getEnvironmentTypeName(Environment) + Twine("-") + - getObjectFormatTypeName(Kind); - setEnvironmentName(Env.str()); + setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + + getObjectFormatTypeName(Kind)).str()); } void Triple::setArchName(StringRef Str) { @@ -799,6 +806,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::x86: case llvm::Triple::xcore: case llvm::Triple::spir: + case llvm::Triple::kalimba: return 32; case llvm::Triple::arm64: @@ -850,6 +858,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::arm: case Triple::armeb: case Triple::hexagon: + case Triple::kalimba: case Triple::le32: case Triple::mips: case Triple::mipsel: @@ -884,6 +893,7 @@ Triple Triple::get64BitArchVariant() const { case Triple::arm: case Triple::armeb: case Triple::hexagon: + case Triple::kalimba: case Triple::le32: case Triple::msp430: case Triple::r600: diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc index 23b49b7..c9d89a8 100644 --- a/lib/Support/Unix/Memory.inc +++ b/lib/Support/Unix/Memory.inc @@ -83,8 +83,8 @@ MemoryBlock Memory::allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned PFlags, - error_code &EC) { - EC = error_code::success(); + std::error_code &EC) { + EC = std::error_code(); if (NumBytes == 0) return MemoryBlock(); @@ -95,7 +95,7 @@ Memory::allocateMappedMemory(size_t NumBytes, #ifdef NEED_DEV_ZERO_FOR_MMAP static int zero_fd = open("/dev/zero", O_RDWR); if (zero_fd == -1) { - EC = error_code(errno, system_category()); + EC = std::error_code(errno, std::generic_category()); return MemoryBlock(); } fd = zero_fd; @@ -123,7 +123,7 @@ Memory::allocateMappedMemory(size_t NumBytes, if (NearBlock) //Try again without a near hint return allocateMappedMemory(NumBytes, nullptr, PFlags, EC); - EC = error_code(errno, system_category()); + EC = std::error_code(errno, std::generic_category()); return MemoryBlock(); } @@ -137,38 +137,38 @@ Memory::allocateMappedMemory(size_t NumBytes, return Result; } -error_code +std::error_code Memory::releaseMappedMemory(MemoryBlock &M) { if (M.Address == nullptr || M.Size == 0) - return error_code::success(); + return std::error_code(); if (0 != ::munmap(M.Address, M.Size)) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); M.Address = nullptr; M.Size = 0; - return error_code::success(); + return std::error_code(); } -error_code +std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { if (M.Address == nullptr || M.Size == 0) - return error_code::success(); + return std::error_code(); if (!Flags) - return error_code(EINVAL, generic_category()); + return std::error_code(EINVAL, std::generic_category()); int Protect = getPosixProtectionFlags(Flags); int Result = ::mprotect(M.Address, M.Size, Protect); if (Result != 0) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); if (Flags & MF_EXEC) Memory::InvalidateInstructionCache(M.Address, M.Size); - return error_code::success(); + return std::error_code(); } /// AllocateRWX - Allocate a slab of memory with read/write/execute diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index 519a016..623547a 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -87,7 +87,7 @@ namespace { }; } -static error_code TempDir(SmallVectorImpl<char> &result) { +static std::error_code TempDir(SmallVectorImpl<char> &result) { // FIXME: Don't use TMPDIR if program is SUID or SGID enabled. const char *dir = nullptr; (dir = std::getenv("TMPDIR")) || (dir = std::getenv("TMP")) || @@ -100,7 +100,7 @@ static error_code TempDir(SmallVectorImpl<char> &result) { result.clear(); StringRef d(dir); result.append(d.begin(), d.end()); - return error_code::success(); + return std::error_code(); } namespace llvm { @@ -225,7 +225,7 @@ UniqueID file_status::getUniqueID() const { return UniqueID(fs_st_dev, fs_st_ino); } -error_code current_path(SmallVectorImpl<char> &result) { +std::error_code current_path(SmallVectorImpl<char> &result) { result.clear(); const char *pwd = ::getenv("PWD"); @@ -235,7 +235,7 @@ error_code current_path(SmallVectorImpl<char> &result) { !llvm::sys::fs::status(".", DotStatus) && PWDStatus.getUniqueID() == DotStatus.getUniqueID()) { result.append(pwd, pwd + strlen(pwd)); - return error_code::success(); + return std::error_code(); } #ifdef MAXPATHLEN @@ -248,8 +248,8 @@ error_code current_path(SmallVectorImpl<char> &result) { while (true) { if (::getcwd(result.data(), result.capacity()) == nullptr) { // See if there was a real error. - if (errno != errc::not_enough_memory) - return error_code(errno, system_category()); + if (errno != ENOMEM) + return std::error_code(errno, std::generic_category()); // Otherwise there just wasn't enough space. result.reserve(result.capacity() * 2); } else @@ -257,22 +257,22 @@ error_code current_path(SmallVectorImpl<char> &result) { } result.set_size(strlen(result.data())); - return error_code::success(); + return std::error_code(); } -error_code create_directory(const Twine &path, bool IgnoreExisting) { +std::error_code create_directory(const Twine &path, bool IgnoreExisting) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); if (::mkdir(p.begin(), S_IRWXU | S_IRWXG) == -1) { - if (errno != errc::file_exists || !IgnoreExisting) - return error_code(errno, system_category()); + if (errno != EEXIST || !IgnoreExisting) + return std::error_code(errno, std::generic_category()); } - return error_code::success(); + return std::error_code(); } -error_code normalize_separators(SmallVectorImpl<char> &Path) { +std::error_code normalize_separators(SmallVectorImpl<char> &Path) { for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) { if (*PI == '\\') { auto PN = PI + 1; @@ -282,12 +282,12 @@ error_code normalize_separators(SmallVectorImpl<char> &Path) { *PI = '/'; } } - return error_code::success(); + return std::error_code(); } // Note that we are using symbolic link because hard links are not supported by // all filesystems (SMB doesn't). -error_code create_link(const Twine &to, const Twine &from) { +std::error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -295,20 +295,20 @@ error_code create_link(const Twine &to, const Twine &from) { StringRef t = to.toNullTerminatedStringRef(to_storage); if (::symlink(t.begin(), f.begin()) == -1) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); - return error_code::success(); + return std::error_code(); } -error_code remove(const Twine &path, bool IgnoreNonExisting) { +std::error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); struct stat buf; if (lstat(p.begin(), &buf) != 0) { - if (errno != errc::no_such_file_or_directory || !IgnoreNonExisting) - return error_code(errno, system_category()); - return error_code::success(); + if (errno != ENOENT || !IgnoreNonExisting) + return std::error_code(errno, std::generic_category()); + return std::error_code(); } // Note: this check catches strange situations. In all cases, LLVM should @@ -320,14 +320,14 @@ error_code remove(const Twine &path, bool IgnoreNonExisting) { return make_error_code(errc::operation_not_permitted); if (::remove(p.begin()) == -1) { - if (errno != errc::no_such_file_or_directory || !IgnoreNonExisting) - return error_code(errno, system_category()); + if (errno != ENOENT || !IgnoreNonExisting) + return std::error_code(errno, std::generic_category()); } - return error_code::success(); + return std::error_code(); } -error_code rename(const Twine &from, const Twine &to) { +std::error_code rename(const Twine &from, const Twine &to) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -335,33 +335,33 @@ error_code rename(const Twine &from, const Twine &to) { StringRef t = to.toNullTerminatedStringRef(to_storage); if (::rename(f.begin(), t.begin()) == -1) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); - return error_code::success(); + return std::error_code(); } -error_code resize_file(const Twine &path, uint64_t size) { +std::error_code resize_file(const Twine &path, uint64_t size) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); if (::truncate(p.begin(), size) == -1) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); - return error_code::success(); + return std::error_code(); } -error_code exists(const Twine &path, bool &result) { +std::error_code exists(const Twine &path, bool &result) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); if (::access(p.begin(), F_OK) == -1) { - if (errno != errc::no_such_file_or_directory) - return error_code(errno, system_category()); + if (errno != ENOENT) + return std::error_code(errno, std::generic_category()); result = false; } else result = true; - return error_code::success(); + return std::error_code(); } bool can_write(const Twine &Path) { @@ -390,18 +390,20 @@ bool equivalent(file_status A, file_status B) { A.fs_st_ino == B.fs_st_ino; } -error_code equivalent(const Twine &A, const Twine &B, bool &result) { +std::error_code equivalent(const Twine &A, const Twine &B, bool &result) { file_status fsA, fsB; - if (error_code ec = status(A, fsA)) return ec; - if (error_code ec = status(B, fsB)) return ec; + if (std::error_code ec = status(A, fsA)) + return ec; + if (std::error_code ec = status(B, fsB)) + return ec; result = equivalent(fsA, fsB); - return error_code::success(); + return std::error_code(); } -static error_code fillStatus(int StatRet, const struct stat &Status, +static std::error_code fillStatus(int StatRet, const struct stat &Status, file_status &Result) { if (StatRet != 0) { - error_code ec(errno, system_category()); + std::error_code ec(errno, std::generic_category()); if (ec == errc::no_such_file_or_directory) Result = file_status(file_type::file_not_found); else @@ -429,10 +431,10 @@ static error_code fillStatus(int StatRet, const struct stat &Status, file_status(Type, Perms, Status.st_dev, Status.st_ino, Status.st_mtime, Status.st_uid, Status.st_gid, Status.st_size); - return error_code::success(); + return std::error_code(); } -error_code status(const Twine &Path, file_status &Result) { +std::error_code status(const Twine &Path, file_status &Result) { SmallString<128> PathStorage; StringRef P = Path.toNullTerminatedStringRef(PathStorage); @@ -441,36 +443,36 @@ error_code status(const Twine &Path, file_status &Result) { return fillStatus(StatRet, Status, Result); } -error_code status(int FD, file_status &Result) { +std::error_code status(int FD, file_status &Result) { struct stat Status; int StatRet = ::fstat(FD, &Status); return fillStatus(StatRet, Status, Result); } -error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { +std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { #if defined(HAVE_FUTIMENS) timespec Times[2]; Times[0].tv_sec = Time.toEpochTime(); Times[0].tv_nsec = 0; Times[1] = Times[0]; if (::futimens(FD, Times)) - return error_code(errno, system_category()); - return error_code::success(); + return std::error_code(errno, std::generic_category()); + return std::error_code(); #elif defined(HAVE_FUTIMES) timeval Times[2]; Times[0].tv_sec = Time.toEpochTime(); Times[0].tv_usec = 0; Times[1] = Times[0]; if (::futimes(FD, Times)) - return error_code(errno, system_category()); - return error_code::success(); + return std::error_code(errno, std::generic_category()); + return std::error_code(); #else #warning Missing futimes() and futimens() - return make_error_code(errc::not_supported); + return make_error_code(errc::function_not_supported); #endif } -error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { +std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { AutoFD ScopedFD(FD); if (!CloseFD) ScopedFD.take(); @@ -478,7 +480,7 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { // Figure out how large the file is. struct stat FileInfo; if (fstat(FD, &FileInfo) == -1) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); uint64_t FileSize = FileInfo.st_size; if (Size == 0) @@ -486,7 +488,7 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { else if (FileSize < Size) { // We need to grow the file. if (ftruncate(FD, Size) == -1) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); } int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE; @@ -496,15 +498,15 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { #endif Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset); if (Mapping == MAP_FAILED) - return error_code(errno, system_category()); - return error_code::success(); + return std::error_code(errno, std::generic_category()); + return std::error_code(); } mapped_file_region::mapped_file_region(const Twine &path, mapmode mode, uint64_t length, uint64_t offset, - error_code &ec) + std::error_code &ec) : Mode(mode) , Size(length) , Mapping() { @@ -519,7 +521,7 @@ mapped_file_region::mapped_file_region(const Twine &path, int oflags = (mode == readonly) ? O_RDONLY : O_RDWR; int ofd = ::open(name.begin(), oflags); if (ofd == -1) { - ec = error_code(errno, system_category()); + ec = std::error_code(errno, std::generic_category()); return; } @@ -533,7 +535,7 @@ mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length, uint64_t offset, - error_code &ec) + std::error_code &ec) : Mode(mode) , Size(length) , Mapping() { @@ -583,12 +585,12 @@ int mapped_file_region::alignment() { return process::get_self()->page_size(); } -error_code detail::directory_iterator_construct(detail::DirIterState &it, +std::error_code detail::directory_iterator_construct(detail::DirIterState &it, StringRef path){ SmallString<128> path_null(path); DIR *directory = ::opendir(path_null.c_str()); if (!directory) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); it.IterationHandle = reinterpret_cast<intptr_t>(directory); // Add something for replace_filename to replace. @@ -597,19 +599,19 @@ error_code detail::directory_iterator_construct(detail::DirIterState &it, return directory_iterator_increment(it); } -error_code detail::directory_iterator_destruct(detail::DirIterState &it) { +std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { if (it.IterationHandle) ::closedir(reinterpret_cast<DIR *>(it.IterationHandle)); it.IterationHandle = 0; it.CurrentEntry = directory_entry(); - return error_code::success(); + return std::error_code(); } -error_code detail::directory_iterator_increment(detail::DirIterState &it) { +std::error_code detail::directory_iterator_increment(detail::DirIterState &it) { errno = 0; dirent *cur_dir = ::readdir(reinterpret_cast<DIR *>(it.IterationHandle)); if (cur_dir == nullptr && errno != 0) { - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); } else if (cur_dir != nullptr) { StringRef name(cur_dir->d_name, NAMLEN(cur_dir)); if ((name.size() == 1 && name[0] == '.') || @@ -619,80 +621,20 @@ error_code detail::directory_iterator_increment(detail::DirIterState &it) { } else return directory_iterator_destruct(it); - return error_code::success(); -} - -error_code get_magic(const Twine &path, uint32_t len, - SmallVectorImpl<char> &result) { - SmallString<128> PathStorage; - StringRef Path = path.toNullTerminatedStringRef(PathStorage); - result.set_size(0); - - // Open path. - std::FILE *file = std::fopen(Path.data(), "rb"); - if (!file) - return error_code(errno, system_category()); - - // Reserve storage. - result.reserve(len); - - // Read magic! - size_t size = std::fread(result.data(), 1, len, file); - if (std::ferror(file) != 0) { - std::fclose(file); - return error_code(errno, system_category()); - } else if (size != len) { - if (std::feof(file) != 0) { - std::fclose(file); - result.set_size(size); - return make_error_code(errc::value_too_large); - } - } - std::fclose(file); - result.set_size(size); - return error_code::success(); -} - -error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, - bool map_writable, void *&result) { - SmallString<128> path_storage; - StringRef name = path.toNullTerminatedStringRef(path_storage); - int oflags = map_writable ? O_RDWR : O_RDONLY; - int ofd = ::open(name.begin(), oflags); - if ( ofd == -1 ) - return error_code(errno, system_category()); - AutoFD fd(ofd); - int flags = map_writable ? MAP_SHARED : MAP_PRIVATE; - int prot = map_writable ? (PROT_READ|PROT_WRITE) : PROT_READ; -#ifdef MAP_FILE - flags |= MAP_FILE; -#endif - result = ::mmap(nullptr, size, prot, flags, fd, file_offset); - if (result == MAP_FAILED) { - return error_code(errno, system_category()); - } - - return error_code::success(); -} - -error_code unmap_file_pages(void *base, size_t size) { - if ( ::munmap(base, size) == -1 ) - return error_code(errno, system_category()); - - return error_code::success(); + return std::error_code(); } -error_code openFileForRead(const Twine &Name, int &ResultFD) { +std::error_code openFileForRead(const Twine &Name, int &ResultFD) { SmallString<128> Storage; StringRef P = Name.toNullTerminatedStringRef(Storage); while ((ResultFD = open(P.begin(), O_RDONLY)) < 0) { if (errno != EINTR) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); } - return error_code::success(); + return std::error_code(); } -error_code openFileForWrite(const Twine &Name, int &ResultFD, +std::error_code openFileForWrite(const Twine &Name, int &ResultFD, sys::fs::OpenFlags Flags, unsigned Mode) { // Verify that we don't have both "append" and "excl". assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) && @@ -717,9 +659,9 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, StringRef P = Name.toNullTerminatedStringRef(Storage); while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) { if (errno != EINTR) - return error_code(errno, system_category()); + return std::error_code(errno, std::generic_category()); } - return error_code::success(); + return std::error_code(); } } // end namespace fs diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc index 8faa638..d2c5dbc 100644 --- a/lib/Support/Unix/Process.inc +++ b/lib/Support/Unix/Process.inc @@ -47,7 +47,6 @@ using namespace llvm; using namespace sys; - process::id_type self_process::get_id() { return getpid(); } @@ -190,12 +189,13 @@ Optional<std::string> Process::GetEnv(StringRef Name) { return std::string(Val); } -error_code Process::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut, - ArrayRef<const char *> ArgsIn, - SpecificBumpPtrAllocator<char> &) { +std::error_code +Process::GetArgumentVector(SmallVectorImpl<const char *> &ArgsOut, + ArrayRef<const char *> ArgsIn, + SpecificBumpPtrAllocator<char> &) { ArgsOut.append(ArgsIn.begin(), ArgsIn.end()); - return error_code::success(); + return std::error_code(); } bool Process::StandardInIsUserInput() { diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 1225a9c..06a33cd 100644 --- a/lib/Support/Unix/Program.inc +++ b/lib/Support/Unix/Program.inc @@ -48,6 +48,7 @@ #endif namespace llvm { + using namespace sys; ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {} @@ -349,7 +350,11 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, // Parent process: Wait for the child process to terminate. int status; ProcessInfo WaitResult; - WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions); + + do { + WaitResult.Pid = waitpid(ChildPid, &status, WaitPidOptions); + } while (WaitUntilTerminates && WaitResult.Pid == -1 && errno == EINTR); + if (WaitResult.Pid != PI.Pid) { if (WaitResult.Pid == 0) { // Non-blocking wait. @@ -425,14 +430,14 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, return WaitResult; } -error_code sys::ChangeStdinToBinary(){ + std::error_code sys::ChangeStdinToBinary(){ // Do nothing, as Unix doesn't differentiate between text and binary. - return make_error_code(errc::success); + return std::error_code(); } -error_code sys::ChangeStdoutToBinary(){ + std::error_code sys::ChangeStdoutToBinary(){ // Do nothing, as Unix doesn't differentiate between text and binary. - return make_error_code(errc::success); + return std::error_code(); } bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) { diff --git a/lib/Support/Unix/system_error.inc b/lib/Support/Unix/system_error.inc deleted file mode 100644 index 681e919..0000000 --- a/lib/Support/Unix/system_error.inc +++ /dev/null @@ -1,34 +0,0 @@ -//===- llvm/Support/Unix/system_error.inc - Unix error_code ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Unix specific implementation of the error_code -// and error_condition classes. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic UNIX code that -//=== is guaranteed to work on *all* UNIX variants. -//===----------------------------------------------------------------------===// - -using namespace llvm; - -std::string -_system_error_category::message(int ev) const { - return _do_message::message(ev); -} - -error_condition -_system_error_category::default_error_condition(int ev) const { -#ifdef ELAST - if (ev > ELAST) - return error_condition(ev, system_category()); -#endif // ELAST - return error_condition(ev, generic_category()); -} diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index 5d0278f..5ed0b70 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -85,7 +85,7 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, } SmallVector<wchar_t, MAX_PATH> filenameUnicode; - if (error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) { + if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) { SetLastError(ec.value()); MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16: "); return DynamicLibrary(); diff --git a/lib/Support/Windows/Memory.inc b/lib/Support/Windows/Memory.inc index ebe7878..ae8371a 100644 --- a/lib/Support/Windows/Memory.inc +++ b/lib/Support/Windows/Memory.inc @@ -15,6 +15,7 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Process.h" +#include "llvm/Support/WindowsError.h" // The Windows.h header must be the last one included. #include "WindowsSupport.h" @@ -69,8 +70,8 @@ namespace sys { MemoryBlock Memory::allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, - error_code &EC) { - EC = error_code::success(); + std::error_code &EC) { + EC = std::error_code(); if (NumBytes == 0) return MemoryBlock(); @@ -99,7 +100,7 @@ MemoryBlock Memory::allocateMappedMemory(size_t NumBytes, // Try again without the NearBlock hint return allocateMappedMemory(NumBytes, NULL, Flags, EC); } - EC = error_code(::GetLastError(), system_category()); + EC = mapWindowsError(::GetLastError()); return MemoryBlock(); } @@ -113,34 +114,34 @@ MemoryBlock Memory::allocateMappedMemory(size_t NumBytes, return Result; } -error_code Memory::releaseMappedMemory(MemoryBlock &M) { + std::error_code Memory::releaseMappedMemory(MemoryBlock &M) { if (M.Address == 0 || M.Size == 0) - return error_code::success(); + return std::error_code(); if (!VirtualFree(M.Address, 0, MEM_RELEASE)) - return error_code(::GetLastError(), system_category()); + return mapWindowsError(::GetLastError()); M.Address = 0; M.Size = 0; - return error_code::success(); + return std::error_code(); } -error_code Memory::protectMappedMemory(const MemoryBlock &M, + std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { if (M.Address == 0 || M.Size == 0) - return error_code::success(); + return std::error_code(); DWORD Protect = getWindowsProtectionFlags(Flags); DWORD OldFlags; if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags)) - return error_code(::GetLastError(), system_category()); + return mapWindowsError(::GetLastError()); if (Flags & MF_EXEC) Memory::InvalidateInstructionCache(M.Address, M.Size); - return error_code::success(); + return std::error_code(); } /// InvalidateInstructionCache - Before the JIT can run a block of code @@ -156,18 +157,18 @@ MemoryBlock Memory::AllocateRWX(size_t NumBytes, const MemoryBlock *NearBlock, std::string *ErrMsg) { MemoryBlock MB; - error_code EC; + std::error_code EC; MB = allocateMappedMemory(NumBytes, NearBlock, MF_READ|MF_WRITE|MF_EXEC, EC); - if (EC != error_code::success() && ErrMsg) { + if (EC != std::error_code() && ErrMsg) { MakeErrMsg(ErrMsg, EC.message()); } return MB; } bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - error_code EC = releaseMappedMemory(M); - if (EC == error_code::success()) + std::error_code EC = releaseMappedMemory(M); + if (EC == std::error_code()) return false; MakeErrMsg(ErrMsg, EC.message()); return true; diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index e59888e..7a1bc04 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/WindowsError.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> @@ -44,7 +45,11 @@ using namespace llvm; using llvm::sys::windows::UTF8ToUTF16; using llvm::sys::windows::UTF16ToUTF8; -static error_code TempDir(SmallVectorImpl<char> &Result) { +static std::error_code windows_error(DWORD E) { + return mapWindowsError(E); +} + +static std::error_code TempDir(SmallVectorImpl<char> &Result) { SmallVector<wchar_t, 64> Res; retry_temp_dir: DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin()); @@ -119,7 +124,7 @@ TimeValue file_status::getLastModificationTime() const { return Ret; } -error_code current_path(SmallVectorImpl<char> &result) { +std::error_code current_path(SmallVectorImpl<char> &result) { SmallVector<wchar_t, MAX_PATH> cur_path; DWORD len = MAX_PATH; @@ -141,30 +146,30 @@ error_code current_path(SmallVectorImpl<char> &result) { return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result); } -error_code create_directory(const Twine &path, bool IgnoreExisting) { +std::error_code create_directory(const Twine &path, bool IgnoreExisting) { SmallString<128> path_storage; SmallVector<wchar_t, 128> path_utf16; - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), - path_utf16)) + if (std::error_code ec = + UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)) return ec; if (!::CreateDirectoryW(path_utf16.begin(), NULL)) { - error_code ec = windows_error(::GetLastError()); - if (ec != windows_error::already_exists || !IgnoreExisting) - return ec; + DWORD LastError = ::GetLastError(); + if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting) + return windows_error(LastError); } - return error_code::success(); + return std::error_code(); } -error_code normalize_separators(SmallVectorImpl<char> &Path) { +std::error_code normalize_separators(SmallVectorImpl<char> &Path) { (void) Path; - return error_code::success(); + return std::error_code(); } // We can't use symbolic links for windows. -error_code create_link(const Twine &to, const Twine &from) { +std::error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -174,47 +179,49 @@ error_code create_link(const Twine &to, const Twine &from) { // Convert to utf-16. SmallVector<wchar_t, 128> wide_from; SmallVector<wchar_t, 128> wide_to; - if (error_code ec = UTF8ToUTF16(f, wide_from)) return ec; - if (error_code ec = UTF8ToUTF16(t, wide_to)) return ec; + if (std::error_code ec = UTF8ToUTF16(f, wide_from)) + return ec; + if (std::error_code ec = UTF8ToUTF16(t, wide_to)) + return ec; if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL)) return windows_error(::GetLastError()); - return error_code::success(); + return std::error_code(); } -error_code remove(const Twine &path, bool IgnoreNonExisting) { +std::error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallString<128> path_storage; SmallVector<wchar_t, 128> path_utf16; file_status ST; - if (error_code EC = status(path, ST)) { + if (std::error_code EC = status(path, ST)) { if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) return EC; - return error_code::success(); + return std::error_code(); } - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), - path_utf16)) + if (std::error_code ec = + UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)) return ec; if (ST.type() == file_type::directory_file) { if (!::RemoveDirectoryW(c_str(path_utf16))) { - error_code EC = windows_error(::GetLastError()); + std::error_code EC = windows_error(::GetLastError()); if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) return EC; } - return error_code::success(); + return std::error_code(); } if (!::DeleteFileW(c_str(path_utf16))) { - error_code EC = windows_error(::GetLastError()); + std::error_code EC = windows_error(::GetLastError()); if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) return EC; } - return error_code::success(); + return std::error_code(); } -error_code rename(const Twine &from, const Twine &to) { +std::error_code rename(const Twine &from, const Twine &to) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -224,16 +231,18 @@ error_code rename(const Twine &from, const Twine &to) { // Convert to utf-16. SmallVector<wchar_t, 128> wide_from; SmallVector<wchar_t, 128> wide_to; - if (error_code ec = UTF8ToUTF16(f, wide_from)) return ec; - if (error_code ec = UTF8ToUTF16(t, wide_to)) return ec; + if (std::error_code ec = UTF8ToUTF16(f, wide_from)) + return ec; + if (std::error_code ec = UTF8ToUTF16(t, wide_to)) + return ec; - error_code ec = error_code::success(); + std::error_code ec = std::error_code(); for (int i = 0; i < 2000; i++) { if (::MoveFileExW(wide_from.begin(), wide_to.begin(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) - return error_code::success(); - ec = windows_error(::GetLastError()); - if (ec != windows_error::access_denied) + return std::error_code(); + DWORD LastError = ::GetLastError(); + if (LastError != ERROR_ACCESS_DENIED) break; // Retry MoveFile() at ACCESS_DENIED. // System scanners (eg. indexer) might open the source file when @@ -244,46 +253,46 @@ error_code rename(const Twine &from, const Twine &to) { return ec; } -error_code resize_file(const Twine &path, uint64_t size) { +std::error_code resize_file(const Twine &path, uint64_t size) { SmallString<128> path_storage; SmallVector<wchar_t, 128> path_utf16; - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), - path_utf16)) + if (std::error_code ec = + UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)) return ec; int fd = ::_wopen(path_utf16.begin(), O_BINARY | _O_RDWR, S_IWRITE); if (fd == -1) - return error_code(errno, generic_category()); + return std::error_code(errno, std::generic_category()); #ifdef HAVE__CHSIZE_S errno_t error = ::_chsize_s(fd, size); #else errno_t error = ::_chsize(fd, size); #endif ::close(fd); - return error_code(error, generic_category()); + return std::error_code(error, std::generic_category()); } -error_code exists(const Twine &path, bool &result) { +std::error_code exists(const Twine &path, bool &result) { SmallString<128> path_storage; SmallVector<wchar_t, 128> path_utf16; - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), - path_utf16)) + if (std::error_code ec = + UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)) return ec; DWORD attributes = ::GetFileAttributesW(path_utf16.begin()); if (attributes == INVALID_FILE_ATTRIBUTES) { // See if the file didn't actually exist. - error_code ec = make_error_code(windows_error(::GetLastError())); - if (ec != windows_error::file_not_found && - ec != windows_error::path_not_found) - return ec; + DWORD LastError = ::GetLastError(); + if (LastError != ERROR_FILE_NOT_FOUND && + LastError != ERROR_PATH_NOT_FOUND) + return windows_error(LastError); result = false; } else result = true; - return error_code::success(); + return std::error_code(); } bool can_write(const Twine &Path) { @@ -320,12 +329,14 @@ bool equivalent(file_status A, file_status B) { A.VolumeSerialNumber == B.VolumeSerialNumber; } -error_code equivalent(const Twine &A, const Twine &B, bool &result) { +std::error_code equivalent(const Twine &A, const Twine &B, bool &result) { file_status fsA, fsB; - if (error_code ec = status(A, fsA)) return ec; - if (error_code ec = status(B, fsB)) return ec; + if (std::error_code ec = status(A, fsA)) + return ec; + if (std::error_code ec = status(B, fsB)) + return ec; result = equivalent(fsA, fsB); - return error_code::success(); + return std::error_code(); } static bool isReservedName(StringRef path) { @@ -351,7 +362,7 @@ static bool isReservedName(StringRef path) { return false; } -static error_code getStatus(HANDLE FileHandle, file_status &Result) { +static std::error_code getStatus(HANDLE FileHandle, file_status &Result) { if (FileHandle == INVALID_HANDLE_VALUE) goto handle_status_error; @@ -363,16 +374,16 @@ static error_code getStatus(HANDLE FileHandle, file_status &Result) { if (Err != NO_ERROR) return windows_error(Err); Result = file_status(file_type::type_unknown); - return error_code::success(); + return std::error_code(); } case FILE_TYPE_DISK: break; case FILE_TYPE_CHAR: Result = file_status(file_type::character_file); - return error_code::success(); + return std::error_code(); case FILE_TYPE_PIPE: Result = file_status(file_type::fifo_file); - return error_code::success(); + return std::error_code(); } BY_HANDLE_FILE_INFORMATION Info; @@ -388,32 +399,32 @@ static error_code getStatus(HANDLE FileHandle, file_status &Result) { Info.ftLastWriteTime.dwLowDateTime, Info.dwVolumeSerialNumber, Info.nFileSizeHigh, Info.nFileSizeLow, Info.nFileIndexHigh, Info.nFileIndexLow); - return error_code::success(); + return std::error_code(); } handle_status_error: - error_code EC = windows_error(::GetLastError()); - if (EC == windows_error::file_not_found || - EC == windows_error::path_not_found) + DWORD LastError = ::GetLastError(); + if (LastError == ERROR_FILE_NOT_FOUND || + LastError == ERROR_PATH_NOT_FOUND) Result = file_status(file_type::file_not_found); - else if (EC == windows_error::sharing_violation) + else if (LastError == ERROR_SHARING_VIOLATION) Result = file_status(file_type::type_unknown); else Result = file_status(file_type::status_error); - return EC; + return windows_error(LastError); } -error_code status(const Twine &path, file_status &result) { +std::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); if (isReservedName(path8)) { result = file_status(file_type::character_file); - return error_code::success(); + return std::error_code(); } - if (error_code ec = UTF8ToUTF16(path8, path_utf16)) + if (std::error_code ec = UTF8ToUTF16(path8, path_utf16)) return ec; DWORD attr = ::GetFileAttributesW(path_utf16.begin()); @@ -444,12 +455,12 @@ error_code status(const Twine &path, file_status &result) { return getStatus(h, result); } -error_code status(int FD, file_status &Result) { +std::error_code status(int FD, file_status &Result) { HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); return getStatus(FileHandle, Result); } -error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { +std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { ULARGE_INTEGER UI; UI.QuadPart = Time.toWin32Time(); FILETIME FT; @@ -458,52 +469,10 @@ error_code setLastModificationAndAccessTime(int FD, TimeValue Time) { HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD)); if (!SetFileTime(FileHandle, NULL, &FT, &FT)) return windows_error(::GetLastError()); - return error_code::success(); -} - -error_code get_magic(const Twine &path, uint32_t len, - SmallVectorImpl<char> &result) { - SmallString<128> path_storage; - SmallVector<wchar_t, 128> path_utf16; - result.set_size(0); - - // Convert path to UTF-16. - if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage), - path_utf16)) - return ec; - - // Open file. - HANDLE file = ::CreateFileW(c_str(path_utf16), - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_READONLY, - NULL); - if (file == INVALID_HANDLE_VALUE) - return windows_error(::GetLastError()); - - // Allocate buffer. - result.reserve(len); - - // Get magic! - DWORD bytes_read = 0; - BOOL read_success = ::ReadFile(file, result.data(), len, &bytes_read, NULL); - error_code ec = windows_error(::GetLastError()); - ::CloseHandle(file); - if (!read_success || (bytes_read != len)) { - // Set result size to the number of bytes read if it's valid. - if (bytes_read <= len) - result.set_size(bytes_read); - // ERROR_HANDLE_EOF is mapped to errc::value_too_large. - return ec; - } - - result.set_size(len); - return error_code::success(); + return std::error_code(); } -error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { +std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { FileDescriptor = FD; // Make sure that the requested size fits within SIZE_T. if (Size > std::numeric_limits<SIZE_T>::max()) { @@ -528,7 +497,7 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { (Offset + Size) & 0xffffffff, 0); if (FileMappingHandle == NULL) { - error_code ec = windows_error(GetLastError()); + std::error_code ec = windows_error(GetLastError()); if (FileDescriptor) { if (CloseFD) _close(FileDescriptor); @@ -549,7 +518,7 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { Offset & 0xffffffff, Size); if (Mapping == NULL) { - error_code ec = windows_error(GetLastError()); + std::error_code ec = windows_error(GetLastError()); ::CloseHandle(FileMappingHandle); if (FileDescriptor) { if (CloseFD) @@ -563,7 +532,7 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { MEMORY_BASIC_INFORMATION mbi; SIZE_T Result = VirtualQuery(Mapping, &mbi, sizeof(mbi)); if (Result == 0) { - error_code ec = windows_error(GetLastError()); + std::error_code ec = windows_error(GetLastError()); ::UnmapViewOfFile(Mapping); ::CloseHandle(FileMappingHandle); if (FileDescriptor) { @@ -584,14 +553,14 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { _close(FileDescriptor); // Also closes FileHandle. } else ::CloseHandle(FileHandle); - return error_code::success(); + return std::error_code(); } mapped_file_region::mapped_file_region(const Twine &path, mapmode mode, uint64_t length, uint64_t offset, - error_code &ec) + std::error_code &ec) : Mode(mode) , Size(length) , Mapping() @@ -636,7 +605,7 @@ mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length, uint64_t offset, - error_code &ec) + std::error_code &ec) : Mode(mode) , Size(length) , Mapping() @@ -704,12 +673,11 @@ int mapped_file_region::alignment() { return SysInfo.dwAllocationGranularity; } -error_code detail::directory_iterator_construct(detail::DirIterState &it, +std::error_code detail::directory_iterator_construct(detail::DirIterState &it, StringRef path){ SmallVector<wchar_t, 128> path_utf16; - if (error_code ec = UTF8ToUTF16(path, - path_utf16)) + if (std::error_code ec = UTF8ToUTF16(path, path_utf16)) return ec; // Convert path to the format that Windows is happy with. @@ -733,19 +701,19 @@ error_code detail::directory_iterator_construct(detail::DirIterState &it, (FilenameLen == 2 && FirstFind.cFileName[0] == L'.' && FirstFind.cFileName[1] == L'.')) if (!::FindNextFileW(FindHandle, &FirstFind)) { - error_code ec = windows_error(::GetLastError()); + DWORD LastError = ::GetLastError(); // Check for end. - if (ec == windows_error::no_more_files) + if (LastError == ERROR_NO_MORE_FILES) return detail::directory_iterator_destruct(it); - return ec; + return windows_error(LastError); } else FilenameLen = ::wcslen(FirstFind.cFileName); // Construct the current directory entry. SmallString<128> directory_entry_name_utf8; - if (error_code ec = UTF16ToUTF8(FirstFind.cFileName, - ::wcslen(FirstFind.cFileName), - directory_entry_name_utf8)) + if (std::error_code ec = + UTF16ToUTF8(FirstFind.cFileName, ::wcslen(FirstFind.cFileName), + directory_entry_name_utf8)) return ec; it.IterationHandle = intptr_t(FindHandle.take()); @@ -753,26 +721,26 @@ error_code detail::directory_iterator_construct(detail::DirIterState &it, path::append(directory_entry_path, directory_entry_name_utf8.str()); it.CurrentEntry = directory_entry(directory_entry_path.str()); - return error_code::success(); + return std::error_code(); } -error_code detail::directory_iterator_destruct(detail::DirIterState &it) { +std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { if (it.IterationHandle != 0) // Closes the handle if it's valid. ScopedFindHandle close(HANDLE(it.IterationHandle)); it.IterationHandle = 0; it.CurrentEntry = directory_entry(); - return error_code::success(); + return std::error_code(); } -error_code detail::directory_iterator_increment(detail::DirIterState &it) { +std::error_code detail::directory_iterator_increment(detail::DirIterState &it) { WIN32_FIND_DATAW FindData; if (!::FindNextFileW(HANDLE(it.IterationHandle), &FindData)) { - error_code ec = windows_error(::GetLastError()); + DWORD LastError = ::GetLastError(); // Check for end. - if (ec == windows_error::no_more_files) + if (LastError == ERROR_NO_MORE_FILES) return detail::directory_iterator_destruct(it); - return ec; + return windows_error(LastError); } size_t FilenameLen = ::wcslen(FindData.cFileName); @@ -782,60 +750,50 @@ error_code detail::directory_iterator_increment(detail::DirIterState &it) { return directory_iterator_increment(it); SmallString<128> directory_entry_path_utf8; - if (error_code ec = UTF16ToUTF8(FindData.cFileName, - ::wcslen(FindData.cFileName), - directory_entry_path_utf8)) + if (std::error_code ec = + UTF16ToUTF8(FindData.cFileName, ::wcslen(FindData.cFileName), + directory_entry_path_utf8)) return ec; it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8)); - return error_code::success(); + return std::error_code(); } -error_code map_file_pages(const Twine &path, off_t file_offset, size_t size, - bool map_writable, void *&result) { - assert(0 && "NOT IMPLEMENTED"); - return windows_error::invalid_function; -} - -error_code unmap_file_pages(void *base, size_t size) { - assert(0 && "NOT IMPLEMENTED"); - return windows_error::invalid_function; -} - -error_code openFileForRead(const Twine &Name, int &ResultFD) { +std::error_code openFileForRead(const Twine &Name, int &ResultFD) { SmallString<128> PathStorage; SmallVector<wchar_t, 128> PathUTF16; - if (error_code EC = UTF8ToUTF16(Name.toStringRef(PathStorage), - PathUTF16)) + if (std::error_code EC = + UTF8ToUTF16(Name.toStringRef(PathStorage), PathUTF16)) return EC; HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (H == INVALID_HANDLE_VALUE) { - error_code EC = windows_error(::GetLastError()); + DWORD LastError = ::GetLastError(); + std::error_code EC = windows_error(LastError); // Provide a better error message when trying to open directories. // This only runs if we failed to open the file, so there is probably // no performances issues. - if (EC != windows_error::access_denied) + if (LastError != ERROR_ACCESS_DENIED) return EC; if (is_directory(Name)) - return error_code(errc::is_a_directory, posix_category()); + return make_error_code(errc::is_a_directory); return EC; } int FD = ::_open_osfhandle(intptr_t(H), 0); if (FD == -1) { ::CloseHandle(H); - return windows_error::invalid_handle; + return windows_error(ERROR_INVALID_HANDLE); } ResultFD = FD; - return error_code::success(); + return std::error_code(); } -error_code openFileForWrite(const Twine &Name, int &ResultFD, +std::error_code openFileForWrite(const Twine &Name, int &ResultFD, sys::fs::OpenFlags Flags, unsigned Mode) { // Verify that we don't have both "append" and "excl". assert((!(Flags & sys::fs::F_Excl) || !(Flags & sys::fs::F_Append)) && @@ -844,8 +802,8 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, SmallString<128> PathStorage; SmallVector<wchar_t, 128> PathUTF16; - if (error_code EC = UTF8ToUTF16(Name.toStringRef(PathStorage), - PathUTF16)) + if (std::error_code EC = + UTF8ToUTF16(Name.toStringRef(PathStorage), PathUTF16)) return EC; DWORD CreationDisposition; @@ -865,14 +823,15 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); if (H == INVALID_HANDLE_VALUE) { - error_code EC = windows_error(::GetLastError()); + DWORD LastError = ::GetLastError(); + std::error_code EC = windows_error(LastError); // Provide a better error message when trying to open directories. // This only runs if we failed to open the file, so there is probably // no performances issues. - if (EC != windows_error::access_denied) + if (LastError != ERROR_ACCESS_DENIED) return EC; if (is_directory(Name)) - return error_code(errc::is_a_directory, posix_category()); + return make_error_code(errc::is_a_directory); return EC; } @@ -886,11 +845,11 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, int FD = ::_open_osfhandle(intptr_t(H), OpenFlags); if (FD == -1) { ::CloseHandle(H); - return windows_error::invalid_handle; + return windows_error(ERROR_INVALID_HANDLE); } ResultFD = FD; - return error_code::success(); + return std::error_code(); } } // end namespace fs @@ -911,14 +870,14 @@ bool home_directory(SmallVectorImpl<char> &result) { } // end namespace path namespace windows { -llvm::error_code UTF8ToUTF16(llvm::StringRef utf8, - llvm::SmallVectorImpl<wchar_t> &utf16) { +std::error_code UTF8ToUTF16(llvm::StringRef utf8, + llvm::SmallVectorImpl<wchar_t> &utf16) { if (!utf8.empty()) { int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(), utf8.size(), utf16.begin(), 0); if (len == 0) - return llvm::windows_error(::GetLastError()); + return windows_error(::GetLastError()); utf16.reserve(len + 1); utf16.set_size(len); @@ -927,25 +886,25 @@ llvm::error_code UTF8ToUTF16(llvm::StringRef utf8, utf8.size(), utf16.begin(), utf16.size()); if (len == 0) - return llvm::windows_error(::GetLastError()); + return windows_error(::GetLastError()); } // Make utf16 null terminated. utf16.push_back(0); utf16.pop_back(); - return llvm::error_code::success(); + return std::error_code(); } -llvm::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, - llvm::SmallVectorImpl<char> &utf8) { +std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, + llvm::SmallVectorImpl<char> &utf8) { if (utf16_len) { // Get length. int len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.begin(), 0, NULL, NULL); if (len == 0) - return llvm::windows_error(::GetLastError()); + return windows_error(::GetLastError()); utf8.reserve(len); utf8.set_size(len); @@ -955,14 +914,14 @@ llvm::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, utf8.size(), NULL, NULL); if (len == 0) - return llvm::windows_error(::GetLastError()); + return windows_error(::GetLastError()); } // Make utf8 null terminated. utf8.push_back(0); utf8.pop_back(); - return llvm::error_code::success(); + return std::error_code(); } } // end namespace windows } // end namespace sys diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc index c3df801..81aee0e 100644 --- a/lib/Support/Windows/Process.inc +++ b/lib/Support/Windows/Process.inc @@ -12,6 +12,8 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/WindowsError.h" #include <malloc.h> // The Windows.h header must be after LLVM and standard headers. @@ -47,7 +49,6 @@ using namespace llvm; using namespace sys; - process::id_type self_process::get_id() { return GetCurrentProcessId(); } @@ -178,12 +179,16 @@ Optional<std::string> Process::GetEnv(StringRef Name) { return std::string(Res.data()); } -error_code +static std::error_code windows_error(DWORD E) { + return mapWindowsError(E); +} + +std::error_code Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, ArrayRef<const char *>, SpecificBumpPtrAllocator<char> &ArgAllocator) { int NewArgCount; - error_code ec; + std::error_code ec; wchar_t **UnicodeCommandLine = CommandLineToArgvW(GetCommandLineW(), &NewArgCount); @@ -208,7 +213,7 @@ Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, if (ec) return ec; - return error_code::success(); + return std::error_code(); } bool Process::StandardInIsUserInput() { @@ -363,12 +368,12 @@ unsigned Process::GetRandomNumber() { HCRYPTPROV HCPC; if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - assert(false && "Could not acquire a cryptographic context"); + report_fatal_error("Could not acquire a cryptographic context"); ScopedCryptContext CryptoProvider(HCPC); unsigned Ret; if (!::CryptGenRandom(CryptoProvider, sizeof(Ret), reinterpret_cast<BYTE *>(&Ret))) - assert(false && "Could not generate a random number"); + report_fatal_error("Could not generate a random number"); return Ret; } diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index 5827c10..b2f71ae 100644 --- a/lib/Support/Windows/Program.inc +++ b/lib/Support/Windows/Program.inc @@ -226,7 +226,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, // an environment block by concatenating them. for (unsigned i = 0; envp[i]; ++i) { SmallVector<wchar_t, MAX_PATH> EnvString; - if (error_code ec = windows::UTF8ToUTF16(envp[i], EnvString)) { + if (std::error_code ec = windows::UTF8ToUTF16(envp[i], EnvString)) { SetLastError(ec.value()); MakeErrMsg(ErrMsg, "Unable to convert environment variable to UTF-16"); return false; @@ -290,7 +290,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, fflush(stderr); SmallVector<wchar_t, MAX_PATH> ProgramUtf16; - if (error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) { + if (std::error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) { SetLastError(ec.value()); MakeErrMsg(ErrMsg, std::string("Unable to convert application name to UTF-16")); @@ -298,7 +298,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, } SmallVector<wchar_t, MAX_PATH> CommandUtf16; - if (error_code ec = windows::UTF8ToUTF16(command.get(), CommandUtf16)) { + if (std::error_code ec = windows::UTF8ToUTF16(command.get(), CommandUtf16)) { SetLastError(ec.value()); MakeErrMsg(ErrMsg, std::string("Unable to convert command-line to UTF-16")); @@ -422,18 +422,18 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, return WaitResult; } -error_code sys::ChangeStdinToBinary(){ + std::error_code sys::ChangeStdinToBinary(){ int result = _setmode( _fileno(stdin), _O_BINARY ); if (result == -1) - return error_code(errno, generic_category()); - return make_error_code(errc::success); + return std::error_code(errno, std::generic_category()); + return std::error_code(); } -error_code sys::ChangeStdoutToBinary(){ + std::error_code sys::ChangeStdoutToBinary(){ int result = _setmode( _fileno(stdout), _O_BINARY ); if (result == -1) - return error_code(errno, generic_category()); - return make_error_code(errc::success); + return std::error_code(errno, std::generic_category()); + return std::error_code(); } bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) { diff --git a/lib/Support/Windows/WindowsSupport.h b/lib/Support/Windows/WindowsSupport.h index 6bef444..f68835b 100644 --- a/lib/Support/Windows/WindowsSupport.h +++ b/lib/Support/Windows/WindowsSupport.h @@ -32,7 +32,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" // Get build system configuration settings #include "llvm/Support/Compiler.h" -#include "llvm/Support/system_error.h" +#include <system_error> #include <windows.h> #include <wincrypt.h> #include <cassert> @@ -163,10 +163,9 @@ c_str(SmallVectorImpl<T> &str) { namespace sys { namespace windows { -error_code UTF8ToUTF16(StringRef utf8, - SmallVectorImpl<wchar_t> &utf16); -error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, - SmallVectorImpl<char> &utf8); +std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16); +std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, + SmallVectorImpl<char> &utf8); } // end namespace windows } // end namespace sys } // end namespace llvm. diff --git a/lib/Support/Windows/system_error.inc b/lib/Support/Windows/system_error.inc deleted file mode 100644 index 37ec81d..0000000 --- a/lib/Support/Windows/system_error.inc +++ /dev/null @@ -1,142 +0,0 @@ -//===- llvm/Support/Win32/system_error.inc - Windows error_code --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides the Windows specific implementation of the error_code -// and error_condition classes. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Windows code that -//=== is guaranteed to work on *all* Windows variants. -//===----------------------------------------------------------------------===// - -#include <windows.h> -#include <winerror.h> - -using namespace llvm; - -std::string -_system_error_category::message(int ev) const { - LPVOID lpMsgBuf = 0; - DWORD retval = ::FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - ev, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPSTR) &lpMsgBuf, - 0, - NULL); - if (retval == 0) { - ::LocalFree(lpMsgBuf); - return std::string("Unknown error"); - } - - std::string str( static_cast<LPCSTR>(lpMsgBuf) ); - ::LocalFree(lpMsgBuf); - - while (str.size() - && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r')) - str.erase( str.size()-1 ); - if (str.size() && str[str.size()-1] == '.') - str.erase( str.size()-1 ); - return str; -} - -// I'd rather not double the line count of the following. -#define MAP_ERR_TO_COND(x, y) case x: return make_error_condition(errc::y) - -error_condition -_system_error_category::default_error_condition(int ev) const { - switch (ev) { - MAP_ERR_TO_COND(0, success); - // Windows system -> posix_errno decode table ---------------------------// - // see WinError.h comments for descriptions of errors - MAP_ERR_TO_COND(ERROR_ACCESS_DENIED, permission_denied); - MAP_ERR_TO_COND(ERROR_ALREADY_EXISTS, file_exists); - MAP_ERR_TO_COND(ERROR_BAD_UNIT, no_such_device); - MAP_ERR_TO_COND(ERROR_BUFFER_OVERFLOW, filename_too_long); - MAP_ERR_TO_COND(ERROR_BUSY, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_BUSY_DRIVE, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_CANNOT_MAKE, permission_denied); - MAP_ERR_TO_COND(ERROR_CANTOPEN, io_error); - MAP_ERR_TO_COND(ERROR_CANTREAD, io_error); - MAP_ERR_TO_COND(ERROR_CANTWRITE, io_error); - MAP_ERR_TO_COND(ERROR_CURRENT_DIRECTORY, permission_denied); - MAP_ERR_TO_COND(ERROR_DEV_NOT_EXIST, no_such_device); - MAP_ERR_TO_COND(ERROR_DEVICE_IN_USE, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_DIR_NOT_EMPTY, directory_not_empty); - MAP_ERR_TO_COND(ERROR_DIRECTORY, invalid_argument); - MAP_ERR_TO_COND(ERROR_DISK_FULL, no_space_on_device); - MAP_ERR_TO_COND(ERROR_FILE_EXISTS, file_exists); - MAP_ERR_TO_COND(ERROR_FILE_NOT_FOUND, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_HANDLE_DISK_FULL, no_space_on_device); - MAP_ERR_TO_COND(ERROR_HANDLE_EOF, value_too_large); - MAP_ERR_TO_COND(ERROR_INVALID_ACCESS, permission_denied); - MAP_ERR_TO_COND(ERROR_INVALID_DRIVE, no_such_device); - MAP_ERR_TO_COND(ERROR_INVALID_FUNCTION, function_not_supported); - MAP_ERR_TO_COND(ERROR_INVALID_HANDLE, invalid_argument); - MAP_ERR_TO_COND(ERROR_INVALID_NAME, invalid_argument); - MAP_ERR_TO_COND(ERROR_LOCK_VIOLATION, no_lock_available); - MAP_ERR_TO_COND(ERROR_LOCKED, no_lock_available); - MAP_ERR_TO_COND(ERROR_NEGATIVE_SEEK, invalid_argument); - MAP_ERR_TO_COND(ERROR_NOACCESS, permission_denied); - MAP_ERR_TO_COND(ERROR_NOT_ENOUGH_MEMORY, not_enough_memory); - MAP_ERR_TO_COND(ERROR_NOT_READY, resource_unavailable_try_again); - MAP_ERR_TO_COND(ERROR_NOT_SAME_DEVICE, cross_device_link); - MAP_ERR_TO_COND(ERROR_OPEN_FAILED, io_error); - MAP_ERR_TO_COND(ERROR_OPEN_FILES, device_or_resource_busy); - MAP_ERR_TO_COND(ERROR_OPERATION_ABORTED, operation_canceled); - MAP_ERR_TO_COND(ERROR_OUTOFMEMORY, not_enough_memory); - MAP_ERR_TO_COND(ERROR_PATH_NOT_FOUND, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_BAD_NETPATH, no_such_file_or_directory); - MAP_ERR_TO_COND(ERROR_READ_FAULT, io_error); - MAP_ERR_TO_COND(ERROR_RETRY, resource_unavailable_try_again); - MAP_ERR_TO_COND(ERROR_SEEK, io_error); - MAP_ERR_TO_COND(ERROR_SHARING_VIOLATION, permission_denied); - MAP_ERR_TO_COND(ERROR_TOO_MANY_OPEN_FILES, too_many_files_open); - MAP_ERR_TO_COND(ERROR_WRITE_FAULT, io_error); - MAP_ERR_TO_COND(ERROR_WRITE_PROTECT, permission_denied); - MAP_ERR_TO_COND(ERROR_SEM_TIMEOUT, timed_out); - MAP_ERR_TO_COND(WSAEACCES, permission_denied); - MAP_ERR_TO_COND(WSAEADDRINUSE, address_in_use); - MAP_ERR_TO_COND(WSAEADDRNOTAVAIL, address_not_available); - MAP_ERR_TO_COND(WSAEAFNOSUPPORT, address_family_not_supported); - MAP_ERR_TO_COND(WSAEALREADY, connection_already_in_progress); - MAP_ERR_TO_COND(WSAEBADF, bad_file_descriptor); - MAP_ERR_TO_COND(WSAECONNABORTED, connection_aborted); - MAP_ERR_TO_COND(WSAECONNREFUSED, connection_refused); - MAP_ERR_TO_COND(WSAECONNRESET, connection_reset); - MAP_ERR_TO_COND(WSAEDESTADDRREQ, destination_address_required); - MAP_ERR_TO_COND(WSAEFAULT, bad_address); - MAP_ERR_TO_COND(WSAEHOSTUNREACH, host_unreachable); - MAP_ERR_TO_COND(WSAEINPROGRESS, operation_in_progress); - MAP_ERR_TO_COND(WSAEINTR, interrupted); - MAP_ERR_TO_COND(WSAEINVAL, invalid_argument); - MAP_ERR_TO_COND(WSAEISCONN, already_connected); - MAP_ERR_TO_COND(WSAEMFILE, too_many_files_open); - MAP_ERR_TO_COND(WSAEMSGSIZE, message_size); - MAP_ERR_TO_COND(WSAENAMETOOLONG, filename_too_long); - MAP_ERR_TO_COND(WSAENETDOWN, network_down); - MAP_ERR_TO_COND(WSAENETRESET, network_reset); - MAP_ERR_TO_COND(WSAENETUNREACH, network_unreachable); - MAP_ERR_TO_COND(WSAENOBUFS, no_buffer_space); - MAP_ERR_TO_COND(WSAENOPROTOOPT, no_protocol_option); - MAP_ERR_TO_COND(WSAENOTCONN, not_connected); - MAP_ERR_TO_COND(WSAENOTSOCK, not_a_socket); - MAP_ERR_TO_COND(WSAEOPNOTSUPP, operation_not_supported); - MAP_ERR_TO_COND(WSAEPROTONOSUPPORT, protocol_not_supported); - MAP_ERR_TO_COND(WSAEPROTOTYPE, wrong_protocol_type); - MAP_ERR_TO_COND(WSAETIMEDOUT, timed_out); - MAP_ERR_TO_COND(WSAEWOULDBLOCK, operation_would_block); - default: return error_condition(ev, system_category()); - } -} diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp index e5f9494..5212624 100644 --- a/lib/Support/YAMLTraits.cpp +++ b/lib/Support/YAMLTraits.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/YAMLTraits.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Casting.h" @@ -56,9 +57,7 @@ Input::Input(StringRef InputContent, Input::~Input() { } -error_code Input::error() { - return EC; -} +std::error_code Input::error() { return EC; } // Pin the vtables to this file. void Input::HNode::anchor() {} @@ -90,8 +89,8 @@ bool Input::setCurrentDocument() { return false; } -void Input::nextDocument() { - ++DocIterator; +bool Input::nextDocument() { + return ++DocIterator != Strm->end(); } bool Input::mapTag(StringRef Tag, bool Default) { diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index f55838e..f7c213a 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -22,10 +22,10 @@ #include "llvm/Support/Format.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" -#include "llvm/Support/system_error.h" #include <cctype> #include <cerrno> #include <sys/stat.h> +#include <system_error> // <fcntl.h> may provide O_BINARY. #if defined(HAVE_FCNTL_H) @@ -450,7 +450,7 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, return; } - error_code EC = sys::fs::openFileForWrite(Filename, FD, Flags); + std::error_code EC = sys::fs::openFileForWrite(Filename, FD, Flags); if (EC) { ErrorInfo = "Error opening output file '" + std::string(Filename) + "': " + diff --git a/lib/Support/regcclass.h b/lib/Support/regcclass.h index 2cea3e4..7fd6604 100644 --- a/lib/Support/regcclass.h +++ b/lib/Support/regcclass.h @@ -37,6 +37,9 @@ * @(#)cclass.h 8.3 (Berkeley) 3/20/94 */ +#ifndef LLVM_SUPPORT_REGCCLASS_H +#define LLVM_SUPPORT_REGCCLASS_H + /* character-class table */ static struct cclass { const char *name; @@ -68,3 +71,5 @@ static struct cclass { ""} , { NULL, 0, "" } }; + +#endif diff --git a/lib/Support/regcname.h b/lib/Support/regcname.h index 3c0bb24..891d255 100644 --- a/lib/Support/regcname.h +++ b/lib/Support/regcname.h @@ -35,6 +35,9 @@ * @(#)cname.h 8.3 (Berkeley) 3/20/94 */ +#ifndef LLVM_SUPPORT_REGCNAME_H +#define LLVM_SUPPORT_REGCNAME_H + /* character-name table */ static struct cname { const char *name; @@ -137,3 +140,5 @@ static struct cname { { "DEL", '\177' }, { NULL, 0 } }; + +#endif diff --git a/lib/Support/regex2.h b/lib/Support/regex2.h index 21659c3..d81bfbc 100644 --- a/lib/Support/regex2.h +++ b/lib/Support/regex2.h @@ -35,6 +35,9 @@ * @(#)regex2.h 8.4 (Berkeley) 3/20/94 */ +#ifndef LLVM_SUPPORT_REGEX2_H +#define LLVM_SUPPORT_REGEX2_H + /* * internals of regex_t */ @@ -155,3 +158,5 @@ struct re_guts { /* misc utilities */ #define OUT (CHAR_MAX+1) /* a non-character value */ #define ISWORD(c) (isalnum(c&0xff) || (c) == '_') + +#endif diff --git a/lib/Support/regutils.h b/lib/Support/regutils.h index d0ee100..49a975c 100644 --- a/lib/Support/regutils.h +++ b/lib/Support/regutils.h @@ -35,6 +35,9 @@ * @(#)utils.h 8.3 (Berkeley) 3/20/94 */ +#ifndef LLVM_SUPPORT_REGUTILS_H +#define LLVM_SUPPORT_REGUTILS_H + /* utility definitions */ #define NC (CHAR_MAX - CHAR_MIN + 1) typedef unsigned char uch; @@ -51,3 +54,5 @@ typedef unsigned char uch; #ifdef USEBCOPY #define memmove(d, s, c) bcopy(s, d, c) #endif + +#endif diff --git a/lib/Support/system_error.cpp b/lib/Support/system_error.cpp deleted file mode 100644 index 299f54a..0000000 --- a/lib/Support/system_error.cpp +++ /dev/null @@ -1,130 +0,0 @@ -//===---------------------- system_error.cpp ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This was lifted from libc++ and modified for C++03. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/system_error.h" -#include "llvm/Support/Errno.h" -#include <cstring> -#include <string> - -namespace llvm { - -// class error_category - -error_category::error_category() { -} - -error_category::~error_category() { -} - -error_condition -error_category::default_error_condition(int ev) const { - return error_condition(ev, *this); -} - -bool -error_category::equivalent(int code, const error_condition& condition) const { - return default_error_condition(code) == condition; -} - -bool -error_category::equivalent(const error_code& code, int condition) const { - return *this == code.category() && code.value() == condition; -} - -std::string -_do_message::message(int ev) const { - return std::string(sys::StrError(ev)); -} - -class _generic_error_category : public _do_message { -public: - const char* name() const override; - std::string message(int ev) const override; -}; - -const char* -_generic_error_category::name() const { - return "generic"; -} - -std::string -_generic_error_category::message(int ev) const { -#ifdef ELAST - if (ev > ELAST) - return std::string("unspecified generic_category error"); -#endif // ELAST - return _do_message::message(ev); -} - -const error_category& -generic_category() { - static _generic_error_category s; - return s; -} - -class _system_error_category : public _do_message { -public: - const char* name() const override; - std::string message(int ev) const override; - error_condition default_error_condition(int ev) const override; -}; - -const char* -_system_error_category::name() const { - return "system"; -} - -// std::string _system_error_category::message(int ev) const { -// Is in Platform/system_error.inc - -// error_condition _system_error_category::default_error_condition(int ev) const -// Is in Platform/system_error.inc - -const error_category& -system_category() { - static _system_error_category s; - return s; -} - -const error_category& -posix_category() { -#ifdef LLVM_ON_WIN32 - return generic_category(); -#else - return system_category(); -#endif -} - -// error_condition - -std::string -error_condition::message() const { - return _cat_->message(_val_); -} - -// error_code - -std::string -error_code::message() const { - return _cat_->message(_val_); -} - -} // end namespace llvm - -// Include the truly platform-specific parts of this class. -#if defined(LLVM_ON_UNIX) -#include "Unix/system_error.inc" -#endif -#if defined(LLVM_ON_WIN32) -#include "Windows/system_error.inc" -#endif |