diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 |
commit | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (patch) | |
tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/Support | |
parent | 678318cd20f7db4e6c6b85d83fe00fa327b04fca (diff) | |
parent | e27feadae0885aa074df58ebfda2e7a7f7a7d590 (diff) | |
download | FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.zip FreeBSD-src-2c8643c6396b0a3db33430cf9380e70bbb9efce0.tar.gz |
Merge llvm 3.5.0 release from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/Support')
92 files changed, 3262 insertions, 3356 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp index 676e2d4..7989e30 100644 --- a/contrib/llvm/lib/Support/APFloat.cpp +++ b/contrib/llvm/lib/Support/APFloat.cpp @@ -683,6 +683,20 @@ APFloat::operator=(const APFloat &rhs) return *this; } +APFloat & +APFloat::operator=(APFloat &&rhs) { + freeSignificand(); + + semantics = rhs.semantics; + significand = rhs.significand; + exponent = rhs.exponent; + category = rhs.category; + sign = rhs.sign; + + rhs.semantics = &Bogus; + return *this; +} + bool APFloat::isDenormal() const { return isFiniteNonZero() && (exponent == semantics->minExponent) && @@ -806,6 +820,10 @@ APFloat::APFloat(const APFloat &rhs) { assign(rhs); } +APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) { + *this = std::move(rhs); +} + APFloat::~APFloat() { freeSignificand(); @@ -1340,7 +1358,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1354,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; @@ -1467,7 +1487,7 @@ APFloat::multiplySpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1511,7 +1531,7 @@ APFloat::divideSpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): @@ -1552,7 +1572,7 @@ APFloat::modSpecials(const APFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -1661,7 +1681,7 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) fs = multiplySpecials(rhs); if (isFiniteNonZero()) { - lostFraction lost_fraction = multiplySignificand(rhs, 0); + lostFraction lost_fraction = multiplySignificand(rhs, nullptr); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -1864,7 +1884,7 @@ APFloat::compare(const APFloat &rhs) const switch (PackCategoriesIntoKey(category, rhs.category)) { default: - llvm_unreachable(0); + llvm_unreachable(nullptr); case PackCategoriesIntoKey(fcNaN, fcZero): case PackCategoriesIntoKey(fcNaN, fcNormal): @@ -2421,7 +2441,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, if (exp >= 0) { /* multiplySignificand leaves the precision-th bit set to 1. */ - calcLostFraction = decSig.multiplySignificand(pow5, NULL); + calcLostFraction = decSig.multiplySignificand(pow5, nullptr); powHUerr = powStatus != opOK; } else { calcLostFraction = decSig.divideSignificand(pow5); @@ -3313,7 +3333,7 @@ APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api) if (Sem == &PPCDoubleDouble) return initFromPPCDoubleDoubleAPInt(api); - llvm_unreachable(0); + llvm_unreachable(nullptr); } APFloat @@ -3776,8 +3796,8 @@ APFloat::opStatus APFloat::next(bool nextDown) { // change the payload. if (isSignaling()) { result = opInvalidOp; - // For consistency, propogate the sign of the sNaN to the qNaN. - makeNaN(false, isNegative(), 0); + // For consistency, propagate the sign of the sNaN to the qNaN. + makeNaN(false, isNegative(), nullptr); } break; case fcZero: @@ -3816,7 +3836,7 @@ APFloat::opStatus APFloat::next(bool nextDown) { // Decrement the significand. // // We always do this since: - // 1. If we are dealing with a non binade decrement, by definition we + // 1. If we are dealing with a non-binade decrement, by definition we // just decrement the significand. // 2. If we are dealing with a normal -> normal binade decrement, since // we have an explicit integral bit the fact that all bits but the diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp index 89f96bd..fa929eb 100644 --- a/contrib/llvm/lib/Support/APInt.cpp +++ b/contrib/llvm/lib/Support/APInt.cpp @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "apint" #include "llvm/ADT/APInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" @@ -28,6 +27,8 @@ #include <limits> using namespace llvm; +#define DEBUG_TYPE "apint" + /// A utility function for allocating memory, checking for allocation failures, /// and ensuring the contents are zeroed. inline static uint64_t* getClearedMemory(unsigned numWords) { @@ -1096,7 +1097,7 @@ APInt APInt::ashr(unsigned shiftAmt) const { // to include in this word. val[breakWord] = pVal[breakWord+offset] >> wordShift; - // Deal with sign extenstion in the break word, and possibly the word before + // Deal with sign extension in the break word, and possibly the word before // it. if (isNegative()) { if (wordShift > bitsInWord) { @@ -1683,10 +1684,10 @@ void APInt::divide(const APInt LHS, unsigned lhsWords, // Allocate space for the temporary values we need either on the stack, if // it will fit, or on the heap if it won't. unsigned SPACE[128]; - unsigned *U = 0; - unsigned *V = 0; - unsigned *Q = 0; - unsigned *R = 0; + unsigned *U = nullptr; + unsigned *V = nullptr; + unsigned *Q = nullptr; + unsigned *R = nullptr; if ((Remainder?4:3)*n+2*m+1 <= 128) { U = &SPACE[0]; V = &SPACE[m+n+1]; @@ -1872,7 +1873,7 @@ APInt APInt::udiv(const APInt& RHS) const { // We have to compute it the hard way. Invoke the Knuth divide algorithm. APInt Quotient(1,0); // to hold result. - divide(*this, lhsWords, RHS, rhsWords, &Quotient, 0); + divide(*this, lhsWords, RHS, rhsWords, &Quotient, nullptr); return Quotient; } @@ -1920,7 +1921,7 @@ APInt APInt::urem(const APInt& RHS) const { // We have to compute it the hard way. Invoke the Knuth divide algorithm. APInt Remainder(1,0); - divide(*this, lhsWords, RHS, rhsWords, 0, &Remainder); + divide(*this, lhsWords, RHS, rhsWords, nullptr, &Remainder); return Remainder; } diff --git a/contrib/llvm/lib/Support/ARMBuildAttrs.cpp b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp new file mode 100644 index 0000000..960a0f1 --- /dev/null +++ b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp @@ -0,0 +1,95 @@ +//===-- ARMBuildAttrs.cpp - ARM Build Attributes --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ARMBuildAttributes.h" +#include "llvm/ADT/StringRef.h" + +using namespace llvm; + +namespace { +const struct { + ARMBuildAttrs::AttrType Attr; + const char *TagName; +} ARMAttributeTags[] = { + { ARMBuildAttrs::File, "Tag_File" }, + { ARMBuildAttrs::Section, "Tag_Section" }, + { ARMBuildAttrs::Symbol, "Tag_Symbol" }, + { ARMBuildAttrs::CPU_raw_name, "Tag_CPU_raw_name" }, + { ARMBuildAttrs::CPU_name, "Tag_CPU_name" }, + { ARMBuildAttrs::CPU_arch, "Tag_CPU_arch" }, + { ARMBuildAttrs::CPU_arch_profile, "Tag_CPU_arch_profile" }, + { ARMBuildAttrs::ARM_ISA_use, "Tag_ARM_ISA_use" }, + { ARMBuildAttrs::THUMB_ISA_use, "Tag_THUMB_ISA_use" }, + { ARMBuildAttrs::FP_arch, "Tag_FP_arch" }, + { ARMBuildAttrs::WMMX_arch, "Tag_WMMX_arch" }, + { ARMBuildAttrs::Advanced_SIMD_arch, "Tag_Advanced_SIMD_arch" }, + { ARMBuildAttrs::PCS_config, "Tag_PCS_config" }, + { ARMBuildAttrs::ABI_PCS_R9_use, "Tag_ABI_PCS_R9_use" }, + { ARMBuildAttrs::ABI_PCS_RW_data, "Tag_ABI_PCS_RW_data" }, + { ARMBuildAttrs::ABI_PCS_RO_data, "Tag_ABI_PCS_RO_data" }, + { ARMBuildAttrs::ABI_PCS_GOT_use, "Tag_ABI_PCS_GOT_use" }, + { ARMBuildAttrs::ABI_PCS_wchar_t, "Tag_ABI_PCS_wchar_t" }, + { ARMBuildAttrs::ABI_FP_rounding, "Tag_ABI_FP_rounding" }, + { ARMBuildAttrs::ABI_FP_denormal, "Tag_ABI_FP_denormal" }, + { ARMBuildAttrs::ABI_FP_exceptions, "Tag_ABI_FP_exceptions" }, + { ARMBuildAttrs::ABI_FP_user_exceptions, "Tag_ABI_FP_user_exceptions" }, + { ARMBuildAttrs::ABI_FP_number_model, "Tag_ABI_FP_number_model" }, + { ARMBuildAttrs::ABI_align_needed, "Tag_ABI_align_needed" }, + { ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align_preserved" }, + { ARMBuildAttrs::ABI_enum_size, "Tag_ABI_enum_size" }, + { ARMBuildAttrs::ABI_HardFP_use, "Tag_ABI_HardFP_use" }, + { ARMBuildAttrs::ABI_VFP_args, "Tag_ABI_VFP_args" }, + { ARMBuildAttrs::ABI_WMMX_args, "Tag_ABI_WMMX_args" }, + { ARMBuildAttrs::ABI_optimization_goals, "Tag_ABI_optimization_goals" }, + { ARMBuildAttrs::ABI_FP_optimization_goals, "Tag_ABI_FP_optimization_goals" }, + { ARMBuildAttrs::compatibility, "Tag_compatibility" }, + { ARMBuildAttrs::CPU_unaligned_access, "Tag_CPU_unaligned_access" }, + { ARMBuildAttrs::FP_HP_extension, "Tag_FP_HP_extension" }, + { ARMBuildAttrs::ABI_FP_16bit_format, "Tag_ABI_FP_16bit_format" }, + { ARMBuildAttrs::MPextension_use, "Tag_MPextension_use" }, + { ARMBuildAttrs::DIV_use, "Tag_DIV_use" }, + { ARMBuildAttrs::nodefaults, "Tag_nodefaults" }, + { ARMBuildAttrs::also_compatible_with, "Tag_also_compatible_with" }, + { ARMBuildAttrs::T2EE_use, "Tag_T2EE_use" }, + { ARMBuildAttrs::conformance, "Tag_conformance" }, + { ARMBuildAttrs::Virtualization_use, "Tag_Virtualization_use" }, + + // Legacy Names + { ARMBuildAttrs::FP_arch, "Tag_VFP_arch" }, + { ARMBuildAttrs::FP_HP_extension, "Tag_VFP_HP_extension" }, + { ARMBuildAttrs::ABI_align_needed, "Tag_ABI_align8_needed" }, + { ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved" }, +}; +} + +namespace llvm { +namespace ARMBuildAttrs { +StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix) { + return AttrTypeAsString(static_cast<AttrType>(Attr), HasTagPrefix); +} + +StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix) { + for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags); + TI != TE; ++TI) + if (ARMAttributeTags[TI].Attr == Attr) + return ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4); + return ""; +} + +int AttrTypeFromString(StringRef Tag) { + bool HasTagPrefix = Tag.startswith("Tag_"); + for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags); + TI != TE; ++TI) + if (StringRef(ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4)) == Tag) + return ARMAttributeTags[TI].Attr; + return -1; +} +} +} + diff --git a/contrib/llvm/lib/Support/ARMWinEH.cpp b/contrib/llvm/lib/Support/ARMWinEH.cpp new file mode 100644 index 0000000..03c150f --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/Support/Allocator.cpp b/contrib/llvm/lib/Support/Allocator.cpp index 6e7a541..7c306b2 100644 --- a/contrib/llvm/lib/Support/Allocator.cpp +++ b/contrib/llvm/lib/Support/Allocator.cpp @@ -21,149 +21,10 @@ namespace llvm { -BumpPtrAllocator::BumpPtrAllocator(size_t size, size_t threshold, - SlabAllocator &allocator) - : SlabSize(size), SizeThreshold(std::min(size, threshold)), - Allocator(allocator), CurSlab(0), BytesAllocated(0) { } - -BumpPtrAllocator::BumpPtrAllocator(size_t size, size_t threshold) - : SlabSize(size), SizeThreshold(std::min(size, threshold)), - Allocator(DefaultSlabAllocator), CurSlab(0), BytesAllocated(0) { } - -BumpPtrAllocator::~BumpPtrAllocator() { - DeallocateSlabs(CurSlab); -} - -/// AlignPtr - Align Ptr to Alignment bytes, rounding up. Alignment should -/// be a power of two. This method rounds up, so AlignPtr(7, 4) == 8 and -/// AlignPtr(8, 4) == 8. -char *BumpPtrAllocator::AlignPtr(char *Ptr, size_t Alignment) { - assert(Alignment && (Alignment & (Alignment - 1)) == 0 && - "Alignment is not a power of two!"); - - // Do the alignment. - return (char*)(((uintptr_t)Ptr + Alignment - 1) & - ~(uintptr_t)(Alignment - 1)); -} - -/// StartNewSlab - Allocate a new slab and move the bump pointers over into -/// the new slab. Modifies CurPtr and End. -void BumpPtrAllocator::StartNewSlab() { - // If we allocated a big number of slabs already it's likely that we're going - // to allocate more. Increase slab size to reduce mallocs and possibly memory - // overhead. The factors are chosen conservatively to avoid overallocation. - if (BytesAllocated >= SlabSize * 128) - SlabSize *= 2; - - MemSlab *NewSlab = Allocator.Allocate(SlabSize); - NewSlab->NextPtr = CurSlab; - CurSlab = NewSlab; - CurPtr = (char*)(CurSlab + 1); - End = ((char*)CurSlab) + CurSlab->Size; -} - -/// DeallocateSlabs - Deallocate all memory slabs after and including this -/// one. -void BumpPtrAllocator::DeallocateSlabs(MemSlab *Slab) { - while (Slab) { - MemSlab *NextSlab = Slab->NextPtr; -#ifndef NDEBUG - // Poison the memory so stale pointers crash sooner. Note we must - // preserve the Size and NextPtr fields at the beginning. - sys::Memory::setRangeWritable(Slab + 1, Slab->Size - sizeof(MemSlab)); - memset(Slab + 1, 0xCD, Slab->Size - sizeof(MemSlab)); -#endif - Allocator.Deallocate(Slab); - Slab = NextSlab; - } -} - -/// Reset - Deallocate all but the current slab and reset the current pointer -/// to the beginning of it, freeing all memory allocated so far. -void BumpPtrAllocator::Reset() { - if (!CurSlab) - return; - DeallocateSlabs(CurSlab->NextPtr); - CurSlab->NextPtr = 0; - CurPtr = (char*)(CurSlab + 1); - End = ((char*)CurSlab) + CurSlab->Size; - BytesAllocated = 0; -} - -/// Allocate - Allocate space at the specified alignment. -/// -void *BumpPtrAllocator::Allocate(size_t Size, size_t Alignment) { - if (!CurSlab) // Start a new slab if we haven't allocated one already. - StartNewSlab(); - - // Keep track of how many bytes we've allocated. - BytesAllocated += Size; - - // 0-byte alignment means 1-byte alignment. - if (Alignment == 0) Alignment = 1; - - // Allocate the aligned space, going forwards from CurPtr. - char *Ptr = AlignPtr(CurPtr, Alignment); - - // Check if we can hold it. - if (Ptr + Size <= End) { - CurPtr = Ptr + Size; - // Update the allocation point of this memory block in MemorySanitizer. - // Without this, MemorySanitizer messages for values originated from here - // will point to the allocation of the entire slab. - __msan_allocated_memory(Ptr, Size); - return Ptr; - } - - // If Size is really big, allocate a separate slab for it. - size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1; - if (PaddedSize > SizeThreshold) { - MemSlab *NewSlab = Allocator.Allocate(PaddedSize); - - // Put the new slab after the current slab, since we are not allocating - // into it. - NewSlab->NextPtr = CurSlab->NextPtr; - CurSlab->NextPtr = NewSlab; - - Ptr = AlignPtr((char*)(NewSlab + 1), Alignment); - assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size); - __msan_allocated_memory(Ptr, Size); - return Ptr; - } - - // Otherwise, start a new slab and try again. - StartNewSlab(); - Ptr = AlignPtr(CurPtr, Alignment); - CurPtr = Ptr + Size; - assert(CurPtr <= End && "Unable to allocate memory!"); - __msan_allocated_memory(Ptr, Size); - return Ptr; -} - -unsigned BumpPtrAllocator::GetNumSlabs() const { - unsigned NumSlabs = 0; - for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { - ++NumSlabs; - } - return NumSlabs; -} - -size_t BumpPtrAllocator::getTotalMemory() const { - size_t TotalMemory = 0; - for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { - TotalMemory += Slab->Size; - } - return TotalMemory; -} - -void BumpPtrAllocator::PrintStats() const { - unsigned NumSlabs = 0; - size_t TotalMemory = 0; - for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { - TotalMemory += Slab->Size; - ++NumSlabs; - } +namespace detail { +void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated, + size_t TotalMemory) { errs() << "\nNumber of memory regions: " << NumSlabs << '\n' << "Bytes used: " << BytesAllocated << '\n' << "Bytes allocated: " << TotalMemory << '\n' @@ -171,20 +32,7 @@ void BumpPtrAllocator::PrintStats() const { << " (includes alignment, etc)\n"; } -SlabAllocator::~SlabAllocator() { } - -MallocSlabAllocator::~MallocSlabAllocator() { } - -MemSlab *MallocSlabAllocator::Allocate(size_t Size) { - MemSlab *Slab = (MemSlab*)Allocator.Allocate(Size, 0); - Slab->Size = Size; - Slab->NextPtr = 0; - return Slab; -} - -void MallocSlabAllocator::Deallocate(MemSlab *Slab) { - Allocator.Deallocate(Slab); -} +} // End namespace detail. void PrintRecyclerStats(size_t Size, size_t Align, diff --git a/contrib/llvm/lib/Support/Atomic.cpp b/contrib/llvm/lib/Support/Atomic.cpp index 9559ad7..ac4ff3e 100644 --- a/contrib/llvm/lib/Support/Atomic.cpp +++ b/contrib/llvm/lib/Support/Atomic.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This header file implements atomic operations. +// This file implements atomic operations. // //===----------------------------------------------------------------------===// @@ -17,6 +17,7 @@ using namespace llvm; #if defined(_MSC_VER) +#include <Intrin.h> #include <windows.h> #undef MemoryFence #endif diff --git a/contrib/llvm/lib/Support/BlockFrequency.cpp b/contrib/llvm/lib/Support/BlockFrequency.cpp index 00efe90..6f7e341 100644 --- a/contrib/llvm/lib/Support/BlockFrequency.cpp +++ b/contrib/llvm/lib/Support/BlockFrequency.cpp @@ -18,94 +18,8 @@ using namespace llvm; -/// Multiply FREQ by N and store result in W array. -static void mult96bit(uint64_t freq, uint32_t N, uint32_t W[3]) { - uint64_t u0 = freq & UINT32_MAX; - uint64_t u1 = freq >> 32; - - // Represent 96-bit value as W[2]:W[1]:W[0]; - uint64_t t = u0 * N; - uint64_t k = t >> 32; - W[0] = t; - t = u1 * N + k; - W[1] = t; - W[2] = t >> 32; -} - -/// Divide 96-bit value stored in W[2]:W[1]:W[0] by D. Since our word size is a -/// 32 bit unsigned integer, we can use a short division algorithm. -static uint64_t divrem96bit(uint32_t W[3], uint32_t D, uint32_t *Rout) { - // We assume that W[2] is non-zero since if W[2] is not then the user should - // just use hardware division. - assert(W[2] && "This routine assumes that W[2] is non-zero since if W[2] is " - "zero, the caller should just use 64/32 hardware."); - uint32_t Q[3] = { 0, 0, 0 }; - - // The generalized short division algorithm sets i to m + n - 1, where n is - // the number of words in the divisior and m is the number of words by which - // the divident exceeds the divisor (i.e. m + n == the length of the dividend - // in words). Due to our assumption that W[2] is non-zero, we know that the - // dividend is of length 3 implying since n is 1 that m = 2. Thus we set i to - // m + n - 1 = 2 + 1 - 1 = 2. - uint32_t R = 0; - for (int i = 2; i >= 0; --i) { - uint64_t PartialD = uint64_t(R) << 32 | W[i]; - if (PartialD == 0) { - Q[i] = 0; - R = 0; - } else if (PartialD < D) { - Q[i] = 0; - R = uint32_t(PartialD); - } else if (PartialD == D) { - Q[i] = 1; - R = 0; - } else { - Q[i] = uint32_t(PartialD / D); - R = uint32_t(PartialD - (Q[i] * D)); - } - } - - // If Q[2] is non-zero, then we overflowed. - uint64_t Result; - if (Q[2]) { - Result = UINT64_MAX; - R = D; - } else { - // Form the final uint64_t result, avoiding endianness issues. - Result = uint64_t(Q[0]) | (uint64_t(Q[1]) << 32); - } - - if (Rout) - *Rout = R; - - return Result; -} - -uint32_t BlockFrequency::scale(uint32_t N, uint32_t D) { - assert(D != 0 && "Division by zero"); - - // Calculate Frequency * N. - uint64_t MulLo = (Frequency & UINT32_MAX) * N; - uint64_t MulHi = (Frequency >> 32) * N; - uint64_t MulRes = (MulHi << 32) + MulLo; - - // If the product fits in 64 bits, just use built-in division. - if (MulHi <= UINT32_MAX && MulRes >= MulLo) { - Frequency = MulRes / D; - return MulRes % D; - } - - // Product overflowed, use 96-bit operations. - // 96-bit value represented as W[2]:W[1]:W[0]. - uint32_t W[3]; - uint32_t R; - mult96bit(Frequency, N, W); - Frequency = divrem96bit(W, D, &R); - return R; -} - BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) { - scale(Prob.getNumerator(), Prob.getDenominator()); + Frequency = Prob.scale(Frequency); return *this; } @@ -117,7 +31,7 @@ BlockFrequency::operator*(const BranchProbability &Prob) const { } BlockFrequency &BlockFrequency::operator/=(const BranchProbability &Prob) { - scale(Prob.getDenominator(), Prob.getNumerator()); + Frequency = Prob.scaleByInverse(Frequency); return *this; } @@ -145,28 +59,14 @@ BlockFrequency::operator+(const BlockFrequency &Prob) const { return Freq; } -uint32_t BlockFrequency::scale(const BranchProbability &Prob) { - return scale(Prob.getNumerator(), Prob.getDenominator()); -} - -void BlockFrequency::print(raw_ostream &OS) const { - // Convert fixed-point number to decimal. - OS << Frequency / getEntryFrequency() << "."; - uint64_t Rem = Frequency % getEntryFrequency(); - uint64_t Eps = 1; - do { - Rem *= 10; - Eps *= 10; - OS << Rem / getEntryFrequency(); - Rem = Rem % getEntryFrequency(); - } while (Rem >= Eps/2); -} +BlockFrequency &BlockFrequency::operator>>=(const unsigned count) { + // Frequency can never be 0 by design. + assert(Frequency != 0); -namespace llvm { - -raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) { - Freq.print(OS); - return OS; -} + // Shift right by count. + Frequency >>= count; + // Saturate to 1 if we are 0. + Frequency |= Frequency == 0; + return *this; } diff --git a/contrib/llvm/lib/Support/BranchProbability.cpp b/contrib/llvm/lib/Support/BranchProbability.cpp index e8b83e5..65878d6 100644 --- a/contrib/llvm/lib/Support/BranchProbability.cpp +++ b/contrib/llvm/lib/Support/BranchProbability.cpp @@ -18,19 +18,56 @@ using namespace llvm; -void BranchProbability::print(raw_ostream &OS) const { - OS << N << " / " << D << " = " << format("%g%%", ((double)N / D) * 100.0); +raw_ostream &BranchProbability::print(raw_ostream &OS) const { + return OS << N << " / " << D << " = " + << format("%g%%", ((double)N / D) * 100.0); } -void BranchProbability::dump() const { - dbgs() << *this << '\n'; -} +void BranchProbability::dump() const { print(dbgs()) << '\n'; } + +static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D) { + assert(D && "divide by 0"); + + // Fast path for multiplying by 1.0. + if (!Num || D == N) + return Num; + + // Split Num into upper and lower parts to multiply, then recombine. + uint64_t ProductHigh = (Num >> 32) * N; + uint64_t ProductLow = (Num & UINT32_MAX) * N; + + // Split into 32-bit digits. + uint32_t Upper32 = ProductHigh >> 32; + uint32_t Lower32 = ProductLow & UINT32_MAX; + uint32_t Mid32Partial = ProductHigh & UINT32_MAX; + uint32_t Mid32 = Mid32Partial + (ProductLow >> 32); + + // Carry. + Upper32 += Mid32 < Mid32Partial; -namespace llvm { + // Check for overflow. + if (Upper32 >= D) + return UINT64_MAX; + + uint64_t Rem = (uint64_t(Upper32) << 32) | Mid32; + uint64_t UpperQ = Rem / D; + + // Check for overflow. + if (UpperQ > UINT32_MAX) + return UINT64_MAX; + + Rem = ((Rem % D) << 32) | Lower32; + uint64_t LowerQ = Rem / D; + uint64_t Q = (UpperQ << 32) + LowerQ; + + // Check for overflow. + return Q < LowerQ ? UINT64_MAX : Q; +} -raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) { - Prob.print(OS); - return OS; +uint64_t BranchProbability::scale(uint64_t Num) const { + return ::scale(Num, N, D); } +uint64_t BranchProbability::scaleByInverse(uint64_t Num) const { + return ::scale(Num, D, N); } diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp index 44a88d8..586ecea 100644 --- a/contrib/llvm/lib/Support/CommandLine.cpp +++ b/contrib/llvm/lib/Support/CommandLine.cpp @@ -18,7 +18,6 @@ #include "llvm/Support/CommandLine.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" @@ -32,13 +31,15 @@ #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; +#define DEBUG_TYPE "commandline" + //===----------------------------------------------------------------------===// // Template instantiations and anchors. // @@ -82,7 +83,7 @@ void StringSaver::anchor() {} // Globals for name and overview of program. Program name is not a string to // avoid static ctor/dtor issues. static char ProgramName[80] = "<premain>"; -static const char *ProgramOverview = 0; +static const char *ProgramOverview = nullptr; // This collects additional help to be printed. static ManagedStatic<std::vector<const char*> > MoreHelp; @@ -101,16 +102,23 @@ void cl::MarkOptionsChanged() { /// RegisteredOptionList - This is the list of the command line options that /// have statically constructed themselves. -static Option *RegisteredOptionList = 0; +static Option *RegisteredOptionList = nullptr; void Option::addArgument() { - assert(NextRegistered == 0 && "argument multiply registered!"); + assert(!NextRegistered && "argument multiply registered!"); NextRegistered = RegisteredOptionList; RegisteredOptionList = this; MarkOptionsChanged(); } +void Option::removeArgument() { + assert(NextRegistered && "argument never registered"); + assert(RegisteredOptionList == this && "argument is not the last registered"); + RegisteredOptionList = NextRegistered; + MarkOptionsChanged(); +} + // This collects the different option categories that have been registered. typedef SmallPtrSet<OptionCategory*,16> OptionCatSet; static ManagedStatic<OptionCatSet> RegisteredOptionCategories; @@ -118,8 +126,13 @@ static ManagedStatic<OptionCatSet> RegisteredOptionCategories; // Initialise the general option category. OptionCategory llvm::cl::GeneralCategory("General options"); -void OptionCategory::registerCategory() -{ +void OptionCategory::registerCategory() { + assert(std::count_if(RegisteredOptionCategories->begin(), + RegisteredOptionCategories->end(), + [this](const OptionCategory *Category) { + return getName() == Category->getName(); + }) == 0 && "Duplicate option categories"); + RegisteredOptionCategories->insert(this); } @@ -132,8 +145,9 @@ 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 = 0; // The ConsumeAfter option if it exists. + Option *CAOpt = nullptr; // The ConsumeAfter option if it exists. for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) { // If this option wants to handle multiple option names, get the full set. // This handles enum options like "-O1 -O2" etc. @@ -145,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; } } @@ -158,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; } } @@ -169,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"); } @@ -178,7 +201,7 @@ static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, static Option *LookupOption(StringRef &Arg, StringRef &Value, const StringMap<Option*> &OptionsMap) { // Reject all dashes. - if (Arg.empty()) return 0; + if (Arg.empty()) return nullptr; size_t EqualPos = Arg.find('='); @@ -186,14 +209,14 @@ static Option *LookupOption(StringRef &Arg, StringRef &Value, if (EqualPos == StringRef::npos) { // Look up the option. StringMap<Option*>::const_iterator I = OptionsMap.find(Arg); - return I != OptionsMap.end() ? I->second : 0; + return I != OptionsMap.end() ? I->second : nullptr; } // If the argument before the = is a valid option name, we match. If not, // return Arg unmolested. StringMap<Option*>::const_iterator I = OptionsMap.find(Arg.substr(0, EqualPos)); - if (I == OptionsMap.end()) return 0; + if (I == OptionsMap.end()) return nullptr; Value = Arg.substr(EqualPos+1); Arg = Arg.substr(0, EqualPos); @@ -208,7 +231,7 @@ static Option *LookupNearestOption(StringRef Arg, const StringMap<Option*> &OptionsMap, std::string &NearestString) { // Reject all dashes. - if (Arg.empty()) return 0; + if (Arg.empty()) return nullptr; // Split on any equal sign. std::pair<StringRef, StringRef> SplitArg = Arg.split('='); @@ -216,7 +239,7 @@ static Option *LookupNearestOption(StringRef Arg, StringRef &RHS = SplitArg.second; // Find the closest match. - Option *Best = 0; + Option *Best = nullptr; unsigned BestDistance = 0; for (StringMap<Option*>::const_iterator it = OptionsMap.begin(), ie = OptionsMap.end(); it != ie; ++it) { @@ -246,12 +269,11 @@ static Option *LookupNearestOption(StringRef Arg, return Best; } -/// CommaSeparateAndAddOccurence - A wrapper around Handler->addOccurence() that -/// does special handling of cl::CommaSeparated options. -static bool CommaSeparateAndAddOccurence(Option *Handler, unsigned pos, - StringRef ArgName, - StringRef Value, bool MultiArg = false) -{ +/// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence() +/// that does special handling of cl::CommaSeparated options. +static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos, + StringRef ArgName, StringRef Value, + bool MultiArg = false) { // Check to see if this option accepts a comma separated list of values. If // it does, we have to split up the value into multiple values. if (Handler->getMiscFlags() & CommaSeparated) { @@ -290,7 +312,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, // Enforce value requirements switch (Handler->getValueExpectedFlag()) { case ValueRequired: - if (Value.data() == 0) { // No value specified? + if (!Value.data()) { // No value specified? if (i+1 >= argc) return Handler->error("requires a value!"); // Steal the next argument, like for '-o filename' @@ -312,13 +334,13 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, // If this isn't a multi-arg option, just run the handler. if (NumAdditionalVals == 0) - return CommaSeparateAndAddOccurence(Handler, i, ArgName, Value); + return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value); // If it is, run the handle several times. bool MultiArg = false; if (Value.data()) { - if (CommaSeparateAndAddOccurence(Handler, i, ArgName, Value, MultiArg)) + if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) return true; --NumAdditionalVals; MultiArg = true; @@ -329,7 +351,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, return Handler->error("not enough values!"); Value = argv[++i]; - if (CommaSeparateAndAddOccurence(Handler, i, ArgName, Value, MultiArg)) + if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) return true; MultiArg = true; --NumAdditionalVals; @@ -339,7 +361,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { int Dummy = i; - return ProvideOption(Handler, Handler->ArgStr, Arg, 0, 0, Dummy); + return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); } @@ -375,7 +397,7 @@ static Option *getOptionPred(StringRef Name, size_t &Length, Length = Name.size(); return OMI->second; // Found one! } - return 0; // No option found! + return nullptr; // No option found! } /// HandlePrefixedOrGroupedOption - The specified argument string (which started @@ -385,12 +407,12 @@ static Option *getOptionPred(StringRef Name, size_t &Length, static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, bool &ErrorParsing, const StringMap<Option*> &OptionsMap) { - if (Arg.size() == 1) return 0; + if (Arg.size() == 1) return nullptr; // Do the lookup! size_t Length = 0; Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap); - if (PGOpt == 0) return 0; + if (!PGOpt) return nullptr; // If the option is a prefixed option, then the value is simply the // rest of the name... so fall through to later processing, by @@ -417,7 +439,7 @@ static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, "Option can not be cl::Grouping AND cl::ValueRequired!"); int Dummy = 0; ErrorParsing |= ProvideOption(PGOpt, OneArgName, - StringRef(), 0, 0, Dummy); + StringRef(), 0, nullptr, Dummy); // Get the next grouping option. PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap); @@ -609,9 +631,11 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, static bool ExpandResponseFile(const char *FName, StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &NewArgv) { - OwningPtr<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. @@ -634,7 +658,7 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver, bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv) { unsigned RspFiles = 0; - bool AllExpanded = false; + bool AllExpanded = true; // Don't cache Argv.size() because it can change. for (unsigned I = 0; I != Argv.size(); ) { @@ -655,7 +679,10 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, // the cwd of the process or the response file? SmallVector<const char *, 0> ExpandedArgv; if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv)) { + // We couldn't read this file, so we leave it in the argument stream and + // move on. AllExpanded = false; + ++I; continue; } Argv.erase(Argv.begin() + I); @@ -675,7 +702,7 @@ namespace { free(Dup); } } - const char *SaveString(const char *Str) LLVM_OVERRIDE { + const char *SaveString(const char *Str) override { char *Dup = strdup(Str); Dups.push_back(Dup); return Dup; @@ -733,7 +760,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, argc = static_cast<int>(newArgv.size()); // Copy the program name into ProgName, making sure not to overflow it. - std::string ProgName = sys::path::filename(argv[0]); + StringRef ProgName = sys::path::filename(argv[0]); size_t Len = std::min(ProgName.size(), size_t(79)); memcpy(ProgramName, ProgName.data(), Len); ProgramName[Len] = '\0'; @@ -747,7 +774,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, // Determine whether or not there are an unlimited number of positionals bool HasUnlimitedPositionals = false; - Option *ConsumeAfterOpt = 0; + Option *ConsumeAfterOpt = nullptr; if (!PositionalOpts.empty()) { if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { assert(PositionalOpts.size() > 1 && @@ -757,7 +784,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, // Calculate how many positional values are _required_. bool UnboundedFound = false; - for (size_t i = ConsumeAfterOpt != 0, e = PositionalOpts.size(); + for (size_t i = ConsumeAfterOpt ? 1 : 0, e = PositionalOpts.size(); i != e; ++i) { Option *Opt = PositionalOpts[i]; if (RequiresValue(Opt)) @@ -793,13 +820,13 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, // If the program has named positional arguments, and the name has been run // across, keep track of which positional argument was named. Otherwise put // the positional args into the PositionalVals list... - Option *ActivePositionalArg = 0; + Option *ActivePositionalArg = nullptr; // Loop over all of the arguments... processing them. bool DashDashFound = false; // Have we read '--'? for (int i = 1; i < argc; ++i) { - Option *Handler = 0; - Option *NearestHandler = 0; + Option *Handler = nullptr; + Option *NearestHandler = nullptr; std::string NearestHandlerString; StringRef Value; StringRef ArgName = ""; @@ -832,8 +859,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, // All of the positional arguments have been fulfulled, give the rest to // the consume after option... if it's specified... // - if (PositionalVals.size() >= NumPositionalRequired && - ConsumeAfterOpt != 0) { + if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) { for (++i; i < argc; ++i) PositionalVals.push_back(std::make_pair(argv[i],i)); break; // Handle outside of the argument processing loop... @@ -871,18 +897,18 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, Handler = LookupOption(ArgName, Value, Opts); // Check to see if this "option" is really a prefixed or grouped argument. - if (Handler == 0) + if (!Handler) Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing, Opts); // Otherwise, look for the closest available option to report to the user // in the upcoming error. - if (Handler == 0 && SinkOpts.empty()) + if (!Handler && SinkOpts.empty()) NearestHandler = LookupNearestOption(ArgName, Opts, NearestHandlerString); } - if (Handler == 0) { + if (!Handler) { if (SinkOpts.empty()) { errs() << ProgramName << ": Unknown command line argument '" << argv[i] << "'. Try: '" << argv[0] << " -help'\n"; @@ -926,7 +952,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, << " positional arguments: See: " << argv[0] << " -help\n"; ErrorParsing = true; - } else if (ConsumeAfterOpt == 0) { + } else if (!ConsumeAfterOpt) { // Positional args have already been handled if ConsumeAfter is specified. unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size()); for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) { @@ -992,13 +1018,12 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, } // Loop over args and make sure all required args are specified! - for (StringMap<Option*>::iterator I = Opts.begin(), - E = Opts.end(); I != E; ++I) { - switch (I->second->getNumOccurrencesFlag()) { + for (const auto &Opt : Opts) { + switch (Opt.second->getNumOccurrencesFlag()) { case Required: case OneOrMore: - if (I->second->getNumOccurrences() == 0) { - I->second->error("must be specified at least once!"); + if (Opt.second->getNumOccurrences() == 0) { + Opt.second->error("must be specified at least once!"); ErrorParsing = true; } // Fall through @@ -1031,7 +1056,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv, // bool Option::error(const Twine &Message, StringRef ArgName) { - if (ArgName.data() == 0) ArgName = ArgStr; + if (!ArgName.data()) ArgName = ArgStr; if (ArgName.empty()) errs() << HelpStr; // Be nice for positional arguments else @@ -1442,12 +1467,12 @@ public: outs() << "USAGE: " << ProgramName << " [options]"; // Print out the positional options. - Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists... + Option *CAOpt = nullptr; // The cl::ConsumeAfter option, if it exists... if (!PositionalOpts.empty() && PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter) CAOpt = PositionalOpts[0]; - for (size_t i = CAOpt != 0, e = PositionalOpts.size(); i != e; ++i) { + for (size_t i = CAOpt != nullptr, e = PositionalOpts.size(); i != e; ++i) { if (PositionalOpts[i]->ArgStr[0]) outs() << " --" << PositionalOpts[i]->ArgStr; outs() << " " << PositionalOpts[i]->HelpStr; @@ -1474,7 +1499,7 @@ public: MoreHelp->clear(); // Halt the program since help information was printed - exit(1); + exit(0); } }; @@ -1486,25 +1511,24 @@ public: // It shall return true if A's name should be lexographically // ordered before B's name. It returns false otherwise. static bool OptionCategoryCompare(OptionCategory *A, OptionCategory *B) { - int Length = strcmp(A->getName(), B->getName()); - assert(Length != 0 && "Duplicate option categories"); - return Length < 0; + return strcmp(A->getName(), B->getName()) < 0; } // Make sure we inherit our base class's operator=() using HelpPrinter::operator= ; protected: - virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) { + void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override { std::vector<OptionCategory *> SortedCategories; std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions; - // Collect registered option categories into vector in preperation for + // Collect registered option categories into vector in preparation for // sorting. for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(), E = RegisteredOptionCategories->end(); - I != E; ++I) + I != E; ++I) { SortedCategories.push_back(*I); + } // Sort the different option categories alphabetically. assert(SortedCategories.size() > 0 && "No option categories registered!"); @@ -1543,7 +1567,7 @@ protected: outs() << (*Category)->getName() << ":\n"; // Check if description is set. - if ((*Category)->getDescription() != 0) + if ((*Category)->getDescription() != nullptr) outs() << (*Category)->getDescription() << "\n\n"; else outs() << "\n"; @@ -1674,9 +1698,9 @@ void cl::PrintOptionValues() { Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions); } -static void (*OverrideVersionPrinter)() = 0; +static void (*OverrideVersionPrinter)() = nullptr; -static std::vector<void (*)()>* ExtraVersionPrinters = 0; +static std::vector<void (*)()>* ExtraVersionPrinters = nullptr; namespace { class VersionPrinter { @@ -1686,7 +1710,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__ @@ -1709,15 +1733,15 @@ public: void operator=(bool OptionWasSpecified) { if (!OptionWasSpecified) return; - if (OverrideVersionPrinter != 0) { + if (OverrideVersionPrinter != nullptr) { (*OverrideVersionPrinter)(); - exit(1); + exit(0); } print(); // Iterate over any registered extra printers and call them to add further // information. - if (ExtraVersionPrinters != 0) { + if (ExtraVersionPrinters != nullptr) { outs() << '\n'; for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(), E = ExtraVersionPrinters->end(); @@ -1725,7 +1749,7 @@ public: (*I)(); } - exit(1); + exit(0); } }; } // End anonymous namespace @@ -1767,7 +1791,7 @@ void cl::SetVersionPrinter(void (*func)()) { } void cl::AddExtraVersionPrinter(void (*func)()) { - if (ExtraVersionPrinters == 0) + if (!ExtraVersionPrinters) ExtraVersionPrinters = new std::vector<void (*)()>; ExtraVersionPrinters->push_back(func); diff --git a/contrib/llvm/lib/Support/Compression.cpp b/contrib/llvm/lib/Support/Compression.cpp index b5ddb70..c32eb21 100644 --- a/contrib/llvm/lib/Support/Compression.cpp +++ b/contrib/llvm/lib/Support/Compression.cpp @@ -12,12 +12,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Compression.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" #if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H #include <zlib.h> #endif @@ -48,36 +46,26 @@ static zlib::Status encodeZlibReturnValue(int ReturnValue) { bool zlib::isAvailable() { return true; } zlib::Status zlib::compress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &CompressedBuffer, + SmallVectorImpl<char> &CompressedBuffer, CompressionLevel Level) { unsigned long CompressedSize = ::compressBound(InputBuffer.size()); - OwningArrayPtr<char> TmpBuffer(new char[CompressedSize]); + CompressedBuffer.resize(CompressedSize); int CLevel = encodeZlibCompressionLevel(Level); Status Res = encodeZlibReturnValue(::compress2( - (Bytef *)TmpBuffer.get(), &CompressedSize, + (Bytef *)CompressedBuffer.data(), &CompressedSize, (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel)); - if (Res == StatusOK) { - CompressedBuffer.reset(MemoryBuffer::getMemBufferCopy( - StringRef(TmpBuffer.get(), CompressedSize))); - // Tell MSan that memory initialized by zlib is valid. - __msan_unpoison(CompressedBuffer->getBufferStart(), CompressedSize); - } + CompressedBuffer.resize(CompressedSize); return Res; } zlib::Status zlib::uncompress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &UncompressedBuffer, + SmallVectorImpl<char> &UncompressedBuffer, size_t UncompressedSize) { - OwningArrayPtr<char> TmpBuffer(new char[UncompressedSize]); - Status Res = encodeZlibReturnValue( - ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize, - (const Bytef *)InputBuffer.data(), InputBuffer.size())); - if (Res == StatusOK) { - UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy( - StringRef(TmpBuffer.get(), UncompressedSize))); - // Tell MSan that memory initialized by zlib is valid. - __msan_unpoison(UncompressedBuffer->getBufferStart(), UncompressedSize); - } + UncompressedBuffer.resize(UncompressedSize); + Status Res = encodeZlibReturnValue(::uncompress( + (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize, + (const Bytef *)InputBuffer.data(), InputBuffer.size())); + UncompressedBuffer.resize(UncompressedSize); return Res; } @@ -88,12 +76,12 @@ uint32_t zlib::crc32(StringRef Buffer) { #else bool zlib::isAvailable() { return false; } zlib::Status zlib::compress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &CompressedBuffer, + SmallVectorImpl<char> &CompressedBuffer, CompressionLevel Level) { return zlib::StatusUnsupported; } zlib::Status zlib::uncompress(StringRef InputBuffer, - OwningPtr<MemoryBuffer> &UncompressedBuffer, + SmallVectorImpl<char> &UncompressedBuffer, size_t UncompressedSize) { return zlib::StatusUnsupported; } diff --git a/contrib/llvm/lib/Support/ConstantRange.cpp b/contrib/llvm/lib/Support/ConstantRange.cpp deleted file mode 100644 index 265b6e9..0000000 --- a/contrib/llvm/lib/Support/ConstantRange.cpp +++ /dev/null @@ -1,734 +0,0 @@ -//===-- ConstantRange.cpp - ConstantRange implementation ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Represent a range of possible values that may occur when the program is run -// for an integral value. This keeps track of a lower and upper bound for the -// constant, which MAY wrap around the end of the numeric range. To do this, it -// keeps track of a [lower, upper) bound, which specifies an interval just like -// STL iterators. When used with boolean values, the following are important -// ranges (other integral ranges use min/max values for special range values): -// -// [F, F) = {} = Empty set -// [T, F) = {T} -// [F, T) = {F} -// [T, T) = {F, T} = Full set -// -//===----------------------------------------------------------------------===// - -#include "llvm/IR/InstrTypes.h" -#include "llvm/Support/ConstantRange.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -/// Initialize a full (the default) or empty set for the specified type. -/// -ConstantRange::ConstantRange(uint32_t BitWidth, bool Full) { - if (Full) - Lower = Upper = APInt::getMaxValue(BitWidth); - else - Lower = Upper = APInt::getMinValue(BitWidth); -} - -/// Initialize a range to hold the single specified value. -/// -ConstantRange::ConstantRange(APIntMoveTy V) - : Lower(llvm_move(V)), Upper(Lower + 1) {} - -ConstantRange::ConstantRange(APIntMoveTy L, APIntMoveTy U) - : Lower(llvm_move(L)), Upper(llvm_move(U)) { - assert(Lower.getBitWidth() == Upper.getBitWidth() && - "ConstantRange with unequal bit widths"); - assert((Lower != Upper || (Lower.isMaxValue() || Lower.isMinValue())) && - "Lower == Upper, but they aren't min or max value!"); -} - -ConstantRange ConstantRange::makeICmpRegion(unsigned Pred, - const ConstantRange &CR) { - if (CR.isEmptySet()) - return CR; - - uint32_t W = CR.getBitWidth(); - switch (Pred) { - default: llvm_unreachable("Invalid ICmp predicate to makeICmpRegion()"); - case CmpInst::ICMP_EQ: - return CR; - case CmpInst::ICMP_NE: - if (CR.isSingleElement()) - return ConstantRange(CR.getUpper(), CR.getLower()); - return ConstantRange(W); - case CmpInst::ICMP_ULT: { - APInt UMax(CR.getUnsignedMax()); - if (UMax.isMinValue()) - return ConstantRange(W, /* empty */ false); - return ConstantRange(APInt::getMinValue(W), UMax); - } - case CmpInst::ICMP_SLT: { - APInt SMax(CR.getSignedMax()); - if (SMax.isMinSignedValue()) - return ConstantRange(W, /* empty */ false); - return ConstantRange(APInt::getSignedMinValue(W), SMax); - } - case CmpInst::ICMP_ULE: { - APInt UMax(CR.getUnsignedMax()); - if (UMax.isMaxValue()) - return ConstantRange(W); - return ConstantRange(APInt::getMinValue(W), UMax + 1); - } - case CmpInst::ICMP_SLE: { - APInt SMax(CR.getSignedMax()); - if (SMax.isMaxSignedValue()) - return ConstantRange(W); - return ConstantRange(APInt::getSignedMinValue(W), SMax + 1); - } - case CmpInst::ICMP_UGT: { - APInt UMin(CR.getUnsignedMin()); - if (UMin.isMaxValue()) - return ConstantRange(W, /* empty */ false); - return ConstantRange(UMin + 1, APInt::getNullValue(W)); - } - case CmpInst::ICMP_SGT: { - APInt SMin(CR.getSignedMin()); - if (SMin.isMaxSignedValue()) - return ConstantRange(W, /* empty */ false); - return ConstantRange(SMin + 1, APInt::getSignedMinValue(W)); - } - case CmpInst::ICMP_UGE: { - APInt UMin(CR.getUnsignedMin()); - if (UMin.isMinValue()) - return ConstantRange(W); - return ConstantRange(UMin, APInt::getNullValue(W)); - } - case CmpInst::ICMP_SGE: { - APInt SMin(CR.getSignedMin()); - if (SMin.isMinSignedValue()) - return ConstantRange(W); - return ConstantRange(SMin, APInt::getSignedMinValue(W)); - } - } -} - -/// isFullSet - Return true if this set contains all of the elements possible -/// for this data-type -bool ConstantRange::isFullSet() const { - return Lower == Upper && Lower.isMaxValue(); -} - -/// isEmptySet - Return true if this set contains no members. -/// -bool ConstantRange::isEmptySet() const { - return Lower == Upper && Lower.isMinValue(); -} - -/// isWrappedSet - Return true if this set wraps around the top of the range, -/// for example: [100, 8) -/// -bool ConstantRange::isWrappedSet() const { - return Lower.ugt(Upper); -} - -/// isSignWrappedSet - Return true if this set wraps around the INT_MIN of -/// its bitwidth, for example: i8 [120, 140). -/// -bool ConstantRange::isSignWrappedSet() const { - return contains(APInt::getSignedMaxValue(getBitWidth())) && - contains(APInt::getSignedMinValue(getBitWidth())); -} - -/// getSetSize - Return the number of elements in this set. -/// -APInt ConstantRange::getSetSize() const { - if (isFullSet()) { - APInt Size(getBitWidth()+1, 0); - Size.setBit(getBitWidth()); - return Size; - } - - // This is also correct for wrapped sets. - return (Upper - Lower).zext(getBitWidth()+1); -} - -/// getUnsignedMax - Return the largest unsigned value contained in the -/// ConstantRange. -/// -APInt ConstantRange::getUnsignedMax() const { - if (isFullSet() || isWrappedSet()) - return APInt::getMaxValue(getBitWidth()); - return getUpper() - 1; -} - -/// getUnsignedMin - Return the smallest unsigned value contained in the -/// ConstantRange. -/// -APInt ConstantRange::getUnsignedMin() const { - if (isFullSet() || (isWrappedSet() && getUpper() != 0)) - return APInt::getMinValue(getBitWidth()); - return getLower(); -} - -/// getSignedMax - Return the largest signed value contained in the -/// ConstantRange. -/// -APInt ConstantRange::getSignedMax() const { - APInt SignedMax(APInt::getSignedMaxValue(getBitWidth())); - if (!isWrappedSet()) { - if (getLower().sle(getUpper() - 1)) - return getUpper() - 1; - return SignedMax; - } - if (getLower().isNegative() == getUpper().isNegative()) - return SignedMax; - return getUpper() - 1; -} - -/// getSignedMin - Return the smallest signed value contained in the -/// ConstantRange. -/// -APInt ConstantRange::getSignedMin() const { - APInt SignedMin(APInt::getSignedMinValue(getBitWidth())); - if (!isWrappedSet()) { - if (getLower().sle(getUpper() - 1)) - return getLower(); - return SignedMin; - } - if ((getUpper() - 1).slt(getLower())) { - if (getUpper() != SignedMin) - return SignedMin; - } - return getLower(); -} - -/// contains - Return true if the specified value is in the set. -/// -bool ConstantRange::contains(const APInt &V) const { - if (Lower == Upper) - return isFullSet(); - - if (!isWrappedSet()) - return Lower.ule(V) && V.ult(Upper); - return Lower.ule(V) || V.ult(Upper); -} - -/// contains - Return true if the argument is a subset of this range. -/// Two equal sets contain each other. The empty set contained by all other -/// sets. -/// -bool ConstantRange::contains(const ConstantRange &Other) const { - if (isFullSet() || Other.isEmptySet()) return true; - if (isEmptySet() || Other.isFullSet()) return false; - - if (!isWrappedSet()) { - if (Other.isWrappedSet()) - return false; - - return Lower.ule(Other.getLower()) && Other.getUpper().ule(Upper); - } - - if (!Other.isWrappedSet()) - return Other.getUpper().ule(Upper) || - Lower.ule(Other.getLower()); - - return Other.getUpper().ule(Upper) && Lower.ule(Other.getLower()); -} - -/// subtract - Subtract the specified constant from the endpoints of this -/// constant range. -ConstantRange ConstantRange::subtract(const APInt &Val) const { - assert(Val.getBitWidth() == getBitWidth() && "Wrong bit width"); - // If the set is empty or full, don't modify the endpoints. - if (Lower == Upper) - return *this; - return ConstantRange(Lower - Val, Upper - Val); -} - -/// \brief Subtract the specified range from this range (aka relative complement -/// of the sets). -ConstantRange ConstantRange::difference(const ConstantRange &CR) const { - return intersectWith(CR.inverse()); -} - -/// intersectWith - Return the range that results from the intersection of this -/// range with another range. The resultant range is guaranteed to include all -/// elements contained in both input ranges, and to have the smallest possible -/// set size that does so. Because there may be two intersections with the -/// same set size, A.intersectWith(B) might not be equal to B.intersectWith(A). -ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const { - assert(getBitWidth() == CR.getBitWidth() && - "ConstantRange types don't agree!"); - - // Handle common cases. - if ( isEmptySet() || CR.isFullSet()) return *this; - if (CR.isEmptySet() || isFullSet()) return CR; - - if (!isWrappedSet() && CR.isWrappedSet()) - return CR.intersectWith(*this); - - if (!isWrappedSet() && !CR.isWrappedSet()) { - if (Lower.ult(CR.Lower)) { - if (Upper.ule(CR.Lower)) - return ConstantRange(getBitWidth(), false); - - if (Upper.ult(CR.Upper)) - return ConstantRange(CR.Lower, Upper); - - return CR; - } - if (Upper.ult(CR.Upper)) - return *this; - - if (Lower.ult(CR.Upper)) - return ConstantRange(Lower, CR.Upper); - - return ConstantRange(getBitWidth(), false); - } - - if (isWrappedSet() && !CR.isWrappedSet()) { - if (CR.Lower.ult(Upper)) { - if (CR.Upper.ult(Upper)) - return CR; - - if (CR.Upper.ule(Lower)) - return ConstantRange(CR.Lower, Upper); - - if (getSetSize().ult(CR.getSetSize())) - return *this; - return CR; - } - if (CR.Lower.ult(Lower)) { - if (CR.Upper.ule(Lower)) - return ConstantRange(getBitWidth(), false); - - return ConstantRange(Lower, CR.Upper); - } - return CR; - } - - if (CR.Upper.ult(Upper)) { - if (CR.Lower.ult(Upper)) { - if (getSetSize().ult(CR.getSetSize())) - return *this; - return CR; - } - - if (CR.Lower.ult(Lower)) - return ConstantRange(Lower, CR.Upper); - - return CR; - } - if (CR.Upper.ule(Lower)) { - if (CR.Lower.ult(Lower)) - return *this; - - return ConstantRange(CR.Lower, Upper); - } - if (getSetSize().ult(CR.getSetSize())) - return *this; - return CR; -} - - -/// unionWith - Return the range that results from the union of this range with -/// another range. The resultant range is guaranteed to include the elements of -/// both sets, but may contain more. For example, [3, 9) union [12,15) is -/// [3, 15), which includes 9, 10, and 11, which were not included in either -/// set before. -/// -ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { - assert(getBitWidth() == CR.getBitWidth() && - "ConstantRange types don't agree!"); - - if ( isFullSet() || CR.isEmptySet()) return *this; - if (CR.isFullSet() || isEmptySet()) return CR; - - if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this); - - if (!isWrappedSet() && !CR.isWrappedSet()) { - if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) { - // If the two ranges are disjoint, find the smaller gap and bridge it. - APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; - if (d1.ult(d2)) - return ConstantRange(Lower, CR.Upper); - return ConstantRange(CR.Lower, Upper); - } - - APInt L = Lower, U = Upper; - if (CR.Lower.ult(L)) - L = CR.Lower; - if ((CR.Upper - 1).ugt(U - 1)) - U = CR.Upper; - - if (L == 0 && U == 0) - return ConstantRange(getBitWidth()); - - return ConstantRange(L, U); - } - - if (!CR.isWrappedSet()) { - // ------U L----- and ------U L----- : this - // L--U L--U : CR - if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower)) - return *this; - - // ------U L----- : this - // L---------U : CR - if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) - return ConstantRange(getBitWidth()); - - // ----U L---- : this - // L---U : CR - // <d1> <d2> - if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) { - APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; - if (d1.ult(d2)) - return ConstantRange(Lower, CR.Upper); - return ConstantRange(CR.Lower, Upper); - } - - // ----U L----- : this - // L----U : CR - if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) - return ConstantRange(CR.Lower, Upper); - - // ------U L---- : this - // L-----U : CR - assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) && - "ConstantRange::unionWith missed a case with one range wrapped"); - return ConstantRange(Lower, CR.Upper); - } - - // ------U L---- and ------U L---- : this - // -U L----------- and ------------U L : CR - if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper)) - return ConstantRange(getBitWidth()); - - APInt L = Lower, U = Upper; - if (CR.Upper.ugt(U)) - U = CR.Upper; - if (CR.Lower.ult(L)) - L = CR.Lower; - - return ConstantRange(L, U); -} - -/// zeroExtend - Return a new range in the specified integer type, which must -/// be strictly larger than the current type. The returned range will -/// correspond to the possible range of values as if the source range had been -/// zero extended. -ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const { - if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false); - - unsigned SrcTySize = getBitWidth(); - assert(SrcTySize < DstTySize && "Not a value extension"); - if (isFullSet() || isWrappedSet()) { - // Change into [0, 1 << src bit width) - APInt LowerExt(DstTySize, 0); - if (!Upper) // special case: [X, 0) -- not really wrapping around - LowerExt = Lower.zext(DstTySize); - return ConstantRange(LowerExt, APInt::getOneBitSet(DstTySize, SrcTySize)); - } - - return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize)); -} - -/// signExtend - Return a new range in the specified integer type, which must -/// be strictly larger than the current type. The returned range will -/// correspond to the possible range of values as if the source range had been -/// sign extended. -ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const { - if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false); - - unsigned SrcTySize = getBitWidth(); - assert(SrcTySize < DstTySize && "Not a value extension"); - - // special case: [X, INT_MIN) -- not really wrapping around - if (Upper.isMinSignedValue()) - return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize)); - - if (isFullSet() || isSignWrappedSet()) { - return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1), - APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1); - } - - return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize)); -} - -/// truncate - Return a new range in the specified integer type, which must be -/// strictly smaller than the current type. The returned range will -/// correspond to the possible range of values as if the source range had been -/// truncated to the specified type. -ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { - assert(getBitWidth() > DstTySize && "Not a value truncation"); - if (isEmptySet()) - return ConstantRange(DstTySize, /*isFullSet=*/false); - if (isFullSet()) - return ConstantRange(DstTySize, /*isFullSet=*/true); - - APInt MaxValue = APInt::getMaxValue(DstTySize).zext(getBitWidth()); - APInt MaxBitValue(getBitWidth(), 0); - MaxBitValue.setBit(DstTySize); - - APInt LowerDiv(Lower), UpperDiv(Upper); - ConstantRange Union(DstTySize, /*isFullSet=*/false); - - // Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue] - // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and - // then we do the union with [MaxValue, Upper) - if (isWrappedSet()) { - // if Upper is greater than Max Value, it covers the whole truncated range. - if (Upper.uge(MaxValue)) - return ConstantRange(DstTySize, /*isFullSet=*/true); - - Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize)); - UpperDiv = APInt::getMaxValue(getBitWidth()); - - // Union covers the MaxValue case, so return if the remaining range is just - // MaxValue. - if (LowerDiv == UpperDiv) - return Union; - } - - // Chop off the most significant bits that are past the destination bitwidth. - if (LowerDiv.uge(MaxValue)) { - APInt Div(getBitWidth(), 0); - APInt::udivrem(LowerDiv, MaxBitValue, Div, LowerDiv); - UpperDiv = UpperDiv - MaxBitValue * Div; - } - - if (UpperDiv.ule(MaxValue)) - return ConstantRange(LowerDiv.trunc(DstTySize), - UpperDiv.trunc(DstTySize)).unionWith(Union); - - // The truncated value wrapps around. Check if we can do better than fullset. - APInt UpperModulo = UpperDiv - MaxBitValue; - if (UpperModulo.ult(LowerDiv)) - return ConstantRange(LowerDiv.trunc(DstTySize), - UpperModulo.trunc(DstTySize)).unionWith(Union); - - return ConstantRange(DstTySize, /*isFullSet=*/true); -} - -/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The -/// value is zero extended, truncated, or left alone to make it that width. -ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const { - unsigned SrcTySize = getBitWidth(); - if (SrcTySize > DstTySize) - return truncate(DstTySize); - if (SrcTySize < DstTySize) - return zeroExtend(DstTySize); - return *this; -} - -/// sextOrTrunc - make this range have the bit width given by \p DstTySize. The -/// value is sign extended, truncated, or left alone to make it that width. -ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const { - unsigned SrcTySize = getBitWidth(); - if (SrcTySize > DstTySize) - return truncate(DstTySize); - if (SrcTySize < DstTySize) - return signExtend(DstTySize); - return *this; -} - -ConstantRange -ConstantRange::add(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - if (isFullSet() || Other.isFullSet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); - APInt NewLower = getLower() + Other.getLower(); - APInt NewUpper = getUpper() + Other.getUpper() - 1; - if (NewLower == NewUpper) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - ConstantRange X = ConstantRange(NewLower, NewUpper); - if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) - // We've wrapped, therefore, full set. - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - return X; -} - -ConstantRange -ConstantRange::sub(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - if (isFullSet() || Other.isFullSet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize(); - APInt NewLower = getLower() - Other.getUpper() + 1; - APInt NewUpper = getUpper() - Other.getLower(); - if (NewLower == NewUpper) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - ConstantRange X = ConstantRange(NewLower, NewUpper); - if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y)) - // We've wrapped, therefore, full set. - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - return X; -} - -ConstantRange -ConstantRange::multiply(const ConstantRange &Other) const { - // TODO: If either operand is a single element and the multiply is known to - // be non-wrapping, round the result min and max value to the appropriate - // multiple of that element. If wrapping is possible, at least adjust the - // range according to the greatest power-of-two factor of the single element. - - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - - APInt this_min = getUnsignedMin().zext(getBitWidth() * 2); - APInt this_max = getUnsignedMax().zext(getBitWidth() * 2); - APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2); - APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2); - - ConstantRange Result_zext = ConstantRange(this_min * Other_min, - this_max * Other_max + 1); - return Result_zext.truncate(getBitWidth()); -} - -ConstantRange -ConstantRange::smax(const ConstantRange &Other) const { - // X smax Y is: range(smax(X_smin, Y_smin), - // smax(X_smax, Y_smax)) - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin()); - APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1; - if (NewU == NewL) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return ConstantRange(NewL, NewU); -} - -ConstantRange -ConstantRange::umax(const ConstantRange &Other) const { - // X umax Y is: range(umax(X_umin, Y_umin), - // umax(X_umax, Y_umax)) - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); - APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1; - if (NewU == NewL) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return ConstantRange(NewL, NewU); -} - -ConstantRange -ConstantRange::udiv(const ConstantRange &RHS) const { - if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - if (RHS.isFullSet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax()); - - APInt RHS_umin = RHS.getUnsignedMin(); - if (RHS_umin == 0) { - // We want the lowest value in RHS excluding zero. Usually that would be 1 - // except for a range in the form of [X, 1) in which case it would be X. - if (RHS.getUpper() == 1) - RHS_umin = RHS.getLower(); - else - RHS_umin = APInt(getBitWidth(), 1); - } - - APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1; - - // If the LHS is Full and the RHS is a wrapped interval containing 1 then - // this could occur. - if (Lower == Upper) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - return ConstantRange(Lower, Upper); -} - -ConstantRange -ConstantRange::binaryAnd(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - - // TODO: replace this with something less conservative - - APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax()); - if (umin.isAllOnesValue()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1); -} - -ConstantRange -ConstantRange::binaryOr(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - - // TODO: replace this with something less conservative - - APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin()); - if (umax.isMinValue()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return ConstantRange(umax, APInt::getNullValue(getBitWidth())); -} - -ConstantRange -ConstantRange::shl(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - - APInt min = getUnsignedMin().shl(Other.getUnsignedMin()); - APInt max = getUnsignedMax().shl(Other.getUnsignedMax()); - - // there's no overflow! - APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros()); - if (Zeros.ugt(Other.getUnsignedMax())) - return ConstantRange(min, max + 1); - - // FIXME: implement the other tricky cases - return ConstantRange(getBitWidth(), /*isFullSet=*/true); -} - -ConstantRange -ConstantRange::lshr(const ConstantRange &Other) const { - if (isEmptySet() || Other.isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - - APInt max = getUnsignedMax().lshr(Other.getUnsignedMin()); - APInt min = getUnsignedMin().lshr(Other.getUnsignedMax()); - if (min == max + 1) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - - return ConstantRange(min, max + 1); -} - -ConstantRange ConstantRange::inverse() const { - if (isFullSet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/false); - if (isEmptySet()) - return ConstantRange(getBitWidth(), /*isFullSet=*/true); - return ConstantRange(Upper, Lower); -} - -/// print - Print out the bounds to a stream... -/// -void ConstantRange::print(raw_ostream &OS) const { - if (isFullSet()) - OS << "full-set"; - else if (isEmptySet()) - OS << "empty-set"; - else - OS << "[" << Lower << "," << Upper << ")"; -} - -/// dump - Allow printing from a debugger easily... -/// -void ConstantRange::dump() const { - print(dbgs()); -} diff --git a/contrib/llvm/lib/Support/ConvertUTF.c b/contrib/llvm/lib/Support/ConvertUTF.c index 23f17ca..128459a 100644 --- a/contrib/llvm/lib/Support/ConvertUTF.c +++ b/contrib/llvm/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/contrib/llvm/lib/Support/CrashRecoveryContext.cpp b/contrib/llvm/lib/Support/CrashRecoveryContext.cpp index 92c370d..9b0e443 100644 --- a/contrib/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/contrib/llvm/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; @@ -89,16 +90,16 @@ CrashRecoveryContext::~CrashRecoveryContext() { } bool CrashRecoveryContext::isRecoveringFromCrash() { - return tlIsRecoveringFromCrash->get() != 0; + return tlIsRecoveringFromCrash->get() != nullptr; } CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { if (!gCrashRecoveryEnabled) - return 0; + return nullptr; const CrashRecoveryContextImpl *CRCI = CurrentContext->get(); if (!CRCI) - return 0; + return nullptr; return CRCI->CRC; } @@ -120,7 +121,7 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { if (cleanup == head) { head = cleanup->next; if (head) - head->prev = 0; + head->prev = nullptr; } else { cleanup->prev->next = cleanup->next; @@ -132,7 +133,7 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { #ifdef LLVM_ON_WIN32 -#include "Windows/Windows.h" +#include "Windows/WindowsSupport.h" // On Windows, we can make use of vectored exception handling to // catch most crashing situations. Note that this does mean @@ -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]; @@ -261,7 +263,7 @@ static void CrashRecoverySignalHandler(int Signal) { sigset_t SigMask; sigemptyset(&SigMask); sigaddset(&SigMask, Signal); - sigprocmask(SIG_UNBLOCK, &SigMask, 0); + sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); if (CRCI) const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash(); @@ -296,12 +298,12 @@ void CrashRecoveryContext::Disable() { // Restore the previous signal handlers. for (unsigned i = 0; i != NumSignals; ++i) - sigaction(Signals[i], &PrevActions[i], 0); + sigaction(Signals[i], &PrevActions[i], nullptr); } #endif -bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) { +bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) { // If crash recovery is disabled, do nothing. if (gCrashRecoveryEnabled) { assert(!Impl && "Crash recovery context already initialized!"); @@ -313,7 +315,7 @@ bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) { } } - Fn(UserData); + Fn(); return true; } @@ -330,13 +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 { - void (*UserFn)(void*); - void *UserData; + function_ref<void()> Fn; CrashRecoveryContext *CRC; + bool UseBackgroundPriority; bool Result; }; } @@ -344,11 +359,16 @@ struct RunSafelyOnThreadInfo { static void RunSafelyOnThread_Dispatch(void *UserData) { RunSafelyOnThreadInfo *Info = reinterpret_cast<RunSafelyOnThreadInfo*>(UserData); - Info->Result = Info->CRC->RunSafely(Info->UserFn, Info->UserData); + + if (Info->UseBackgroundPriority) + setThreadBackgroundPriority(); + + Info->Result = Info->CRC->RunSafely(Info->Fn); } -bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData, +bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn, unsigned RequestedStackSize) { - RunSafelyOnThreadInfo Info = { Fn, UserData, 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/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp b/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp index 34e82cf..0d504ee 100644 --- a/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp +++ b/contrib/llvm/lib/Support/DAGDeltaAlgorithm.cpp @@ -42,6 +42,8 @@ #include <map> using namespace llvm; +#define DEBUG_TYPE "dag-delta" + namespace { class DAGDeltaAlgorithmImpl { @@ -162,12 +164,12 @@ class DeltaActiveSetHelper : public DeltaAlgorithm { protected: /// UpdatedSearchState - Callback used when the search state changes. - virtual void UpdatedSearchState(const changeset_ty &Changes, - const changesetlist_ty &Sets) LLVM_OVERRIDE { + void UpdatedSearchState(const changeset_ty &Changes, + const changesetlist_ty &Sets) override { DDAI.UpdatedSearchState(Changes, Sets, Required); } - virtual bool ExecuteOneTest(const changeset_ty &S) LLVM_OVERRIDE { + bool ExecuteOneTest(const changeset_ty &S) override { return DDAI.GetTestResult(S, Required); } diff --git a/contrib/llvm/lib/Support/DataExtractor.cpp b/contrib/llvm/lib/Support/DataExtractor.cpp index a564d21..5d6d60a 100644 --- a/contrib/llvm/lib/Support/DataExtractor.cpp +++ b/contrib/llvm/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); @@ -44,7 +44,7 @@ static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count, // success return dst; } - return NULL; + return nullptr; } uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const { @@ -125,7 +125,7 @@ const char *DataExtractor::getCStr(uint32_t *offset_ptr) const { *offset_ptr = pos + 1; return Data.data() + offset; } - return NULL; + return nullptr; } uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const { diff --git a/contrib/llvm/lib/Support/DataStream.cpp b/contrib/llvm/lib/Support/DataStream.cpp index 0bd0c68..32653de 100644 --- a/contrib/llvm/lib/Support/DataStream.cpp +++ b/contrib/llvm/lib/Support/DataStream.cpp @@ -14,15 +14,14 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "Data-stream" #include "llvm/Support/DataStream.h" #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 @@ -30,6 +29,8 @@ #endif using namespace llvm; +#define DEBUG_TYPE "Data-stream" + // Interface goals: // * StreamableMemoryObject doesn't care about complexities like using // threads/async callbacks to actually overlap download+compile @@ -58,16 +59,16 @@ public: virtual ~DataFileStreamer() { close(Fd); } - virtual size_t GetBytes(unsigned char *buf, size_t len) LLVM_OVERRIDE { + size_t GetBytes(unsigned char *buf, size_t len) override { NumStreamFetches++; 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); @@ -80,10 +81,10 @@ 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 NULL; + return nullptr; } return s; } diff --git a/contrib/llvm/lib/Support/Debug.cpp b/contrib/llvm/lib/Support/Debug.cpp index d9cb8a9..ad4d4ef 100644 --- a/contrib/llvm/lib/Support/Debug.cpp +++ b/contrib/llvm/lib/Support/Debug.cpp @@ -109,7 +109,7 @@ raw_ostream &llvm::dbgs() { if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0) // TODO: Add a handler for SIGUSER1-type signals so the user can // force a debug dump. - sys::AddSignalHandler(&debug_user_sig_handler, 0); + sys::AddSignalHandler(&debug_user_sig_handler, nullptr); // Otherwise we've already set the debug stream buffer size to // zero, disabling buffering so it will output directly to errs(). } diff --git a/contrib/llvm/lib/Support/Disassembler.cpp b/contrib/llvm/lib/Support/Disassembler.cpp deleted file mode 100644 index 27df3a9..0000000 --- a/contrib/llvm/lib/Support/Disassembler.cpp +++ /dev/null @@ -1,74 +0,0 @@ -//===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the necessary glue to call external disassembler -// libraries. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/Disassembler.h" -#include "llvm/Config/config.h" -#include <cassert> -#include <iomanip> -#include <sstream> -#include <string> - -#if USE_UDIS86 -#include <udis86.h> -#endif - -using namespace llvm; - -bool llvm::sys::hasDisassembler() -{ -#if defined (__i386__) || defined (__amd64__) || defined (__x86_64__) - // We have option to enable udis86 library. -# if USE_UDIS86 - return true; -#else - return false; -#endif -#else - return false; -#endif -} - -std::string llvm::sys::disassembleBuffer(uint8_t* start, size_t length, - uint64_t pc) { -#if (defined (__i386__) || defined (__amd64__) || defined (__x86_64__)) \ - && USE_UDIS86 - std::stringstream res; - - unsigned bits; -# if defined(__i386__) - bits = 32; -# else - bits = 64; -# endif - - ud_t ud_obj; - - ud_init(&ud_obj); - ud_set_input_buffer(&ud_obj, start, length); - ud_set_mode(&ud_obj, bits); - ud_set_pc(&ud_obj, pc); - ud_set_syntax(&ud_obj, UD_SYN_ATT); - - res << std::setbase(16) - << std::setw(bits/4); - - while (ud_disassemble(&ud_obj)) { - res << ud_insn_off(&ud_obj) << ":\t" << ud_insn_asm(&ud_obj) << "\n"; - } - - return res.str(); -#else - return "No disassembler available. See configure help for options.\n"; -#endif -} diff --git a/contrib/llvm/lib/Support/Dwarf.cpp b/contrib/llvm/lib/Support/Dwarf.cpp index c000b63..c9efa61 100644 --- a/contrib/llvm/lib/Support/Dwarf.cpp +++ b/contrib/llvm/lib/Support/Dwarf.cpp @@ -84,6 +84,9 @@ const char *llvm::dwarf::TagString(unsigned Tag) { case DW_TAG_arg_variable: return "DW_TAG_arg_variable"; case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type"; case DW_TAG_template_alias: return "DW_TAG_template_alias"; + case DW_TAG_coarray_type: return "DW_TAG_coarray_type"; + case DW_TAG_generic_subrange: return "DW_TAG_generic_subrange"; + case DW_TAG_dynamic_type: return "DW_TAG_dynamic_type"; case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; case DW_TAG_type_unit: return "DW_TAG_type_unit"; case DW_TAG_format_label: return "DW_TAG_format_label"; @@ -97,7 +100,7 @@ const char *llvm::dwarf::TagString(unsigned Tag) { return "DW_TAG_GNU_formal_parameter_pack"; case DW_TAG_APPLE_property: return "DW_TAG_APPLE_property"; } - return 0; + return nullptr; } /// ChildrenString - Return the string for the specified children flag. @@ -107,7 +110,7 @@ const char *llvm::dwarf::ChildrenString(unsigned Children) { case DW_CHILDREN_no: return "DW_CHILDREN_no"; case DW_CHILDREN_yes: return "DW_CHILDREN_yes"; } - return 0; + return nullptr; } /// AttributeString - Return the string for the specified attribute. @@ -206,6 +209,16 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) { case DW_AT_const_expr: return "DW_AT_const_expr"; case DW_AT_enum_class: return "DW_AT_enum_class"; case DW_AT_linkage_name: return "DW_AT_linkage_name"; + case DW_AT_string_length_bit_size: return "DW_AT_string_length_bit_size"; + case DW_AT_string_length_byte_size: return "DW_AT_string_length_byte_size"; + case DW_AT_rank: return "DW_AT_rank"; + case DW_AT_str_offsets_base: return "DW_AT_str_offsets_base"; + case DW_AT_addr_base: return "DW_AT_addr_base"; + case DW_AT_ranges_base: return "DW_AT_ranges_base"; + case DW_AT_dwo_id: return "DW_AT_dwo_id"; + case DW_AT_dwo_name: return "DW_AT_dwo_name"; + case DW_AT_reference: return "DW_AT_reference"; + case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference"; case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; @@ -258,7 +271,7 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) { case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames"; case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes"; } - return 0; + return nullptr; } /// FormEncodingString - Return the string for the specified form encoding. @@ -295,7 +308,7 @@ const char *llvm::dwarf::FormEncodingString(unsigned Encoding) { case DW_FORM_GNU_addr_index: return "DW_FORM_GNU_addr_index"; case DW_FORM_GNU_str_index: return "DW_FORM_GNU_str_index"; } - return 0; + return nullptr; } /// OperationEncodingString - Return the string for the specified operation @@ -464,7 +477,7 @@ const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) { case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index"; case DW_OP_GNU_const_index: return "DW_OP_GNU_const_index"; } - return 0; + return nullptr; } /// AttributeEncodingString - Return the string for the specified attribute @@ -490,7 +503,7 @@ const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) { case DW_ATE_lo_user: return "DW_ATE_lo_user"; case DW_ATE_hi_user: return "DW_ATE_hi_user"; } - return 0; + return nullptr; } /// DecimalSignString - Return the string for the specified decimal sign @@ -503,7 +516,7 @@ const char *llvm::dwarf::DecimalSignString(unsigned Sign) { case DW_DS_leading_separate: return "DW_DS_leading_separate"; case DW_DS_trailing_separate: return "DW_DS_trailing_separate"; } - return 0; + return nullptr; } /// EndianityString - Return the string for the specified endianity. @@ -516,7 +529,7 @@ const char *llvm::dwarf::EndianityString(unsigned Endian) { case DW_END_lo_user: return "DW_END_lo_user"; case DW_END_hi_user: return "DW_END_hi_user"; } - return 0; + return nullptr; } /// AccessibilityString - Return the string for the specified accessibility. @@ -528,7 +541,7 @@ const char *llvm::dwarf::AccessibilityString(unsigned Access) { case DW_ACCESS_protected: return "DW_ACCESS_protected"; case DW_ACCESS_private: return "DW_ACCESS_private"; } - return 0; + return nullptr; } /// VisibilityString - Return the string for the specified visibility. @@ -539,7 +552,7 @@ const char *llvm::dwarf::VisibilityString(unsigned Visibility) { case DW_VIS_exported: return "DW_VIS_exported"; case DW_VIS_qualified: return "DW_VIS_qualified"; } - return 0; + return nullptr; } /// VirtualityString - Return the string for the specified virtuality. @@ -550,7 +563,7 @@ const char *llvm::dwarf::VirtualityString(unsigned Virtuality) { case DW_VIRTUALITY_virtual: return "DW_VIRTUALITY_virtual"; case DW_VIRTUALITY_pure_virtual: return "DW_VIRTUALITY_pure_virtual"; } - return 0; + return nullptr; } /// LanguageString - Return the string for the specified language. @@ -576,10 +589,18 @@ const char *llvm::dwarf::LanguageString(unsigned Language) { case DW_LANG_ObjC_plus_plus: return "DW_LANG_ObjC_plus_plus"; case DW_LANG_UPC: return "DW_LANG_UPC"; case DW_LANG_D: return "DW_LANG_D"; + case DW_LANG_Python: return "DW_LANG_Python"; + case DW_LANG_OpenCL: return "DW_LANG_OpenCL"; + case DW_LANG_Go: return "DW_LANG_Go"; + case DW_LANG_Modula3: return "DW_LANG_Modula3"; + case DW_LANG_Haskell: return "DW_LANG_Haskell"; + case DW_LANG_C_plus_plus_03: return "DW_LANG_C_plus_plus_03"; + case DW_LANG_C_plus_plus_11: return "DW_LANG_C_plus_plus_11"; + case DW_LANG_OCaml: return "DW_LANG_OCaml"; case DW_LANG_lo_user: return "DW_LANG_lo_user"; case DW_LANG_hi_user: return "DW_LANG_hi_user"; } - return 0; + return nullptr; } /// CaseString - Return the string for the specified identifier case. @@ -591,7 +612,7 @@ const char *llvm::dwarf::CaseString(unsigned Case) { case DW_ID_down_case: return "DW_ID_down_case"; case DW_ID_case_insensitive: return "DW_ID_case_insensitive"; } - return 0; + return nullptr; } /// ConventionString - Return the string for the specified calling convention. @@ -604,7 +625,7 @@ const char *llvm::dwarf::ConventionString(unsigned Convention) { case DW_CC_lo_user: return "DW_CC_lo_user"; case DW_CC_hi_user: return "DW_CC_hi_user"; } - return 0; + return nullptr; } /// InlineCodeString - Return the string for the specified inline code. @@ -616,7 +637,7 @@ const char *llvm::dwarf::InlineCodeString(unsigned Code) { case DW_INL_declared_not_inlined: return "DW_INL_declared_not_inlined"; case DW_INL_declared_inlined: return "DW_INL_declared_inlined"; } - return 0; + return nullptr; } /// ArrayOrderString - Return the string for the specified array order. @@ -626,7 +647,7 @@ const char *llvm::dwarf::ArrayOrderString(unsigned Order) { case DW_ORD_row_major: return "DW_ORD_row_major"; case DW_ORD_col_major: return "DW_ORD_col_major"; } - return 0; + return nullptr; } /// DiscriminantString - Return the string for the specified discriminant @@ -636,7 +657,7 @@ const char *llvm::dwarf::DiscriminantString(unsigned Discriminant) { case DW_DSC_label: return "DW_DSC_label"; case DW_DSC_range: return "DW_DSC_range"; } - return 0; + return nullptr; } /// LNStandardString - Return the string for the specified line number standard. @@ -656,7 +677,7 @@ const char *llvm::dwarf::LNStandardString(unsigned Standard) { case DW_LNS_set_epilogue_begin: return "DW_LNS_set_epilogue_begin"; case DW_LNS_set_isa: return "DW_LNS_set_isa"; } - return 0; + return nullptr; } /// LNExtendedString - Return the string for the specified line number extended @@ -671,7 +692,7 @@ const char *llvm::dwarf::LNExtendedString(unsigned Encoding) { case DW_LNE_lo_user: return "DW_LNE_lo_user"; case DW_LNE_hi_user: return "DW_LNE_hi_user"; } - return 0; + return nullptr; } /// MacinfoString - Return the string for the specified macinfo type encodings. @@ -685,7 +706,7 @@ const char *llvm::dwarf::MacinfoString(unsigned Encoding) { case DW_MACINFO_end_file: return "DW_MACINFO_end_file"; case DW_MACINFO_vendor_ext: return "DW_MACINFO_vendor_ext"; } - return 0; + return nullptr; } /// CallFrameString - Return the string for the specified call frame instruction @@ -724,7 +745,7 @@ const char *llvm::dwarf::CallFrameString(unsigned Encoding) { case DW_CFA_lo_user: return "DW_CFA_lo_user"; case DW_CFA_hi_user: return "DW_CFA_hi_user"; } - return 0; + return nullptr; } const char *llvm::dwarf::AtomTypeString(unsigned AT) { @@ -740,7 +761,7 @@ const char *llvm::dwarf::AtomTypeString(unsigned AT) { case DW_ATOM_type_flags: return "DW_ATOM_type_flags"; } - return 0; + return nullptr; } const char *llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) { diff --git a/contrib/llvm/lib/Support/DynamicLibrary.cpp b/contrib/llvm/lib/Support/DynamicLibrary.cpp index a825c68..d2b551e 100644 --- a/contrib/llvm/lib/Support/DynamicLibrary.cpp +++ b/contrib/llvm/lib/Support/DynamicLibrary.cpp @@ -7,19 +7,19 @@ // //===----------------------------------------------------------------------===// // -// This header file implements the operating system DynamicLibrary concept. +// This file implements the operating system DynamicLibrary concept. // // FIXME: This file leaks ExplicitSymbols and OpenedHandles! // //===----------------------------------------------------------------------===// #include "llvm/Support/DynamicLibrary.h" -#include "llvm/Support/ManagedStatic.h" +#include "llvm-c/Support.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/Config/config.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" -#include "llvm-c/Support.h" #include <cstdio> #include <cstring> @@ -51,14 +51,14 @@ using namespace llvm::sys; //=== independent code. //===----------------------------------------------------------------------===// -static DenseSet<void *> *OpenedHandles = 0; +static DenseSet<void *> *OpenedHandles = nullptr; DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, std::string *errMsg) { SmartScopedLock<true> lock(*SymbolsMutex); void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); - if (handle == 0) { + if (!handle) { if (errMsg) *errMsg = dlerror(); return DynamicLibrary(); } @@ -66,11 +66,11 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, #ifdef __CYGWIN__ // Cygwin searches symbols only in the main // with the handle of dlopen(NULL, RTLD_GLOBAL). - if (filename == NULL) + if (!filename) handle = RTLD_DEFAULT; #endif - if (OpenedHandles == 0) + if (!OpenedHandles) OpenedHandles = new DenseSet<void *>(); // If we've already loaded this library, dlclose() the handle in order to @@ -83,7 +83,7 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { if (!isValid()) - return NULL; + return nullptr; return dlsym(Data, symbolName); } @@ -166,7 +166,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) { #endif #undef EXPLICIT_SYMBOL - return 0; + return nullptr; } #endif // LLVM_ON_WIN32 diff --git a/contrib/llvm/lib/Support/ErrorHandling.cpp b/contrib/llvm/lib/Support/ErrorHandling.cpp index 1eafb96..c36007f 100644 --- a/contrib/llvm/lib/Support/ErrorHandling.cpp +++ b/contrib/llvm/lib/Support/ErrorHandling.cpp @@ -13,14 +13,18 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/ErrorHandling.h" +#include "llvm-c/Core.h" #include "llvm/ADT/SmallVector.h" #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 "llvm-c/Core.h" #include <cassert> #include <cstdlib> @@ -34,20 +38,23 @@ using namespace llvm; -static fatal_error_handler_t ErrorHandler = 0; -static void *ErrorHandlerUserData = 0; +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() { - ErrorHandler = 0; + 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/contrib/llvm/lib/Support/FileOutputBuffer.cpp b/contrib/llvm/lib/Support/FileOutputBuffer.cpp index ed084fa..94bcdc5 100644 --- a/contrib/llvm/lib/Support/FileOutputBuffer.cpp +++ b/contrib/llvm/lib/Support/FileOutputBuffer.cpp @@ -11,11 +11,11 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/FileOutputBuffer.h" -#include "llvm/ADT/OwningPtr.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; @@ -28,17 +28,16 @@ FileOutputBuffer::FileOutputBuffer(mapped_file_region * R, } FileOutputBuffer::~FileOutputBuffer() { - bool Existed; - sys::fs::remove(Twine(TempPath), Existed); + sys::fs::remove(Twine(TempPath)); } -error_code FileOutputBuffer::create(StringRef FilePath, - size_t Size, - OwningPtr<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. @@ -57,8 +56,7 @@ error_code FileOutputBuffer::create(StringRef FilePath, } // Delete target file. - bool Existed; - EC = sys::fs::remove(FilePath, Existed); + EC = sys::fs::remove(FilePath); if (EC) return EC; @@ -75,25 +73,25 @@ error_code FileOutputBuffer::create(StringRef FilePath, if (EC) return EC; - OwningPtr<mapped_file_region> MappedFile(new mapped_file_region( + std::unique_ptr<mapped_file_region> MappedFile(new mapped_file_region( FD, true, mapped_file_region::readwrite, Size, 0, EC)); if (EC) return EC; Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath)); if (Result) - MappedFile.take(); + 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(0); + Region.reset(); // 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/contrib/llvm/lib/Support/FileUtilities.cpp b/contrib/llvm/lib/Support/FileUtilities.cpp index 7f5d540..8a23491 100644 --- a/contrib/llvm/lib/Support/FileUtilities.cpp +++ b/contrib/llvm/lib/Support/FileUtilities.cpp @@ -13,15 +13,14 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FileUtilities.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #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) { @@ -177,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. - OwningPtr<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; } - OwningPtr<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/contrib/llvm/lib/Support/FoldingSet.cpp b/contrib/llvm/lib/Support/FoldingSet.cpp index 145f12d..4635114 100644 --- a/contrib/llvm/lib/Support/FoldingSet.cpp +++ b/contrib/llvm/lib/Support/FoldingSet.cpp @@ -190,7 +190,7 @@ FoldingSetNodeID::Intern(BumpPtrAllocator &Allocator) const { static FoldingSetImpl::Node *GetNextPtr(void *NextInBucketPtr) { // The low bit is set if this is the pointer back to the bucket. if (reinterpret_cast<intptr_t>(NextInBucketPtr) & 1) - return 0; + return nullptr; return static_cast<FoldingSetImpl::Node*>(NextInBucketPtr); } @@ -262,7 +262,7 @@ void FoldingSetImpl::GrowHashTable() { while (Node *NodeInBucket = GetNextPtr(Probe)) { // Figure out the next link, remove NodeInBucket from the old link. Probe = NodeInBucket->getNextInBucket(); - NodeInBucket->SetNextInBucket(0); + NodeInBucket->SetNextInBucket(nullptr); // Insert the node into the new bucket, after recomputing the hash. InsertNode(NodeInBucket, @@ -285,7 +285,7 @@ FoldingSetImpl::Node void **Bucket = GetBucketFor(IDHash, Buckets, NumBuckets); void *Probe = *Bucket; - InsertPos = 0; + InsertPos = nullptr; FoldingSetNodeID TempID; while (Node *NodeInBucket = GetNextPtr(Probe)) { @@ -298,14 +298,14 @@ FoldingSetImpl::Node // Didn't find the node, return null with the bucket as the InsertPos. InsertPos = Bucket; - return 0; + return nullptr; } /// InsertNode - Insert the specified node into the folding set, knowing that it /// is not already in the map. InsertPos must be obtained from /// FindNodeOrInsertPos. void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) { - assert(N->getNextInBucket() == 0); + assert(!N->getNextInBucket()); // Do we need to grow the hashtable? if (NumNodes+1 > NumBuckets*2) { GrowHashTable(); @@ -323,7 +323,7 @@ void FoldingSetImpl::InsertNode(Node *N, void *InsertPos) { // If this is the first insertion into this bucket, its next pointer will be // null. Pretend as if it pointed to itself, setting the low bit to indicate // that it is a pointer to the bucket. - if (Next == 0) + if (!Next) Next = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(Bucket)|1); // Set the node's next pointer, and make the bucket point to the node. @@ -337,10 +337,10 @@ bool FoldingSetImpl::RemoveNode(Node *N) { // Because each bucket is a circular list, we don't need to compute N's hash // to remove it. void *Ptr = N->getNextInBucket(); - if (Ptr == 0) return false; // Not in folding set. + if (!Ptr) return false; // Not in folding set. --NumNodes; - N->SetNextInBucket(0); + N->SetNextInBucket(nullptr); // Remember what N originally pointed to, either a bucket or another node. void *NodeNextPtr = Ptr; @@ -390,7 +390,7 @@ FoldingSetImpl::Node *FoldingSetImpl::GetOrInsertNode(FoldingSetImpl::Node *N) { FoldingSetIteratorImpl::FoldingSetIteratorImpl(void **Bucket) { // Skip to the first non-null non-self-cycle bucket. while (*Bucket != reinterpret_cast<void*>(-1) && - (*Bucket == 0 || GetNextPtr(*Bucket) == 0)) + (!*Bucket || !GetNextPtr(*Bucket))) ++Bucket; NodePtr = static_cast<FoldingSetNode*>(*Bucket); @@ -410,7 +410,7 @@ void FoldingSetIteratorImpl::advance() { do { ++Bucket; } while (*Bucket != reinterpret_cast<void*>(-1) && - (*Bucket == 0 || GetNextPtr(*Bucket) == 0)); + (!*Bucket || !GetNextPtr(*Bucket))); NodePtr = static_cast<FoldingSetNode*>(*Bucket); } @@ -420,5 +420,5 @@ void FoldingSetIteratorImpl::advance() { // FoldingSetBucketIteratorImpl Implementation FoldingSetBucketIteratorImpl::FoldingSetBucketIteratorImpl(void **Bucket) { - Ptr = (*Bucket == 0 || GetNextPtr(*Bucket) == 0) ? (void*) Bucket : *Bucket; + Ptr = (!*Bucket || !GetNextPtr(*Bucket)) ? (void*) Bucket : *Bucket; } diff --git a/contrib/llvm/lib/Support/FormattedStream.cpp b/contrib/llvm/lib/Support/FormattedStream.cpp index 9febf66..618ec26 100644 --- a/contrib/llvm/lib/Support/FormattedStream.cpp +++ b/contrib/llvm/lib/Support/FormattedStream.cpp @@ -81,7 +81,7 @@ void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) { TheStream->write(Ptr, Size); // Reset the scanning pointer. - Scanned = 0; + Scanned = nullptr; } /// fouts() - This returns a reference to a formatted_raw_ostream for diff --git a/contrib/llvm/lib/Support/GraphWriter.cpp b/contrib/llvm/lib/Support/GraphWriter.cpp index 85be415..e68ee43 100644 --- a/contrib/llvm/lib/Support/GraphWriter.cpp +++ b/contrib/llvm/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,149 +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],0,0,0,0,&ErrMsg)) { + if (sys::ExecuteAndWait(ExecPath, args.data(), nullptr, nullptr, 0, 0, + &ErrMsg)) { errs() << "Error: " << ErrMsg << "\n"; - return false; + return true; } - bool Existed; - sys::fs::remove(Filename, Existed); + sys::fs::remove(Filename); errs() << " done. \n"; - } - else { - sys::ExecuteNoWait(ExecPath, &args[0],0,0,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(0); - - 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/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp index 6e9a5c9..e2dd6d5 100644 --- a/contrib/llvm/lib/Support/Host.cpp +++ b/contrib/llvm/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. // //===----------------------------------------------------------------------===// @@ -39,6 +39,8 @@ #include <mach/machine.h> #endif +#define DEBUG_TYPE "host-detection" + //===----------------------------------------------------------------------===// // // Implementations of the CPU detection routines @@ -98,8 +100,9 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, /// GetX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the /// 4 values in the specified arguments. If we can't run cpuid on the host, /// return true. -bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, unsigned *rEAX, - unsigned *rEBX, unsigned *rECX, unsigned *rEDX) { +static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, + unsigned *rEAX, unsigned *rEBX, unsigned *rECX, + unsigned *rEDX) { #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64) #if defined(__GNUC__) // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually. @@ -192,7 +195,7 @@ static void DetectX86FamilyModel(unsigned EAX, unsigned &Family, } } -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0; if (GetX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX)) return "generic"; @@ -220,6 +223,7 @@ std::string sys::getHostCPUName() { (EBX & 0x20); GetX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); bool Em64T = (EDX >> 29) & 0x1; + bool HasTBM = (ECX >> 21) & 0x1; if (memcmp(text.c, "GenuineIntel", 12) == 0) { switch (Family) { @@ -432,9 +436,11 @@ std::string sys::getHostCPUName() { case 21: if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback. return "btver1"; + if (Model >= 0x50) + return "bdver4"; // 50h-6Fh: Excavator if (Model >= 0x30) return "bdver3"; // 30h-3Fh: Steamroller - if (Model >= 0x10) + if (Model >= 0x10 || HasTBM) return "bdver2"; // 10h-1Fh: Piledriver return "bdver1"; // 00h-0Fh: Bulldozer case 22: @@ -448,7 +454,7 @@ std::string sys::getHostCPUName() { return "generic"; } #elif defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { host_basic_info_data_t hostInfo; mach_msg_type_number_t infoCount; @@ -477,7 +483,7 @@ std::string sys::getHostCPUName() { return "generic"; } #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)) -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { // Access to the Processor Version Register (PVR) on PowerPC is privileged, // and so we must use an operating-system interface to determine the current // processor type. On Linux, this is exposed through the /proc/cpuinfo file. @@ -564,10 +570,12 @@ std::string sys::getHostCPUName() { .Case("A2", "a2") .Case("POWER6", "pwr6") .Case("POWER7", "pwr7") + .Case("POWER8", "pwr8") + .Case("POWER8E", "pwr8") .Default(generic); } #elif defined(__linux__) && defined(__arm__) -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { // The cpuid register on arm is not accessible from user space. On Linux, // it is exposed through the /proc/cpuinfo file. // Note: We cannot mmap /proc/cpuinfo here and then process the resulting @@ -619,10 +627,21 @@ std::string sys::getHostCPUName() { .Case("0xc24", "cortex-m4") .Default("generic"); + if (Implementer == "0x51") // Qualcomm Technologies, Inc. + // Look for the CPU part line. + for (unsigned I = 0, E = Lines.size(); I != E; ++I) + if (Lines[I].startswith("CPU part")) + // The CPU part is a 3 digit hexadecimal number with a 0x prefix. The + // values correspond to the "Part number" in the CP15/c0 register. The + // contents are specified in the various processor manuals. + return StringSwitch<const char *>(Lines[I].substr(8).ltrim("\t :")) + .Case("0x06f", "krait") // APQ8064 + .Default("generic"); + return "generic"; } #elif defined(__linux__) && defined(__s390x__) -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { // STIDP is a privileged operation, so use /proc/cpuinfo instead. // Note: We cannot mmap /proc/cpuinfo here and then process the resulting // memory buffer because the 'file' has 0 size (it can be read from only @@ -664,12 +683,12 @@ std::string sys::getHostCPUName() { return "generic"; } #else -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { return "generic"; } #endif -#if defined(__linux__) && defined(__arm__) +#if defined(__linux__) && (defined(__arm__) || defined(__aarch64__)) bool sys::getHostCPUFeatures(StringMap<bool> &Features) { std::string Err; DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err); @@ -698,8 +717,24 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { break; } +#if defined(__aarch64__) + // Keep track of which crypto features we have seen + enum { + CAP_AES = 0x1, + CAP_PMULL = 0x2, + CAP_SHA1 = 0x4, + CAP_SHA2 = 0x8 + }; + uint32_t crypto = 0; +#endif + for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) { StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I]) +#if defined(__aarch64__) + .Case("asimd", "neon") + .Case("fp", "fp-armv8") + .Case("crc32", "crc") +#else .Case("half", "fp16") .Case("neon", "neon") .Case("vfpv3", "vfp3") @@ -707,12 +742,32 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { .Case("vfpv4", "vfp4") .Case("idiva", "hwdiv-arm") .Case("idivt", "hwdiv") +#endif .Default(""); +#if defined(__aarch64__) + // 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; + else if (CPUFeatures[I] == "pmull") + crypto |= CAP_PMULL; + else if (CPUFeatures[I] == "sha1") + crypto |= CAP_SHA1; + else if (CPUFeatures[I] == "sha2") + crypto |= CAP_SHA2; +#endif + if (LLVMFeatureStr != "") Features.GetOrCreateValue(LLVMFeatureStr).setValue(true); } +#if defined(__aarch64__) + // If we have all crypto bits we can add the feature + if (crypto == (CAP_AES | CAP_PMULL | CAP_SHA1 | CAP_SHA2)) + Features.GetOrCreateValue("crypto").setValue(true); +#endif + return true; } #else diff --git a/contrib/llvm/lib/Support/IntervalMap.cpp b/contrib/llvm/lib/Support/IntervalMap.cpp index 4dfcc40..e11a7f2 100644 --- a/contrib/llvm/lib/Support/IntervalMap.cpp +++ b/contrib/llvm/lib/Support/IntervalMap.cpp @@ -58,7 +58,7 @@ void Path::moveLeft(unsigned Level) { } } else if (height() < Level) // end() may have created a height=0 path. - path.resize(Level + 1, Entry(0, 0, 0)); + path.resize(Level + 1, Entry(nullptr, 0, 0)); // NR is the subtree containing our left sibling. --path[l].offset; diff --git a/contrib/llvm/lib/Support/LEB128.cpp b/contrib/llvm/lib/Support/LEB128.cpp new file mode 100644 index 0000000..449626f --- /dev/null +++ b/contrib/llvm/lib/Support/LEB128.cpp @@ -0,0 +1,44 @@ +//===- LEB128.cpp - LEB128 utility functions implementation -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements some utility functions for encoding SLEB128 and +// ULEB128 values. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/LEB128.h" + +namespace llvm { + +/// Utility function to get the size of the ULEB128-encoded value. +unsigned getULEB128Size(uint64_t Value) { + unsigned Size = 0; + do { + Value >>= 7; + Size += sizeof(int8_t); + } while (Value); + return Size; +} + +/// Utility function to get the size of the SLEB128-encoded value. +unsigned getSLEB128Size(int64_t Value) { + unsigned Size = 0; + int Sign = Value >> (8 * sizeof(Value) - 1); + bool IsMore; + + do { + unsigned Byte = Value & 0x7f; + Value >>= 7; + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; + Size += sizeof(int8_t); + } while (IsMore); + return Size; +} + +} // namespace llvm diff --git a/contrib/llvm/lib/Support/LineIterator.cpp b/contrib/llvm/lib/Support/LineIterator.cpp new file mode 100644 index 0000000..947a8fb --- /dev/null +++ b/contrib/llvm/lib/Support/LineIterator.cpp @@ -0,0 +1,69 @@ +//===- LineIterator.cpp - Implementation of line iteration ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/LineIterator.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; + +line_iterator::line_iterator(const MemoryBuffer &Buffer, char CommentMarker) + : Buffer(Buffer.getBufferSize() ? &Buffer : nullptr), + CommentMarker(CommentMarker), LineNumber(1), + CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : nullptr, + 0) { + // Ensure that if we are constructed on a non-empty memory buffer that it is + // a null terminated buffer. + if (Buffer.getBufferSize()) { + assert(Buffer.getBufferEnd()[0] == '\0'); + advance(); + } +} + +void line_iterator::advance() { + assert(Buffer && "Cannot advance past the end!"); + + const char *Pos = CurrentLine.end(); + assert(Pos == Buffer->getBufferStart() || *Pos == '\n' || *Pos == '\0'); + + if (CommentMarker == '\0') { + // If we're not stripping comments, this is simpler. + size_t Blanks = 0; + while (Pos[Blanks] == '\n') + ++Blanks; + Pos += Blanks; + LineNumber += Blanks; + } else { + // Skip comments and count line numbers, which is a bit more complex. + for (;;) { + if (*Pos == CommentMarker) + do { + ++Pos; + } while (*Pos != '\0' && *Pos != '\n'); + if (*Pos != '\n') + break; + ++Pos; + ++LineNumber; + } + } + + if (*Pos == '\0') { + // We've hit the end of the buffer, reset ourselves to the end state. + Buffer = nullptr; + CurrentLine = StringRef(); + return; + } + + // Measure the line. + size_t Length = 0; + do { + ++Length; + } while (Pos[Length] != '\0' && Pos[Length] != '\n'); + + CurrentLine = StringRef(Pos, Length); +} diff --git a/contrib/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm/lib/Support/LockFileManager.cpp index eeec274..3f224e0 100644 --- a/contrib/llvm/lib/Support/LockFileManager.cpp +++ b/contrib/llvm/lib/Support/LockFileManager.cpp @@ -9,8 +9,10 @@ #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" #include "llvm/Support/raw_ostream.h" #include <sys/stat.h> #include <sys/types.h> @@ -29,25 +31,26 @@ using namespace llvm; /// \returns The process ID of the process that owns this lock file Optional<std::pair<std::string, int> > LockFileManager::readLockFile(StringRef LockFileName) { - // Check whether the lock file exists. If not, clearly there's nothing - // to read, so we just return. - bool Exists = false; - if (sys::fs::exists(LockFileName, Exists) || !Exists) - return None; - // 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. - OwningPtr<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; - tie(Hostname, PIDStr) = getToken(MB->getBuffer(), " "); + std::tie(Hostname, PIDStr) = getToken(MB->getBuffer(), " "); PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" ")); int PID; - if (!PIDStr.getAsInteger(10, PID)) - return std::make_pair(std::string(Hostname), PID); + if (!PIDStr.getAsInteger(10, PID)) { + auto Owner = std::make_pair(std::string(Hostname), PID); + if (processStillExecuting(Owner.first, Owner.second)) + return Owner; + } // Delete the lock file. It's invalid anyway. sys::fs::remove(LockFileName); @@ -71,7 +74,11 @@ bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { LockFileManager::LockFileManager(StringRef FileName) { this->FileName = FileName; - LockFileName = FileName; + if (std::error_code EC = sys::fs::make_absolute(this->FileName)) { + Error = EC; + return; + } + LockFileName = this->FileName; LockFileName += ".lock"; // If the lock file already exists, don't bother to try to create our own @@ -83,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; } @@ -111,41 +116,44 @@ LockFileManager::LockFileManager(StringRef FileName) // We failed to write out PID, so make up an excuse, remove the // unique lock file, and fail. Error = make_error_code(errc::no_space_on_device); - bool Existed; - sys::fs::remove(UniqueLockFileName.c_str(), Existed); + sys::fs::remove(UniqueLockFileName.c_str()); return; } } - // Create a hard link from the lock file name. If this succeeds, we're done. - error_code EC - = sys::fs::create_hard_link(UniqueLockFileName.str(), - LockFileName.str()); - if (EC == errc::success) - return; + while (1) { + // Create a link from the lock file name. If this succeeds, we're done. + std::error_code EC = + sys::fs::create_link(UniqueLockFileName.str(), LockFileName.str()); + if (!EC) + return; - // Creating the hard link failed. + if (EC != errc::file_exists) { + Error = EC; + return; + } -#ifdef LLVM_ON_UNIX - // The creation of the hard link may appear to fail, but if stat'ing the - // unique file returns a link count of 2, then we can still declare success. - struct stat StatBuf; - if (stat(UniqueLockFileName.c_str(), &StatBuf) == 0 && - StatBuf.st_nlink == 2) - return; -#endif + // Someone else managed to create the lock file first. Read the process ID + // from the lock file. + if ((Owner = readLockFile(LockFileName))) { + // Wipe out our unique lock file (it's useless now) + sys::fs::remove(UniqueLockFileName.str()); + return; + } - // Someone else managed to create the lock file first. Wipe out our unique - // lock file (it's useless now) and read the process ID from the lock file. - bool Existed; - sys::fs::remove(UniqueLockFileName.str(), Existed); - if ((Owner = readLockFile(LockFileName))) - return; + if (!sys::fs::exists(LockFileName.str())) { + // The previous owner released the lock file before we could read it. + // Try to get ownership again. + continue; + } - // There is a lock file that nobody owns; try to clean it up and report - // an error. - sys::fs::remove(LockFileName.str(), Existed); - Error = EC; + // There is a lock file that nobody owns; try to clean it up and get + // ownership. + if ((EC = sys::fs::remove(LockFileName.str()))) { + Error = EC; + return; + } + } } LockFileManager::LockFileState LockFileManager::getState() const { @@ -163,14 +171,13 @@ LockFileManager::~LockFileManager() { return; // Since we own the lock, remove the lock file and our own unique lock file. - bool Existed; - sys::fs::remove(LockFileName.str(), Existed); - sys::fs::remove(UniqueLockFileName.str(), Existed); + sys::fs::remove(LockFileName.str()); + sys::fs::remove(UniqueLockFileName.str()); } -void LockFileManager::waitForUnlock() { +LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() { if (getState() != LFS_Shared) - return; + return Res_Success; #if LLVM_ON_WIN32 unsigned long Interval = 1; @@ -190,26 +197,25 @@ void LockFileManager::waitForUnlock() { #if LLVM_ON_WIN32 Sleep(Interval); #else - nanosleep(&Interval, NULL); + nanosleep(&Interval, nullptr); #endif - bool Exists = false; bool LockFileJustDisappeared = false; // If the lock file is still expected to be there, check whether it still // is. if (!LockFileGone) { + bool Exists; if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) { LockFileGone = true; LockFileJustDisappeared = true; - Exists = false; } } // If the lock file is no longer there, check if the original file is // available now. if (LockFileGone) { - if (!sys::fs::exists(FileName.str(), Exists) && Exists) { - return; + if (sys::fs::exists(FileName.str())) { + return Res_Success; } // The lock file is gone, so now we're waiting for the original file to @@ -232,7 +238,7 @@ void LockFileManager::waitForUnlock() { // owning the lock died without cleaning up, just bail out. if (!LockFileGone && !processStillExecuting((*Owner).first, (*Owner).second)) { - return; + return Res_OwnerDied; } // Exponentially increase the time we wait for the lock to be removed. @@ -255,4 +261,5 @@ void LockFileManager::waitForUnlock() { ); // Give up. + return Res_Timeout; } diff --git a/contrib/llvm/lib/Support/ManagedStatic.cpp b/contrib/llvm/lib/Support/ManagedStatic.cpp index 098cccb..b8fb284 100644 --- a/contrib/llvm/lib/Support/ManagedStatic.cpp +++ b/contrib/llvm/lib/Support/ManagedStatic.cpp @@ -14,18 +14,29 @@ #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 = 0; +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 == 0) { - void* tmp = Creator ? Creator() : 0; + if (!Ptr) { + void* tmp = Creator(); TsanHappensBefore(this); sys::MemoryFence(); @@ -42,12 +53,10 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), Next = StaticList; StaticList = this; } - - llvm_release_global_lock(); } else { - assert(Ptr == 0 && DeleterFn == 0 && Next == 0 && + assert(!Ptr && !DeleterFn && !Next && "Partially initialized ManagedStatic!?"); - Ptr = Creator ? Creator() : 0; + Ptr = Creator(); DeleterFn = Deleter; // Add to list of managed statics. @@ -62,20 +71,20 @@ void ManagedStaticBase::destroy() const { "Not destroyed in reverse order of construction?"); // Unlink from list. StaticList = Next; - Next = 0; + Next = nullptr; // Destroy memory. DeleterFn(Ptr); // Cleanup. - Ptr = 0; - DeleterFn = 0; + Ptr = nullptr; + DeleterFn = nullptr; } /// 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/contrib/llvm/lib/Support/MemoryBuffer.cpp b/contrib/llvm/lib/Support/MemoryBuffer.cpp index dcd5529..5f4b7da 100644 --- a/contrib/llvm/lib/Support/MemoryBuffer.cpp +++ b/contrib/llvm/lib/Support/MemoryBuffer.cpp @@ -12,34 +12,26 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/MemoryBuffer.h" -#include "llvm/ADT/OwningPtr.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/stat.h> #include <sys/types.h> +#include <system_error> #if !defined(_MSC_VER) && !defined(__MINGW32__) #include <unistd.h> #else #include <io.h> -// Simplistic definitinos of these macros for use in getOpenFile. -#ifndef S_ISREG -#define S_ISREG(x) (1) -#endif -#ifndef S_ISBLK -#define S_ISBLK(x) (0) -#endif #endif using namespace llvm; @@ -91,12 +83,12 @@ public: init(InputData.begin(), InputData.end(), RequiresNullTerminator); } - virtual const char *getBufferIdentifier() const LLVM_OVERRIDE { + const char *getBufferIdentifier() const override { // The name is stored after the class itself. return reinterpret_cast<const char*>(this + 1); } - virtual BufferKind getBufferKind() const LLVM_OVERRIDE { + BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; } }; @@ -117,7 +109,7 @@ MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData, MemoryBuffer *MemoryBuffer::getMemBufferCopy(StringRef InputData, StringRef BufferName) { MemoryBuffer *Buf = getNewUninitMemBuffer(InputData.size(), BufferName); - if (!Buf) return 0; + if (!Buf) return nullptr; memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(), InputData.size()); return Buf; @@ -131,12 +123,13 @@ MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size, StringRef BufferName) { // Allocate space for the MemoryBuffer, the data and the name. It is important // that MemoryBuffer and data are aligned so PointerIntPair works with them. + // TODO: Is 16-byte alignment enough? We copy small object files with large + // alignment expectations into this buffer. size_t AlignedStringLen = - RoundUpToAlignment(sizeof(MemoryBufferMem) + BufferName.size() + 1, - sizeof(void*)); // TODO: Is sizeof(void*) enough? + RoundUpToAlignment(sizeof(MemoryBufferMem) + BufferName.size() + 1, 16); size_t RealLen = AlignedStringLen + Size + 1; char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); - if (!Mem) return 0; + if (!Mem) return nullptr; // The name is stored after the class itself. CopyStringRef(Mem + sizeof(MemoryBufferMem), BufferName); @@ -154,24 +147,19 @@ MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size, /// the MemoryBuffer object. MemoryBuffer *MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { MemoryBuffer *SB = getNewUninitMemBuffer(Size, BufferName); - if (!SB) return 0; + if (!SB) return nullptr; memset(const_cast<char*>(SB->getBufferStart()), 0, Size); 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, - OwningPtr<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); } + //===----------------------------------------------------------------------===// // MemoryBuffer::getFile implementation. //===----------------------------------------------------------------------===// @@ -197,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) { @@ -206,20 +194,19 @@ public: } } - virtual const char *getBufferIdentifier() const LLVM_OVERRIDE { + const char *getBufferIdentifier() const override { // The name is stored after the class itself. return reinterpret_cast<const char *>(this + 1); } - virtual BufferKind getBufferKind() const LLVM_OVERRIDE { + BufferKind getBufferKind() const override { return MemoryBuffer_MMap; } }; } -static error_code getMemoryBufferForStream(int FD, - StringRef BufferName, - OwningPtr<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; @@ -229,47 +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, - OwningPtr<MemoryBuffer> &result, int64_t FileSize, - bool RequiresNullTerminator); +static ErrorOr<std::unique_ptr<MemoryBuffer>> +getFileAux(const char *Filename, int64_t FileSize, bool RequiresNullTerminator, + bool IsVolatileSize); -error_code MemoryBuffer::getFile(Twine Filename, - OwningPtr<MemoryBuffer> &result, - int64_t FileSize, - bool RequiresNullTerminator) { +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); + return getFileAux(NullTerminatedName.data(), FileSize, RequiresNullTerminator, + IsVolatileSize); } -static error_code getOpenFileImpl(int FD, const char *Filename, - OwningPtr<MemoryBuffer> &Result, - uint64_t FileSize, uint64_t MapSize, - int64_t Offset, bool RequiresNullTerminator); +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, - OwningPtr<MemoryBuffer> &result, int64_t FileSize, - bool RequiresNullTerminator) { +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); + 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, @@ -277,7 +265,14 @@ static bool shouldUseMmap(int FD, size_t MapSize, off_t Offset, bool RequiresNullTerminator, - int PageSize) { + int PageSize, + bool IsVolatileSize) { + // mmap may leave the buffer without null terminator if the file size changed + // by the time the last page is mapped in, so avoid it if the file size is + // likely to change. + if (IsVolatileSize) + return false; + // We don't use mmap for small files because this can severely fragment our // address space. if (MapSize < 4 * 4096 || MapSize < (unsigned)PageSize) @@ -293,9 +288,8 @@ static bool shouldUseMmap(int FD, // RequiresNullTerminator = false and MapSize != -1. if (FileSize == size_t(-1)) { sys::fs::file_status Status; - error_code EC = sys::fs::status(FD, Status); - if (EC) - return EC; + if (sys::fs::status(FD, Status)) + return false; FileSize = Status.getSize(); } @@ -306,15 +300,6 @@ static bool shouldUseMmap(int FD, if (End != FileSize) return false; -#if defined(_WIN32) || defined(__CYGWIN__) - // Don't peek the next page if file is multiple of *physical* pagesize(4k) - // but is not multiple of AllocationGranularity(64k), - // when a null terminator is required. - // FIXME: It's not good to hardcode 4096 here. dwPageSize shows 4096. - if ((FileSize & (4096 - 1)) == 0) - return false; -#endif - // Don't try to map files that are exactly a multiple of the system page size // if we need a null terminator. if ((FileSize & (PageSize -1)) == 0) @@ -323,10 +308,10 @@ static bool shouldUseMmap(int FD, return true; } -static error_code getOpenFileImpl(int FD, const char *Filename, - OwningPtr<MemoryBuffer> &result, - uint64_t FileSize, uint64_t MapSize, - int64_t Offset, bool RequiresNullTerminator) { +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. @@ -335,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; @@ -345,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(); } @@ -353,12 +338,13 @@ static error_code getOpenFileImpl(int FD, const char *Filename, } if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, - PageSize)) { - error_code EC; - result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile( - RequiresNullTerminator, FD, MapSize, Offset, EC)); + PageSize, IsVolatileSize)) { + 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); @@ -368,13 +354,13 @@ static error_code getOpenFileImpl(int FD, const char *Filename, return make_error_code(errc::not_enough_memory); } - OwningPtr<MemoryBuffer> SB(Buf); + std::unique_ptr<MemoryBuffer> SB(Buf); char *BufPtr = const_cast<char*>(SB->getBufferStart()); 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) { @@ -387,46 +373,39 @@ 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) { - assert(0 && "We got inaccurate FileSize value or fstat reported an " - "invalid file size."); - *BufPtr = '\0'; // null-terminate at the actual size. + memset(BufPtr, 0, BytesLeft); // zero-initialize rest of the buffer. break; } BytesLeft -= NumRead; BufPtr += NumRead; } - result.swap(SB); - return error_code::success(); + return std::move(SB); } -error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, - OwningPtr<MemoryBuffer> &Result, - uint64_t FileSize, - bool RequiresNullTerminator) { - return getOpenFileImpl(FD, Filename, Result, FileSize, FileSize, 0, - RequiresNullTerminator); +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, - OwningPtr<MemoryBuffer> &Result, - uint64_t MapSize, int64_t Offset) { - 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(OwningPtr<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/contrib/llvm/lib/Support/Mutex.cpp b/contrib/llvm/lib/Support/Mutex.cpp index 4e4a026..c8d3844 100644 --- a/contrib/llvm/lib/Support/Mutex.cpp +++ b/contrib/llvm/lib/Support/Mutex.cpp @@ -42,7 +42,7 @@ using namespace sys; // Construct a Mutex using pthread calls MutexImpl::MutexImpl( bool recursive) - : data_(0) + : data_(nullptr) { // Declare the pthread_mutex data structures pthread_mutex_t* mutex = @@ -59,13 +59,6 @@ MutexImpl::MutexImpl( bool recursive) errorcode = pthread_mutexattr_settype(&attr, kind); assert(errorcode == 0); -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \ - !defined(__DragonFly__) && !defined(__Bitrig__) - // Make it a process local mutex - errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); - assert(errorcode == 0); -#endif - // Initialize the mutex errorcode = pthread_mutex_init(mutex, &attr); assert(errorcode == 0); @@ -82,7 +75,7 @@ MutexImpl::MutexImpl( bool recursive) MutexImpl::~MutexImpl() { pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); + assert(mutex != nullptr); pthread_mutex_destroy(mutex); free(mutex); } @@ -91,7 +84,7 @@ bool MutexImpl::acquire() { pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); + assert(mutex != nullptr); int errorcode = pthread_mutex_lock(mutex); return errorcode == 0; @@ -101,7 +94,7 @@ bool MutexImpl::release() { pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); + assert(mutex != nullptr); int errorcode = pthread_mutex_unlock(mutex); return errorcode == 0; @@ -111,7 +104,7 @@ bool MutexImpl::tryacquire() { pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_); - assert(mutex != 0); + assert(mutex != nullptr); int errorcode = pthread_mutex_trylock(mutex); return errorcode == 0; diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp index c869b30..d5a0ec5 100644 --- a/contrib/llvm/lib/Support/Path.cpp +++ b/contrib/llvm/lib/Support/Path.cpp @@ -11,10 +11,12 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Support/Errc.h" #include "llvm/Support/Path.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Process.h" #include <cctype> #include <cstdio> #include <cstring> @@ -26,16 +28,18 @@ #include <io.h> #endif +using namespace llvm; + namespace { using llvm::StringRef; using llvm::sys::path::is_separator; #ifdef LLVM_ON_WIN32 const char *separators = "\\/"; - const char prefered_separator = '\\'; + const char preferred_separator = '\\'; #else const char separators = '/'; - const char prefered_separator = '/'; + const char preferred_separator = '/'; #endif StringRef find_first_component(StringRef path) { @@ -161,10 +165,76 @@ enum FSEntity { }; // Implemented in Unix/Path.inc and Windows/Path.inc. -static llvm::error_code -createUniqueEntity(const llvm::Twine &Model, int &ResultFD, - llvm::SmallVectorImpl<char> &ResultPath, - bool MakeAbsolute, unsigned Mode, FSEntity Type); +static std::error_code TempDir(SmallVectorImpl<char> &result); + +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); + + if (MakeAbsolute) { + // Make model absolute by prepending a temp directory if it's not already. + if (!sys::path::is_absolute(Twine(ModelStorage))) { + SmallString<128> TDir; + if (std::error_code EC = TempDir(TDir)) + return EC; + sys::path::append(TDir, Twine(ModelStorage)); + ModelStorage.swap(TDir); + } + } + + // From here on, DO NOT modify model. It may be needed if the randomly chosen + // path already exists. + ResultPath = ModelStorage; + // Null terminate. + ResultPath.push_back(0); + ResultPath.pop_back(); + +retry_random_path: + // Replace '%' with random chars. + for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) { + if (ModelStorage[i] == '%') + ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15]; + } + + // Try to open + create the file. + switch (Type) { + case FS_File: { + 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) + goto retry_random_path; + return EC; + } + + return std::error_code(); + } + + case FS_Name: { + bool Exists; + std::error_code EC = sys::fs::exists(ResultPath.begin(), Exists); + if (EC) + return EC; + if (Exists) + goto retry_random_path; + return std::error_code(); + } + + case FS_Dir: { + if (std::error_code EC = + sys::fs::create_directory(ResultPath.begin(), false)) { + if (EC == errc::file_exists) + goto retry_random_path; + return EC; + } + return std::error_code(); + } + } + llvm_unreachable("Invalid Type"); +} namespace llvm { namespace sys { @@ -239,21 +309,18 @@ const_iterator &const_iterator::operator++() { } const_iterator &const_iterator::operator--() { - // If we're at the end and the previous char was a '/', return '.'. + // If we're at the end and the previous char was a '/', return '.' unless + // we are the root path. + size_t root_dir_pos = root_dir_start(Path); if (Position == Path.size() && - Path.size() > 1 && - is_separator(Path[Position - 1]) -#ifdef LLVM_ON_WIN32 - && Path[Position - 2] != ':' -#endif - ) { + Path.size() > root_dir_pos + 1 && + is_separator(Path[Position - 1])) { --Position; Component = "."; return *this; } // Skip separators unless it's the root directory. - size_t root_dir_pos = root_dir_start(Path); size_t end_pos = Position; while(end_pos > 0 && @@ -403,7 +470,7 @@ void append(SmallVectorImpl<char> &path, const Twine &a, if (!component_has_sep && !(path.empty() || is_root_name)) { // Add a separator. - path.push_back(prefered_separator); + path.push_back(preferred_separator); } path.append(i->begin(), i->end()); @@ -504,14 +571,21 @@ bool is_separator(char value) { } } +static const char preferred_separator_string[] = { preferred_separator, '\0' }; + +const StringRef get_separator() { + return preferred_separator_string; +} + void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) { result.clear(); -#ifdef __APPLE__ +#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR) // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR. + // macros defined in <unistd.h> on darwin >= 9 int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR : _CS_DARWIN_USER_CACHE_DIR; - size_t ConfLen = confstr(ConfName, 0, 0); + size_t ConfLen = confstr(ConfName, nullptr, 0); if (ConfLen > 0) { do { result.resize(ConfLen); @@ -633,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 && @@ -665,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); } @@ -690,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), @@ -709,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) { @@ -721,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) { @@ -730,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) { @@ -742,27 +816,68 @@ 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 &existed) { - SmallString<128> path_storage; - StringRef p = path.toStringRef(path_storage); +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 + 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) + return EC; - StringRef parent = path::parent_path(p); - if (!parent.empty()) { - bool parent_exists; - if (error_code ec = fs::exists(parent, parent_exists)) return ec; + // We failed because of a no_such_file_or_directory, try to create the + // parent. + StringRef Parent = path::parent_path(P); + if (Parent.empty()) + return EC; + + if ((EC = create_directories(Parent))) + return EC; + + return create_directory(P, IgnoreExisting); +} - if (!parent_exists) - if (error_code ec = create_directories(parent, existed)) return ec; +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; } - return create_directory(p, existed); + 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) { @@ -777,43 +892,30 @@ 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(); -} - -bool is_symlink(file_status status) { - return status.type() == file_type::symlink_file; -} - -error_code is_symlink(const Twine &path, bool &result) { - file_status st; - if (error_code ec = status(path, st)) - return ec; - result = is_symlink(st); - return error_code::success(); + return std::error_code(); } bool is_other(file_status status) { return exists(status) && !is_regular_file(status) && - !is_directory(status) && - !is_symlink(status); + !is_directory(status); } void directory_entry::replace_filename(const Twine &filename, file_status st) { @@ -824,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]) { @@ -943,6 +1027,7 @@ error_code has_magic(const Twine &path, const Twine &magic, bool &result) { case 0x66: // MPS R4000 Windows case 0x50: // mc68K case 0x4c: // 80386 Windows + case 0xc4: // ARMNT Windows if (Magic[1] == 0x01) return file_magic::coff_object; @@ -973,56 +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; - - result = identify_magic(Magic); - return error_code::success(); -} - -namespace { -error_code remove_all_r(StringRef path, file_type ft, uint32_t &count) { - if (ft == file_type::directory_file) { - // This code would be a lot better with exceptions ;/. - error_code ec; - directory_iterator i(path, ec); - if (ec) return ec; - for (directory_iterator e; i != e; i.increment(ec)) { - if (ec) return ec; - file_status st; - if (error_code ec = i->status(st)) return ec; - if (error_code ec = remove_all_r(i->path(), st.type(), count)) return ec; - } - bool obviously_this_exists; - if (error_code ec = remove(path, obviously_this_exists)) return ec; - assert(obviously_this_exists); - ++count; // Include the directory itself in the items removed. - } else { - bool obviously_this_exists; - if (error_code ec = remove(path, obviously_this_exists)) return ec; - assert(obviously_this_exists); - ++count; - } - - return error_code::success(); -} -} // end unnamed namespace +std::error_code identify_magic(const Twine &Path, file_magic &Result) { + int FD; + if (std::error_code EC = openFileForRead(Path, FD)) + return EC; -error_code remove_all(const Twine &path, uint32_t &num_removed) { - SmallString<128> path_storage; - StringRef p = path.toStringRef(path_storage); + char Buffer[32]; + int Length = read(FD, Buffer, sizeof(Buffer)); + if (close(FD) != 0 || Length < 0) + return std::error_code(errno, std::generic_category()); - file_status fs; - if (error_code ec = status(path, fs)) - return ec; - num_removed = 0; - return remove_all_r(p, fs.type(), num_removed); + 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/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp index 722f4ca..987778a 100644 --- a/contrib/llvm/lib/Support/PrettyStackTrace.cpp +++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/PrettyStackTrace.h" +#include "llvm-c/Core.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" // Get autoconf configuration settings #include "llvm/Support/ManagedStatic.h" @@ -20,7 +21,6 @@ #include "llvm/Support/ThreadLocal.h" #include "llvm/Support/Watchdog.h" #include "llvm/Support/raw_ostream.h" -#include "llvm-c/Core.h" #ifdef HAVE_CRASHREPORTERCLIENT_H #include <CrashReporterClient.h> @@ -46,7 +46,7 @@ static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){ /// PrintCurStackTrace - Print the current stack trace to the specified stream. static void PrintCurStackTrace(raw_ostream &OS) { // Don't print an empty trace. - if (PrettyStackTraceHead->get() == 0) return; + if (!PrettyStackTraceHead->get()) return; // If there are pretty stack frames registered, walk and emit them. OS << "Stack dump:\n"; @@ -136,7 +136,7 @@ void PrettyStackTraceProgram::print(raw_ostream &OS) const { } static bool RegisterCrashPrinter() { - sys::AddSignalHandler(CrashHandler, 0); + sys::AddSignalHandler(CrashHandler, nullptr); return false; } diff --git a/contrib/llvm/lib/Support/Process.cpp b/contrib/llvm/lib/Support/Process.cpp index d5168f0..0d42e0e 100644 --- a/contrib/llvm/lib/Support/Process.cpp +++ b/contrib/llvm/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; @@ -34,14 +37,6 @@ self_process *process::get_self() { return SP; } -#if defined(_MSC_VER) -// Visual Studio complains that the self_process destructor never exits. This -// doesn't make much sense, as that's the whole point of calling abort... Just -// silence this warning. -#pragma warning(push) -#pragma warning(disable:4722) -#endif - // The destructor for the self_process subclass must never actually be // executed. There should be at most one instance of this class, and that // instance should live until the process terminates to avoid the potential for @@ -74,10 +69,32 @@ 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; + } + } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif + return FoundPath; +} #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m" diff --git a/contrib/llvm/lib/Support/Program.cpp b/contrib/llvm/lib/Support/Program.cpp index 83f2ec4..b84b82b 100644 --- a/contrib/llvm/lib/Support/Program.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Support/RWMutex.cpp b/contrib/llvm/lib/Support/RWMutex.cpp index 6a34f2d..3b6309c 100644 --- a/contrib/llvm/lib/Support/RWMutex.cpp +++ b/contrib/llvm/lib/Support/RWMutex.cpp @@ -44,7 +44,7 @@ using namespace sys; // Construct a RWMutex using pthread calls RWMutexImpl::RWMutexImpl() - : data_(0) + : data_(nullptr) { // Declare the pthread_rwlock data structures pthread_rwlock_t* rwlock = @@ -56,7 +56,7 @@ RWMutexImpl::RWMutexImpl() #endif // Initialize the rwlock - int errorcode = pthread_rwlock_init(rwlock, NULL); + int errorcode = pthread_rwlock_init(rwlock, nullptr); (void)errorcode; assert(errorcode == 0); @@ -68,7 +68,7 @@ RWMutexImpl::RWMutexImpl() RWMutexImpl::~RWMutexImpl() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); + assert(rwlock != nullptr); pthread_rwlock_destroy(rwlock); free(rwlock); } @@ -77,7 +77,7 @@ bool RWMutexImpl::reader_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); + assert(rwlock != nullptr); int errorcode = pthread_rwlock_rdlock(rwlock); return errorcode == 0; @@ -87,7 +87,7 @@ bool RWMutexImpl::reader_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); + assert(rwlock != nullptr); int errorcode = pthread_rwlock_unlock(rwlock); return errorcode == 0; @@ -97,7 +97,7 @@ bool RWMutexImpl::writer_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); + assert(rwlock != nullptr); int errorcode = pthread_rwlock_wrlock(rwlock); return errorcode == 0; @@ -107,7 +107,7 @@ bool RWMutexImpl::writer_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); - assert(rwlock != 0); + assert(rwlock != nullptr); int errorcode = pthread_rwlock_unlock(rwlock); return errorcode == 0; diff --git a/contrib/llvm/lib/Support/RandomNumberGenerator.cpp b/contrib/llvm/lib/Support/RandomNumberGenerator.cpp new file mode 100644 index 0000000..c50e7cb --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/Support/Regex.cpp b/contrib/llvm/lib/Support/Regex.cpp index 5413641..f7fe1e4 100644 --- a/contrib/llvm/lib/Support/Regex.cpp +++ b/contrib/llvm/lib/Support/Regex.cpp @@ -33,15 +33,17 @@ Regex::Regex(StringRef regex, unsigned Flags) { } Regex::~Regex() { - llvm_regfree(preg); - delete preg; + if (preg) { + llvm_regfree(preg); + delete preg; + } } bool Regex::isValid(std::string &Error) { if (!error) return true; - size_t len = llvm_regerror(error, preg, NULL, 0); + size_t len = llvm_regerror(error, preg, nullptr, 0); Error.resize(len - 1); llvm_regerror(error, preg, &Error[0], len); @@ -169,9 +171,23 @@ std::string Regex::sub(StringRef Repl, StringRef String, return Res; } +// These are the special characters matched in functions like "p_ere_exp". +static const char RegexMetachars[] = "()^$|*+?.[]\\{}"; + bool Regex::isLiteralERE(StringRef Str) { // Check for regex metacharacters. This list was derived from our regex // implementation in regcomp.c and double checked against the POSIX extended // regular expression specification. - return Str.find_first_of("()^$|*+?.[]\\{}") == StringRef::npos; + return Str.find_first_of(RegexMetachars) == StringRef::npos; +} + +std::string Regex::escape(StringRef String) { + std::string RegexStr; + for (unsigned i = 0, e = String.size(); i != e; ++i) { + if (strchr(RegexMetachars, String[i])) + RegexStr += '\\'; + RegexStr += String[i]; + } + + return RegexStr; } diff --git a/contrib/llvm/lib/Support/ScaledNumber.cpp b/contrib/llvm/lib/Support/ScaledNumber.cpp new file mode 100644 index 0000000..3fe027b --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp b/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp index 2d23902..55f3320 100644 --- a/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp +++ b/contrib/llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp @@ -48,7 +48,7 @@ static void *DoSearch(const char* symbolName) { #endif #undef EXPLICIT_SYMBOL - return 0; + return nullptr; } namespace llvm { diff --git a/contrib/llvm/lib/Support/SmallPtrSet.cpp b/contrib/llvm/lib/Support/SmallPtrSet.cpp index dd417b4..a80e095 100644 --- a/contrib/llvm/lib/Support/SmallPtrSet.cpp +++ b/contrib/llvm/lib/Support/SmallPtrSet.cpp @@ -20,7 +20,7 @@ using namespace llvm; -void SmallPtrSetImpl::shrink_and_clear() { +void SmallPtrSetImplBase::shrink_and_clear() { assert(!isSmall() && "Can't shrink a small set!"); free(CurArray); @@ -34,7 +34,7 @@ void SmallPtrSetImpl::shrink_and_clear() { memset(CurArray, -1, CurArraySize*sizeof(void*)); } -bool SmallPtrSetImpl::insert_imp(const void * Ptr) { +bool SmallPtrSetImplBase::insert_imp(const void * Ptr) { if (isSmall()) { // Check to see if it is already in the set. for (const void **APtr = SmallArray, **E = SmallArray+NumElements; @@ -71,7 +71,7 @@ bool SmallPtrSetImpl::insert_imp(const void * Ptr) { return true; } -bool SmallPtrSetImpl::erase_imp(const void * Ptr) { +bool SmallPtrSetImplBase::erase_imp(const void * Ptr) { if (isSmall()) { // Check to see if it is in the set. for (const void **APtr = SmallArray, **E = SmallArray+NumElements; @@ -98,12 +98,12 @@ bool SmallPtrSetImpl::erase_imp(const void * Ptr) { return true; } -const void * const *SmallPtrSetImpl::FindBucketFor(const void *Ptr) const { +const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const { unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1); unsigned ArraySize = CurArraySize; unsigned ProbeAmt = 1; const void *const *Array = CurArray; - const void *const *Tombstone = 0; + const void *const *Tombstone = nullptr; while (1) { // Found Ptr's bucket? if (Array[Bucket] == Ptr) @@ -127,7 +127,7 @@ const void * const *SmallPtrSetImpl::FindBucketFor(const void *Ptr) const { /// Grow - Allocate a larger backing store for the buckets and move it over. /// -void SmallPtrSetImpl::Grow(unsigned NewSize) { +void SmallPtrSetImplBase::Grow(unsigned NewSize) { // Allocate at twice as many buckets, but at least 128. unsigned OldSize = CurArraySize; @@ -163,8 +163,8 @@ void SmallPtrSetImpl::Grow(unsigned NewSize) { } } -SmallPtrSetImpl::SmallPtrSetImpl(const void **SmallStorage, - const SmallPtrSetImpl& that) { +SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage, + const SmallPtrSetImplBase& that) { SmallArray = SmallStorage; // If we're becoming small, prepare to insert into our stack space @@ -186,9 +186,39 @@ SmallPtrSetImpl::SmallPtrSetImpl(const void **SmallStorage, NumTombstones = that.NumTombstones; } +SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage, + unsigned SmallSize, + SmallPtrSetImplBase &&that) { + SmallArray = SmallStorage; + + // Copy over the basic members. + CurArraySize = that.CurArraySize; + NumElements = that.NumElements; + NumTombstones = that.NumTombstones; + + // When small, just copy into our small buffer. + if (that.isSmall()) { + CurArray = SmallArray; + memcpy(CurArray, that.CurArray, sizeof(void *) * CurArraySize); + return; + } + + // Otherwise, we steal the large memory allocation and no copy is needed. + CurArray = that.CurArray; + that.CurArray = that.SmallArray; + + // Make the "that" object small and empty. + that.CurArraySize = SmallSize; + assert(that.CurArray == that.SmallArray); + that.NumElements = 0; + that.NumTombstones = 0; +} + /// CopyFrom - implement operator= from a smallptrset that has the same pointer /// type, but may have a different small size. -void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) { +void SmallPtrSetImplBase::CopyFrom(const SmallPtrSetImplBase &RHS) { + assert(&RHS != this && "Self-copy should be handled by the caller."); + if (isSmall() && RHS.isSmall()) assert(CurArraySize == RHS.CurArraySize && "Cannot assign sets with different small sizes"); @@ -222,7 +252,35 @@ void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) { NumTombstones = RHS.NumTombstones; } -void SmallPtrSetImpl::swap(SmallPtrSetImpl &RHS) { +void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize, + SmallPtrSetImplBase &&RHS) { + assert(&RHS != this && "Self-move should be handled by the caller."); + + if (!isSmall()) + free(CurArray); + + if (RHS.isSmall()) { + // Copy a small RHS rather than moving. + CurArray = SmallArray; + memcpy(CurArray, RHS.CurArray, sizeof(void*)*RHS.CurArraySize); + } else { + CurArray = RHS.CurArray; + RHS.CurArray = RHS.SmallArray; + } + + // Copy the rest of the trivial members. + CurArraySize = RHS.CurArraySize; + NumElements = RHS.NumElements; + NumTombstones = RHS.NumTombstones; + + // Make the RHS small and empty. + RHS.CurArraySize = SmallSize; + assert(RHS.CurArray == RHS.SmallArray); + RHS.NumElements = 0; + RHS.NumTombstones = 0; +} + +void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) { if (this == &RHS) return; // We can only avoid copying elements if neither set is small. @@ -272,7 +330,7 @@ void SmallPtrSetImpl::swap(SmallPtrSetImpl &RHS) { std::swap(this->NumElements, RHS.NumElements); } -SmallPtrSetImpl::~SmallPtrSetImpl() { +SmallPtrSetImplBase::~SmallPtrSetImplBase() { if (!isSmall()) free(CurArray); } diff --git a/contrib/llvm/lib/Support/SourceMgr.cpp b/contrib/llvm/lib/Support/SourceMgr.cpp index d4b94f8..003cb56 100644 --- a/contrib/llvm/lib/Support/SourceMgr.cpp +++ b/contrib/llvm/lib/Support/SourceMgr.cpp @@ -14,20 +14,20 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/SourceMgr.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Locale.h" #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) { - OwningPtr<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] + "/" + 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.take(), 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. @@ -115,7 +111,7 @@ SourceMgr::getLineAndColumn(SMLoc Loc, int BufferID) const { if (*Ptr == '\n') ++LineNo; // Allocate the line number cache if it doesn't exist. - if (LineNoCache == 0) + if (!LineNoCache) LineNoCache = new LineNoCacheTy(); // Update the line # cache. @@ -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,25 +202,28 @@ 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(0, OS, ShowColors); + 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, diff --git a/contrib/llvm/lib/Support/SpecialCaseList.cpp b/contrib/llvm/lib/Support/SpecialCaseList.cpp new file mode 100644 index 0000000..21e43c5 --- /dev/null +++ b/contrib/llvm/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/contrib/llvm/lib/Support/Statistic.cpp b/contrib/llvm/lib/Support/Statistic.cpp index 9c28176..56c3b0f 100644 --- a/contrib/llvm/lib/Support/Statistic.cpp +++ b/contrib/llvm/lib/Support/Statistic.cpp @@ -84,20 +84,6 @@ void Statistic::RegisterStatistic() { } } -namespace { - -struct NameCompare { - bool operator()(const Statistic *LHS, const Statistic *RHS) const { - int Cmp = std::strcmp(LHS->getName(), RHS->getName()); - if (Cmp != 0) return Cmp < 0; - - // Secondary key is the description. - return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0; - } -}; - -} - // Print information when destroyed, iff command line option is specified. StatisticInfo::~StatisticInfo() { llvm::PrintStatistics(); @@ -124,7 +110,14 @@ void llvm::PrintStatistics(raw_ostream &OS) { } // Sort the fields by name. - std::stable_sort(Stats.Stats.begin(), Stats.Stats.end(), NameCompare()); + std::stable_sort(Stats.Stats.begin(), Stats.Stats.end(), + [](const Statistic *LHS, const Statistic *RHS) { + if (int Cmp = std::strcmp(LHS->getName(), RHS->getName())) + return Cmp < 0; + + // Secondary key is the description. + return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0; + }); // Print out the statistics header... OS << "===" << std::string(73, '-') << "===\n" diff --git a/contrib/llvm/lib/Support/StreamableMemoryObject.cpp b/contrib/llvm/lib/Support/StreamableMemoryObject.cpp index 2ed7c5c..5cb0680 100644 --- a/contrib/llvm/lib/Support/StreamableMemoryObject.cpp +++ b/contrib/llvm/lib/Support/StreamableMemoryObject.cpp @@ -10,6 +10,7 @@ #include "llvm/Support/StreamableMemoryObject.h" #include "llvm/Support/Compiler.h" #include <cassert> +#include <cstddef> #include <cstring> @@ -24,20 +25,18 @@ public: assert(LastChar >= FirstChar && "Invalid start/end range"); } - virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; } - virtual uint64_t getExtent() const LLVM_OVERRIDE { + uint64_t getBase() const override { return 0; } + uint64_t getExtent() const override { return LastChar - FirstChar; } - virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE; - virtual int readBytes(uint64_t address, - uint64_t size, - uint8_t *buf) const LLVM_OVERRIDE; - virtual const uint8_t *getPointer(uint64_t address, - uint64_t size) const LLVM_OVERRIDE; - virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE { + int readByte(uint64_t address, uint8_t* ptr) const override; + int readBytes(uint64_t address, uint64_t size, + uint8_t *buf) const override; + const uint8_t *getPointer(uint64_t address, uint64_t size) const override; + bool isValidAddress(uint64_t address) const override { return validAddress(address); } - virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE { + bool isObjectEnd(uint64_t address) const override { return objectEnd(address); } @@ -48,10 +47,10 @@ private: // These are implemented as inline functions here to avoid multiple virtual // calls per public function bool validAddress(uint64_t address) const { - return static_cast<ptrdiff_t>(address) < LastChar - FirstChar; + return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar; } bool objectEnd(uint64_t address) const { - return static_cast<ptrdiff_t>(address) == LastChar - FirstChar; + return static_cast<std::ptrdiff_t>(address) == LastChar - FirstChar; } RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION; diff --git a/contrib/llvm/lib/Support/StringMap.cpp b/contrib/llvm/lib/Support/StringMap.cpp index 9ac1f86..ddb7349 100644 --- a/contrib/llvm/lib/Support/StringMap.cpp +++ b/contrib/llvm/lib/Support/StringMap.cpp @@ -27,7 +27,7 @@ StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) { } // Otherwise, initialize it with zero buckets to avoid the allocation. - TheTable = 0; + TheTable = nullptr; NumBuckets = 0; NumItems = 0; NumTombstones = 0; @@ -70,7 +70,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) { while (1) { StringMapEntryBase *BucketItem = TheTable[BucketNo]; // If we found an empty bucket, this key isn't in the table yet, return it. - if (LLVM_LIKELY(BucketItem == 0)) { + if (LLVM_LIKELY(!BucketItem)) { // If we found a tombstone, we want to reuse the tombstone instead of an // empty bucket. This reduces probing. if (FirstTombstone != -1) { @@ -124,7 +124,7 @@ int StringMapImpl::FindKey(StringRef Key) const { while (1) { StringMapEntryBase *BucketItem = TheTable[BucketNo]; // If we found an empty bucket, this key isn't in the table yet, return. - if (LLVM_LIKELY(BucketItem == 0)) + if (LLVM_LIKELY(!BucketItem)) return -1; if (BucketItem == getTombstoneVal()) { @@ -166,7 +166,7 @@ void StringMapImpl::RemoveKey(StringMapEntryBase *V) { /// table, returning it. If the key is not in the table, this returns null. StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) { int Bucket = FindKey(Key); - if (Bucket == -1) return 0; + if (Bucket == -1) return nullptr; StringMapEntryBase *Result = TheTable[Bucket]; TheTable[Bucket] = getTombstoneVal(); @@ -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 = @@ -212,9 +213,11 @@ void StringMapImpl::RehashTable() { // Fast case, bucket available. unsigned FullHash = HashTable[I]; unsigned NewBucket = FullHash & (NewSize-1); - if (NewTableArray[NewBucket] == 0) { + 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/contrib/llvm/lib/Support/StringPool.cpp b/contrib/llvm/lib/Support/StringPool.cpp index ff607cf..76faabc 100644 --- a/contrib/llvm/lib/Support/StringPool.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Support/StringRef.cpp b/contrib/llvm/lib/Support/StringRef.cpp index bfae754..cde8258 100644 --- a/contrib/llvm/lib/Support/StringRef.cpp +++ b/contrib/llvm/lib/Support/StringRef.cpp @@ -10,7 +10,6 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/edit_distance.h" #include <bitset> @@ -282,7 +281,7 @@ void StringRef::split(SmallVectorImpl<StringRef> &A, // rest.data() is used to distinguish cases like "a," that splits into // "a" + "" and "a" that splits into "a" + 0. for (int splits = 0; - rest.data() != NULL && (MaxSplit < 0 || splits < MaxSplit); + rest.data() != nullptr && (MaxSplit < 0 || splits < MaxSplit); ++splits) { std::pair<StringRef, StringRef> p = rest.split(Separators); @@ -291,7 +290,7 @@ void StringRef::split(SmallVectorImpl<StringRef> &A, rest = p.second; } // If we have a tail left, add it. - if (rest.data() != NULL && (rest.size() != 0 || KeepEmpty)) + if (rest.data() != nullptr && (rest.size() != 0 || KeepEmpty)) A.push_back(rest); } diff --git a/contrib/llvm/lib/Support/TargetRegistry.cpp b/contrib/llvm/lib/Support/TargetRegistry.cpp index 0c90c17..f691883 100644 --- a/contrib/llvm/lib/Support/TargetRegistry.cpp +++ b/contrib/llvm/lib/Support/TargetRegistry.cpp @@ -17,7 +17,7 @@ using namespace llvm; // Clients are responsible for avoid race conditions in registration. -static Target *FirstTarget = 0; +static Target *FirstTarget = nullptr; TargetRegistry::iterator TargetRegistry::begin() { return iterator(FirstTarget); @@ -29,7 +29,7 @@ const Target *TargetRegistry::lookupTarget(const std::string &ArchName, // Allocate target machine. First, check whether the user has explicitly // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. - const Target *TheTarget = 0; + const Target *TheTarget = nullptr; if (!ArchName.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { @@ -41,7 +41,7 @@ const Target *TargetRegistry::lookupTarget(const std::string &ArchName, if (!TheTarget) { Error = "error: invalid target '" + ArchName + "'.\n"; - return 0; + return nullptr; } // Adjust the triple to match (if known), otherwise stick with the @@ -53,11 +53,11 @@ const Target *TargetRegistry::lookupTarget(const std::string &ArchName, // Get the target specific parser. std::string TempError; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), TempError); - if (TheTarget == 0) { + if (!TheTarget) { Error = ": error: unable to get target for '" + TheTriple.getTriple() + "', see --version and --triple.\n"; - return 0; + return nullptr; } } @@ -69,44 +69,36 @@ const Target *TargetRegistry::lookupTarget(const std::string &TT, // Provide special warning when no targets are initialized. if (begin() == end()) { Error = "Unable to find target for this triple (no targets are registered)"; - return 0; + return nullptr; } - const Target *Best = 0, *EquallyBest = 0; - unsigned BestQuality = 0; + const Target *Matching = nullptr; + Triple::ArchType Arch = Triple(TT).getArch(); for (iterator it = begin(), ie = end(); it != ie; ++it) { - if (unsigned Qual = it->TripleMatchQualityFn(TT)) { - if (!Best || Qual > BestQuality) { - Best = &*it; - EquallyBest = 0; - BestQuality = Qual; - } else if (Qual == BestQuality) - EquallyBest = &*it; + if (it->ArchMatchFn(Arch)) { + if (Matching) { + Error = std::string("Cannot choose between targets \"") + + Matching->Name + "\" and \"" + it->Name + "\""; + return nullptr; + } + Matching = &*it; } } - if (!Best) { + if (!Matching) { Error = "No available targets are compatible with this triple, " "see -version for the available targets."; - return 0; + return nullptr; } - // Otherwise, take the best target, but make sure we don't have two equally - // good best targets. - if (EquallyBest) { - Error = std::string("Cannot choose between targets \"") + - Best->Name + "\" and \"" + EquallyBest->Name + "\""; - return 0; - } - - return Best; + return Matching; } void TargetRegistry::RegisterTarget(Target &T, const char *Name, const char *ShortDesc, - Target::TripleMatchQualityFnTy TQualityFn, + Target::ArchMatchFnTy ArchMatchFn, bool HasJIT) { - assert(Name && ShortDesc && TQualityFn && + assert(Name && ShortDesc && ArchMatchFn && "Missing required target information!"); // Check if this target has already been initialized, we allow this as a @@ -120,21 +112,10 @@ void TargetRegistry::RegisterTarget(Target &T, T.Name = Name; T.ShortDesc = ShortDesc; - T.TripleMatchQualityFn = TQualityFn; + T.ArchMatchFn = ArchMatchFn; 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 0; - } - - 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/contrib/llvm/lib/Support/ThreadLocal.cpp b/contrib/llvm/lib/Support/ThreadLocal.cpp index 868b6ea..2dec9eb 100644 --- a/contrib/llvm/lib/Support/ThreadLocal.cpp +++ b/contrib/llvm/lib/Support/ThreadLocal.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Config/config.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ThreadLocal.h" //===----------------------------------------------------------------------===// @@ -26,7 +27,7 @@ using namespace sys; ThreadLocalImpl::ThreadLocalImpl() : data() { } ThreadLocalImpl::~ThreadLocalImpl() { } void ThreadLocalImpl::setInstance(const void* d) { - typedef int SIZE_TOO_BIG[sizeof(d) <= sizeof(data) ? 1 : -1]; + static_assert(sizeof(d) <= sizeof(data), "size too big"); void **pd = reinterpret_cast<void**>(&data); *pd = const_cast<void*>(d); } @@ -50,9 +51,9 @@ namespace llvm { using namespace sys; ThreadLocalImpl::ThreadLocalImpl() : data() { - typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1]; + static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big"); pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); - int errorcode = pthread_key_create(key, NULL); + int errorcode = pthread_key_create(key, nullptr); assert(errorcode == 0); (void) errorcode; } @@ -77,7 +78,7 @@ const void* ThreadLocalImpl::getInstance() { } void ThreadLocalImpl::removeInstance() { - setInstance(0); + setInstance(nullptr); } } diff --git a/contrib/llvm/lib/Support/Threading.cpp b/contrib/llvm/lib/Support/Threading.cpp index 13fba2e..ca7f3f6 100644 --- a/contrib/llvm/lib/Support/Threading.cpp +++ b/contrib/llvm/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 = 0; - -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> @@ -73,7 +38,7 @@ struct ThreadInfo { static void *ExecuteOnThread_Dispatch(void *Arg) { ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg); TI->UserFn(TI->UserData); - return 0; + return nullptr; } void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, @@ -97,13 +62,13 @@ void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, goto error; // Wait for the thread and clean up. - ::pthread_join(Thread, 0); + ::pthread_join(Thread, nullptr); error: ::pthread_attr_destroy(&Attr); } #elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32) -#include "Windows/Windows.h" +#include "Windows/WindowsSupport.h" #include <process.h> struct ThreadInfo { diff --git a/contrib/llvm/lib/Support/TimeValue.cpp b/contrib/llvm/lib/Support/TimeValue.cpp index bd8af17..4a70797 100644 --- a/contrib/llvm/lib/Support/TimeValue.cpp +++ b/contrib/llvm/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/contrib/llvm/lib/Support/Timer.cpp b/contrib/llvm/lib/Support/Timer.cpp index 100b21e..210bda7 100644 --- a/contrib/llvm/lib/Support/Timer.cpp +++ b/contrib/llvm/lib/Support/Timer.cpp @@ -12,13 +12,14 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Timer.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" #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; @@ -66,8 +67,8 @@ raw_ostream *llvm::CreateInfoOutputFile() { // compensate for this, the test-suite Makefiles have code to delete the // info output file before running commands which write to it. std::string Error; - raw_ostream *Result = - new raw_fd_ostream(OutputFilename.c_str(), Error, sys::fs::F_Append); + raw_ostream *Result = new raw_fd_ostream( + OutputFilename.c_str(), Error, sys::fs::F_Append | sys::fs::F_Text); if (Error.empty()) return Result; @@ -78,20 +79,19 @@ raw_ostream *llvm::CreateInfoOutputFile() { } -static TimerGroup *DefaultTimerGroup = 0; +static TimerGroup *DefaultTimerGroup = nullptr; static TimerGroup *getDefaultTimerGroup() { TimerGroup *tmp = DefaultTimerGroup; 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; } @@ -101,7 +101,7 @@ static TimerGroup *getDefaultTimerGroup() { //===----------------------------------------------------------------------===// void Timer::init(StringRef N) { - assert(TG == 0 && "Timer already initialized"); + assert(!TG && "Timer already initialized"); Name.assign(N.begin(), N.end()); Started = false; TG = getDefaultTimerGroup(); @@ -109,7 +109,7 @@ void Timer::init(StringRef N) { } void Timer::init(StringRef N, TimerGroup &tg) { - assert(TG == 0 && "Timer already initialized"); + assert(!TG && "Timer already initialized"); Name.assign(N.begin(), N.end()); Started = false; TG = &tg; @@ -236,11 +236,11 @@ static Timer &getNamedRegionTimer(StringRef Name) { NamedRegionTimer::NamedRegionTimer(StringRef Name, bool Enabled) - : TimeRegion(!Enabled ? 0 : &getNamedRegionTimer(Name)) {} + : TimeRegion(!Enabled ? nullptr : &getNamedRegionTimer(Name)) {} NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName, bool Enabled) - : TimeRegion(!Enabled ? 0 : &NamedGroupedTimers->get(Name, GroupName)) {} + : TimeRegion(!Enabled ? nullptr : &NamedGroupedTimers->get(Name, GroupName)){} //===----------------------------------------------------------------------===// // TimerGroup Implementation @@ -248,10 +248,10 @@ NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName, /// TimerGroupList - This is the global list of TimerGroups, maintained by the /// TimerGroup ctor/dtor and is protected by the TimerLock lock. -static TimerGroup *TimerGroupList = 0; +static TimerGroup *TimerGroupList = nullptr; TimerGroup::TimerGroup(StringRef name) - : Name(name.begin(), name.end()), FirstTimer(0) { + : Name(name.begin(), name.end()), FirstTimer(nullptr) { // Add the group to TimerGroupList. sys::SmartScopedLock<true> L(*TimerLock); @@ -265,7 +265,7 @@ TimerGroup::TimerGroup(StringRef name) TimerGroup::~TimerGroup() { // If the timer group is destroyed before the timers it owns, accumulate and // print the timing data. - while (FirstTimer != 0) + while (FirstTimer) removeTimer(*FirstTimer); // Remove the group from the TimerGroupList. @@ -283,7 +283,7 @@ void TimerGroup::removeTimer(Timer &T) { if (T.Started) TimersToPrint.push_back(std::make_pair(T.Time, T.Name)); - T.TG = 0; + T.TG = nullptr; // Unlink the timer from our list. *T.Prev = T.Next; @@ -292,7 +292,7 @@ void TimerGroup::removeTimer(Timer &T) { // Print the report when all timers in this group are destroyed if some of // them were started. - if (FirstTimer != 0 || TimersToPrint.empty()) + if (FirstTimer || TimersToPrint.empty()) return; raw_ostream *OutStream = CreateInfoOutputFile(); diff --git a/contrib/llvm/lib/Support/ToolOutputFile.cpp b/contrib/llvm/lib/Support/ToolOutputFile.cpp index 5c1268a..b5fb20f 100644 --- a/contrib/llvm/lib/Support/ToolOutputFile.cpp +++ b/contrib/llvm/lib/Support/ToolOutputFile.cpp @@ -25,10 +25,8 @@ tool_output_file::CleanupInstaller::CleanupInstaller(const char *filename) tool_output_file::CleanupInstaller::~CleanupInstaller() { // Delete the file if the client hasn't told us not to. - if (!Keep && Filename != "-") { - bool Existed; - sys::fs::remove(Filename, Existed); - } + if (!Keep && Filename != "-") + sys::fs::remove(Filename); // Ok, the file is successfully written and closed, or deleted. There's no // further need to clean it up on signals. diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp index 6c978a0..ca68775 100644 --- a/contrib/llvm/lib/Support/Triple.cpp +++ b/contrib/llvm/lib/Support/Triple.cpp @@ -19,32 +19,38 @@ const char *Triple::getArchTypeName(ArchType Kind) { switch (Kind) { case UnknownArch: return "unknown"; - case aarch64: return "aarch64"; - case arm: return "arm"; - case hexagon: return "hexagon"; - case mips: return "mips"; - case mipsel: return "mipsel"; - case mips64: return "mips64"; - case mips64el:return "mips64el"; - case msp430: return "msp430"; - case ppc64: return "powerpc64"; - case ppc64le: return "powerpc64le"; - case ppc: return "powerpc"; - case r600: return "r600"; - case sparc: return "sparc"; - case sparcv9: return "sparcv9"; - case systemz: return "s390x"; - case tce: return "tce"; - case thumb: return "thumb"; - case x86: return "i386"; - case x86_64: return "x86_64"; - case xcore: return "xcore"; - case nvptx: return "nvptx"; - case nvptx64: return "nvptx64"; - case le32: return "le32"; - case amdil: return "amdil"; - case spir: return "spir"; - case spir64: return "spir64"; + case aarch64: return "aarch64"; + case aarch64_be: return "aarch64_be"; + case arm: return "arm"; + case armeb: return "armeb"; + case arm64: return "arm64"; + case arm64_be: return "arm64_be"; + case hexagon: return "hexagon"; + case mips: return "mips"; + case mipsel: return "mipsel"; + case mips64: return "mips64"; + case mips64el: return "mips64el"; + case msp430: return "msp430"; + case ppc64: return "powerpc64"; + case ppc64le: return "powerpc64le"; + case ppc: return "powerpc"; + case r600: return "r600"; + case sparc: return "sparc"; + case sparcv9: return "sparcv9"; + case systemz: return "s390x"; + case tce: return "tce"; + case thumb: return "thumb"; + case thumbeb: return "thumbeb"; + case x86: return "i386"; + case x86_64: return "x86_64"; + case xcore: return "xcore"; + case nvptx: return "nvptx"; + case nvptx64: return "nvptx64"; + case le32: return "le32"; + case amdil: return "amdil"; + case spir: return "spir"; + case spir64: return "spir64"; + case kalimba: return "kalimba"; } llvm_unreachable("Invalid ArchType!"); @@ -53,42 +59,49 @@ const char *Triple::getArchTypeName(ArchType Kind) { const char *Triple::getArchTypePrefix(ArchType Kind) { switch (Kind) { default: - return 0; + return nullptr; - case aarch64: return "aarch64"; + case arm64: + case arm64_be: + case aarch64: + case aarch64_be: return "aarch64"; case arm: - case thumb: return "arm"; + case armeb: + case thumb: + case thumbeb: return "arm"; case ppc64: case ppc64le: - case ppc: return "ppc"; + case ppc: return "ppc"; case mips: case mipsel: case mips64: - case mips64el:return "mips"; + case mips64el: return "mips"; - case hexagon: return "hexagon"; + case hexagon: return "hexagon"; - case r600: return "r600"; + case r600: return "r600"; case sparcv9: - case sparc: return "sparc"; + case sparc: return "sparc"; - case systemz: return "systemz"; + case systemz: return "systemz"; case x86: - case x86_64: return "x86"; + case x86_64: return "x86"; + + case xcore: return "xcore"; - case xcore: return "xcore"; + case nvptx: return "nvptx"; + case nvptx64: return "nvptx"; - case nvptx: return "nvptx"; - case nvptx64: return "nvptx"; - case le32: return "le32"; - case amdil: return "amdil"; - case spir: return "spir"; - case spir64: return "spir"; + case le32: return "le32"; + case amdil: return "amdil"; + case spir: return "spir"; + case spir64: return "spir"; + case kalimba: return "kalimba"; } } @@ -103,7 +116,10 @@ const char *Triple::getVendorTypeName(VendorType Kind) { case BGQ: return "bgq"; case Freescale: return "fsl"; case IBM: return "ibm"; + case ImaginationTechnologies: return "img"; + case MipsTechnologies: return "mti"; case NVIDIA: return "nvidia"; + case CSR: return "csr"; } llvm_unreachable("Invalid VendorType!"); @@ -127,7 +143,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case NetBSD: return "netbsd"; case OpenBSD: return "openbsd"; case Solaris: return "solaris"; - case Win32: return "win32"; + case Win32: return "windows"; case Haiku: return "haiku"; case Minix: return "minix"; case RTEMS: return "rtems"; @@ -149,10 +165,13 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { case GNUEABIHF: return "gnueabihf"; case GNUEABI: return "gnueabi"; case GNUX32: return "gnux32"; + case CODE16: return "code16"; case EABI: return "eabi"; - case MachO: return "macho"; + case EABIHF: return "eabihf"; case Android: return "android"; - case ELF: return "elf"; + case MSVC: return "msvc"; + case Itanium: return "itanium"; + case Cygnus: return "cygnus"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -161,7 +180,11 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { return StringSwitch<Triple::ArchType>(Name) .Case("aarch64", aarch64) + .Case("aarch64_be", aarch64_be) .Case("arm", arm) + .Case("armeb", armeb) + .Case("arm64", arm64) + .Case("arm64_be", arm64_be) .Case("mips", mips) .Case("mipsel", mipsel) .Case("mips64", mips64) @@ -178,6 +201,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("systemz", systemz) .Case("tce", tce) .Case("thumb", thumb) + .Case("thumbeb", thumbeb) .Case("x86", x86) .Case("x86-64", x86_64) .Case("xcore", xcore) @@ -187,13 +211,14 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("amdil", amdil) .Case("spir", spir) .Case("spir64", spir64) + .Case("kalimba", kalimba) .Default(UnknownArch); } // Returns architecture name that is understood by the target assembler. const char *Triple::getArchNameForAssembler() { if (!isOSDarwin() && getVendor() != Triple::Apple) - return NULL; + return nullptr; return StringSwitch<const char*>(getArchName()) .Case("i386", "i386") @@ -206,6 +231,9 @@ const char *Triple::getArchNameForAssembler() { .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5") .Cases("armv6", "thumbv6", "armv6") .Cases("armv7", "thumbv7", "armv7") + .Case("armeb", "armeb") + .Case("arm64", "arm64") + .Case("arm64_be", "arm64") .Case("r600", "r600") .Case("nvptx", "nvptx") .Case("nvptx64", "nvptx64") @@ -213,7 +241,7 @@ const char *Triple::getArchNameForAssembler() { .Case("amdil", "amdil") .Case("spir", "spir") .Case("spir64", "spir64") - .Default(NULL); + .Default(nullptr); } static Triple::ArchType parseArch(StringRef ArchName) { @@ -226,12 +254,19 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Cases("powerpc64", "ppu", Triple::ppc64) .Case("powerpc64le", Triple::ppc64le) .Case("aarch64", Triple::aarch64) + .Case("aarch64_be", Triple::aarch64_be) .Cases("arm", "xscale", Triple::arm) // FIXME: It would be good to replace these with explicit names for all the // various suffixes supported. .StartsWith("armv", Triple::arm) + .Case("armeb", Triple::armeb) + .StartsWith("armebv", Triple::armeb) .Case("thumb", Triple::thumb) .StartsWith("thumbv", Triple::thumb) + .Case("thumbeb", Triple::thumbeb) + .StartsWith("thumbebv", Triple::thumbeb) + .Case("arm64", Triple::arm64) + .Case("arm64_be", Triple::arm64_be) .Case("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) .Cases("mipsel", "mipsallegrexel", Triple::mipsel) @@ -250,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); } @@ -262,7 +298,10 @@ static Triple::VendorType parseVendor(StringRef VendorName) { .Case("bgq", Triple::BGQ) .Case("fsl", Triple::Freescale) .Case("ibm", Triple::IBM) + .Case("img", Triple::ImaginationTechnologies) + .Case("mti", Triple::MipsTechnologies) .Case("nvidia", Triple::NVIDIA) + .Case("csr", Triple::CSR) .Default(Triple::UnknownVendor); } @@ -283,6 +322,7 @@ static Triple::OSType parseOS(StringRef OSName) { .StartsWith("openbsd", Triple::OpenBSD) .StartsWith("solaris", Triple::Solaris) .StartsWith("win32", Triple::Win32) + .StartsWith("windows", Triple::Win32) .StartsWith("haiku", Triple::Haiku) .StartsWith("minix", Triple::Minix) .StartsWith("rtems", Triple::RTEMS) @@ -297,17 +337,68 @@ static Triple::OSType parseOS(StringRef OSName) { static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { return StringSwitch<Triple::EnvironmentType>(EnvironmentName) + .StartsWith("eabihf", Triple::EABIHF) .StartsWith("eabi", Triple::EABI) .StartsWith("gnueabihf", Triple::GNUEABIHF) .StartsWith("gnueabi", Triple::GNUEABI) .StartsWith("gnux32", Triple::GNUX32) + .StartsWith("code16", Triple::CODE16) .StartsWith("gnu", Triple::GNU) - .StartsWith("macho", Triple::MachO) .StartsWith("android", Triple::Android) - .StartsWith("elf", Triple::ELF) + .StartsWith("msvc", Triple::MSVC) + .StartsWith("itanium", Triple::Itanium) + .StartsWith("cygnus", Triple::Cygnus) .Default(Triple::UnknownEnvironment); } +static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) { + return StringSwitch<Triple::ObjectFormatType>(EnvironmentName) + .EndsWith("coff", Triple::COFF) + .EndsWith("elf", Triple::ELF) + .EndsWith("macho", Triple::MachO) + .Default(Triple::UnknownObjectFormat); +} + +static Triple::SubArchType parseSubArch(StringRef SubArchName) { + return StringSwitch<Triple::SubArchType>(SubArchName) + .EndsWith("v8", Triple::ARMSubArch_v8) + .EndsWith("v8a", Triple::ARMSubArch_v8) + .EndsWith("v7", Triple::ARMSubArch_v7) + .EndsWith("v7a", Triple::ARMSubArch_v7) + .EndsWith("v7em", Triple::ARMSubArch_v7em) + .EndsWith("v7l", Triple::ARMSubArch_v7) + .EndsWith("v7m", Triple::ARMSubArch_v7m) + .EndsWith("v7r", Triple::ARMSubArch_v7) + .EndsWith("v7s", Triple::ARMSubArch_v7s) + .EndsWith("v6", Triple::ARMSubArch_v6) + .EndsWith("v6m", Triple::ARMSubArch_v6m) + .EndsWith("v6t2", Triple::ARMSubArch_v6t2) + .EndsWith("v5", Triple::ARMSubArch_v5) + .EndsWith("v5e", Triple::ARMSubArch_v5) + .EndsWith("v5t", Triple::ARMSubArch_v5) + .EndsWith("v5te", Triple::ARMSubArch_v5te) + .EndsWith("v4t", Triple::ARMSubArch_v4t) + .Default(Triple::NoSubArch); +} + +static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) { + switch (Kind) { + case Triple::UnknownObjectFormat: return ""; + case Triple::COFF: return "coff"; + case Triple::ELF: return "elf"; + case Triple::MachO: return "macho"; + } + llvm_unreachable("unknown object format type"); +} + +static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { + if (T.isOSDarwin()) + return Triple::MachO; + else if (T.isOSWindows()) + return Triple::COFF; + return Triple::ELF; +} + /// \brief Construct a triple from the string representation provided. /// /// This stores the string representation and parses the various pieces into @@ -315,9 +406,13 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { Triple::Triple(const Twine &Str) : Data(Str.str()), Arch(parseArch(getArchName())), + SubArch(parseSubArch(getArchName())), Vendor(parseVendor(getVendorName())), OS(parseOS(getOSName())), - Environment(parseEnvironment(getEnvironmentName())) { + Environment(parseEnvironment(getEnvironmentName())), + ObjectFormat(parseFormat(getEnvironmentName())) { + if (ObjectFormat == Triple::UnknownObjectFormat) + ObjectFormat = getDefaultFormat(*this); } /// \brief Construct a triple from string representations of the architecture, @@ -329,9 +424,11 @@ Triple::Triple(const Twine &Str) Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), Arch(parseArch(ArchStr.str())), + SubArch(parseSubArch(ArchStr.str())), Vendor(parseVendor(VendorStr.str())), OS(parseOS(OSStr.str())), - Environment() { + Environment(), ObjectFormat(Triple::UnknownObjectFormat) { + ObjectFormat = getDefaultFormat(*this); } /// \brief Construct a triple from string representations of the architecture, @@ -344,9 +441,13 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + EnvironmentStr).str()), Arch(parseArch(ArchStr.str())), + SubArch(parseSubArch(ArchStr.str())), Vendor(parseVendor(VendorStr.str())), OS(parseOS(OSStr.str())), - Environment(parseEnvironment(EnvironmentStr.str())) { + Environment(parseEnvironment(EnvironmentStr.str())), + ObjectFormat(parseFormat(EnvironmentStr.str())) { + if (ObjectFormat == Triple::UnknownObjectFormat) + ObjectFormat = getDefaultFormat(*this); } std::string Triple::normalize(StringRef Str) { @@ -371,6 +472,9 @@ std::string Triple::normalize(StringRef Str) { EnvironmentType Environment = UnknownEnvironment; if (Components.size() > 3) Environment = parseEnvironment(Components[3]); + ObjectFormatType ObjectFormat = UnknownObjectFormat; + if (Components.size() > 4) + ObjectFormat = parseFormat(Components[4]); // Note which components are already in their final position. These will not // be moved. @@ -412,6 +516,10 @@ std::string Triple::normalize(StringRef Str) { case 3: Environment = parseEnvironment(Comp); Valid = Environment != UnknownEnvironment; + if (!Valid) { + ObjectFormat = parseFormat(Comp); + Valid = ObjectFormat != UnknownObjectFormat; + } break; } if (!Valid) @@ -474,6 +582,32 @@ std::string Triple::normalize(StringRef Str) { // Special case logic goes here. At this point Arch, Vendor and OS have the // correct values for the computed components. + if (OS == Triple::Win32) { + Components.resize(4); + Components[2] = "windows"; + if (Environment == UnknownEnvironment) { + if (ObjectFormat == UnknownObjectFormat || ObjectFormat == Triple::COFF) + Components[3] = "msvc"; + else + Components[3] = getObjectFormatTypeName(ObjectFormat); + } + } else if (OS == Triple::MinGW32) { + Components.resize(4); + Components[2] = "windows"; + Components[3] = "gnu"; + } else if (OS == Triple::Cygwin) { + Components.resize(4); + Components[2] = "windows"; + Components[3] = "cygnus"; + } + if (OS == Triple::MinGW32 || OS == Triple::Cygwin || + (OS == Triple::Win32 && Environment != UnknownEnvironment)) { + if (ObjectFormat != UnknownObjectFormat && ObjectFormat != Triple::COFF) { + Components.resize(5); + Components[4] = getObjectFormatTypeName(ObjectFormat); + } + } + // Stick the corrected components back together to form the normalized string. std::string Normalized; for (unsigned i = 0, e = Components.size(); i != e; ++i) { @@ -600,15 +734,15 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor, // the clang driver combines OS X and IOS support into a common Darwin // toolchain that wants to know the iOS version number even when targeting // OS X. - Major = 3; + Major = 5; Minor = 0; Micro = 0; break; case IOS: getOSVersion(Major, Minor, Micro); - // Default to 3.0. + // Default to 5.0 (or 7.0 for arm64). if (Major == 0) - Major = 3; + Major = (getArch() == arm64) ? 7 : 5; break; } } @@ -633,6 +767,14 @@ void Triple::setEnvironment(EnvironmentType Kind) { setEnvironmentName(getEnvironmentTypeName(Kind)); } +void Triple::setObjectFormat(ObjectFormatType Kind) { + if (Environment == UnknownEnvironment) + return setEnvironmentName(getObjectFormatTypeName(Kind)); + + setEnvironmentName((getEnvironmentTypeName(Environment) + Twine("-") + + getObjectFormatTypeName(Kind)).str()); +} + void Triple::setArchName(StringRef Str) { // Work around a miscompilation bug for Twines in gcc 4.0.3. SmallString<64> Triple; @@ -675,6 +817,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::amdil: case llvm::Triple::arm: + case llvm::Triple::armeb: case llvm::Triple::hexagon: case llvm::Triple::le32: case llvm::Triple::mips: @@ -685,12 +828,17 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { case llvm::Triple::sparc: case llvm::Triple::tce: case llvm::Triple::thumb: + case llvm::Triple::thumbeb: case llvm::Triple::x86: case llvm::Triple::xcore: case llvm::Triple::spir: + case llvm::Triple::kalimba: return 32; + case llvm::Triple::arm64: + case llvm::Triple::arm64_be: case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::nvptx64: @@ -722,6 +870,9 @@ Triple Triple::get32BitArchVariant() const { switch (getArch()) { case Triple::UnknownArch: case Triple::aarch64: + case Triple::aarch64_be: + case Triple::arm64: + case Triple::arm64_be: case Triple::msp430: case Triple::systemz: case Triple::ppc64le: @@ -731,7 +882,9 @@ Triple Triple::get32BitArchVariant() const { case Triple::amdil: case Triple::spir: case Triple::arm: + case Triple::armeb: case Triple::hexagon: + case Triple::kalimba: case Triple::le32: case Triple::mips: case Triple::mipsel: @@ -741,6 +894,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::sparc: case Triple::tce: case Triple::thumb: + case Triple::thumbeb: case Triple::x86: case Triple::xcore: // Already 32-bit. @@ -749,7 +903,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::mips64: T.setArch(Triple::mips); break; case Triple::mips64el: T.setArch(Triple::mipsel); break; case Triple::nvptx64: T.setArch(Triple::nvptx); break; - case Triple::ppc64: T.setArch(Triple::ppc); break; + case Triple::ppc64: T.setArch(Triple::ppc); break; case Triple::sparcv9: T.setArch(Triple::sparc); break; case Triple::x86_64: T.setArch(Triple::x86); break; case Triple::spir64: T.setArch(Triple::spir); break; @@ -763,17 +917,21 @@ Triple Triple::get64BitArchVariant() const { case Triple::UnknownArch: case Triple::amdil: case Triple::arm: + case Triple::armeb: case Triple::hexagon: + case Triple::kalimba: case Triple::le32: case Triple::msp430: case Triple::r600: case Triple::tce: case Triple::thumb: + case Triple::thumbeb: case Triple::xcore: T.setArch(UnknownArch); break; case Triple::aarch64: + case Triple::aarch64_be: case Triple::spir64: case Triple::mips64: case Triple::mips64el: @@ -783,6 +941,8 @@ Triple Triple::get64BitArchVariant() const { case Triple::sparcv9: case Triple::systemz: case Triple::x86_64: + case Triple::arm64: + case Triple::arm64_be: // Already 64-bit. break; @@ -796,3 +956,86 @@ Triple Triple::get64BitArchVariant() const { } return T; } + +// FIXME: tblgen this. +const char *Triple::getARMCPUForArch(StringRef MArch) const { + if (MArch.empty()) + MArch = getArchName(); + + switch (getOS()) { + case llvm::Triple::FreeBSD: + case llvm::Triple::NetBSD: + if (MArch == "armv6") + return "arm1176jzf-s"; + break; + case llvm::Triple::Win32: + // FIXME: this is invalid for WindowsCE + return "cortex-a9"; + default: + break; + } + + const char *result = nullptr; + size_t offset = StringRef::npos; + if (MArch.startswith("arm")) + offset = 3; + if (MArch.startswith("thumb")) + offset = 5; + if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb") + offset += 2; + if (offset != StringRef::npos) + result = llvm::StringSwitch<const char *>(MArch.substr(offset)) + .Cases("v2", "v2a", "arm2") + .Case("v3", "arm6") + .Case("v3m", "arm7m") + .Case("v4", "strongarm") + .Case("v4t", "arm7tdmi") + .Cases("v5", "v5t", "arm10tdmi") + .Cases("v5e", "v5te", "arm1022e") + .Case("v5tej", "arm926ej-s") + .Cases("v6", "v6k", "arm1136jf-s") + .Case("v6j", "arm1136j-s") + .Cases("v6z", "v6zk", "arm1176jzf-s") + .Case("v6t2", "arm1156t2-s") + .Cases("v6m", "v6-m", "cortex-m0") + .Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8") + .Cases("v7s", "v7-s", "swift") + .Cases("v7r", "v7-r", "cortex-r4") + .Cases("v7m", "v7-m", "cortex-m3") + .Cases("v7em", "v7e-m", "cortex-m4") + .Cases("v8", "v8a", "v8-a", "cortex-a53") + .Default(nullptr); + else + result = llvm::StringSwitch<const char *>(MArch) + .Case("ep9312", "ep9312") + .Case("iwmmxt", "iwmmxt") + .Case("xscale", "xscale") + .Default(nullptr); + + if (result) + return result; + + // If all else failed, return the most base CPU with thumb interworking + // supported by LLVM. + // FIXME: Should warn once that we're falling back. + switch (getOS()) { + case llvm::Triple::NetBSD: + switch (getEnvironment()) { + case llvm::Triple::GNUEABIHF: + case llvm::Triple::GNUEABI: + case llvm::Triple::EABIHF: + case llvm::Triple::EABI: + return "arm926ej-s"; + default: + return "strongarm"; + } + default: + switch (getEnvironment()) { + case llvm::Triple::EABIHF: + case llvm::Triple::GNUEABIHF: + return "arm1176jzf-s"; + default: + return "arm7tdmi"; + } + } +} diff --git a/contrib/llvm/lib/Support/Twine.cpp b/contrib/llvm/lib/Support/Twine.cpp index 3d04bc3..56ed964 100644 --- a/contrib/llvm/lib/Support/Twine.cpp +++ b/contrib/llvm/lib/Support/Twine.cpp @@ -163,9 +163,9 @@ void Twine::printRepr(raw_ostream &OS) const { } void Twine::dump() const { - print(llvm::dbgs()); + print(dbgs()); } void Twine::dumpRepr() const { - printRepr(llvm::dbgs()); + printRepr(dbgs()); } diff --git a/contrib/llvm/lib/Support/Unix/Host.inc b/contrib/llvm/lib/Support/Unix/Host.inc index 7f79db0..7941166 100644 --- a/contrib/llvm/lib/Support/Unix/Host.inc +++ b/contrib/llvm/lib/Support/Unix/Host.inc @@ -64,6 +64,6 @@ std::string sys::getDefaultTargetTriple() { Triple += getOSVersion(); } - return Triple; + return Triple::normalize(Triple); } #endif // __FreeBSD__ diff --git a/contrib/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm/lib/Support/Unix/Memory.inc index dcfd76e..c9d89a8 100644 --- a/contrib/llvm/lib/Support/Unix/Memory.inc +++ b/contrib/llvm/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; @@ -121,9 +121,9 @@ Memory::allocateMappedMemory(size_t NumBytes, Protect, MMFlags, fd, 0); if (Addr == MAP_FAILED) { if (NearBlock) //Try again without a near hint - return allocateMappedMemory(NumBytes, 0, PFlags, EC); + 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 == 0 || M.Size == 0) - return error_code::success(); + if (M.Address == nullptr || M.Size == 0) + 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 = 0; + 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 == 0 || M.Size == 0) - return error_code::success(); + if (M.Address == nullptr || M.Size == 0) + 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 @@ -203,9 +203,9 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, ; void* start = NearBlock ? (unsigned char*)NearBlock->base() + - NearBlock->size() : 0; + NearBlock->size() : nullptr; -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC, flags, fd, 0); #else @@ -214,13 +214,13 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, #endif if (pa == MAP_FAILED) { if (NearBlock) //Try again without a near hint - return AllocateRWX(NumBytes, 0); + return AllocateRWX(NumBytes, nullptr); MakeErrMsg(ErrMsg, "Can't allocate RWX Memory"); return MemoryBlock(); } -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa, (vm_size_t)(PageSize*NumPages), 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); @@ -246,14 +246,14 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, } bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - if (M.Address == 0 || M.Size == 0) return false; + if (M.Address == nullptr || M.Size == 0) return false; if (0 != ::munmap(M.Address, M.Size)) return MakeErrMsg(ErrMsg, "Can't release RWX Memory"); return false; } bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) if (M.Address == 0 || M.Size == 0) return false; Memory::InvalidateInstructionCache(M.Address, M.Size); kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, @@ -265,7 +265,7 @@ bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) { } bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) if (M.Address == 0 || M.Size == 0) return false; Memory::InvalidateInstructionCache(M.Address, M.Size); kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, @@ -280,7 +280,7 @@ bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { } bool Memory::setRangeWritable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, (vm_size_t)Size, 0, VM_PROT_READ | VM_PROT_WRITE); @@ -291,7 +291,7 @@ bool Memory::setRangeWritable(const void *Addr, size_t Size) { } bool Memory::setRangeExecutable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && defined(__arm__) +#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, (vm_size_t)Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); @@ -311,7 +311,8 @@ void Memory::InvalidateInstructionCache(const void *Addr, #if defined(__APPLE__) # if (defined(__POWERPC__) || defined (__ppc__) || \ - defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__) + defined(_POWER) || defined(_ARCH_PPC) || defined(__arm__) || \ + defined(__arm64__)) sys_icache_invalidate(const_cast<void *>(Addr), Len); # endif @@ -332,7 +333,7 @@ void Memory::InvalidateInstructionCache(const void *Addr, for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) asm volatile("icbi 0, %0" : : "r"(Line)); asm volatile("isync"); -# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__) && !defined(__FreeBSD__) +# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__) // FIXME: Can we safely always call this for __GNUC__ everywhere? const char *Start = static_cast<const char *>(Addr); const char *End = Start + Len; diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc index c9dc871..623547a 100644 --- a/contrib/llvm/lib/Support/Unix/Path.inc +++ b/contrib/llvm/lib/Support/Unix/Path.inc @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "Unix.h" -#include "llvm/Support/Process.h" #include <limits.h> #include <stdio.h> #if HAVE_SYS_STAT_H @@ -86,95 +85,22 @@ namespace { operator int() const {return FileDescriptor;} }; +} - error_code TempDir(SmallVectorImpl<char> &result) { - // FIXME: Don't use TMPDIR if program is SUID or SGID enabled. - const char *dir = 0; - (dir = std::getenv("TMPDIR" )) || - (dir = std::getenv("TMP" )) || - (dir = std::getenv("TEMP" )) || - (dir = std::getenv("TEMPDIR")) || +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")) || + (dir = std::getenv("TEMP")) || (dir = std::getenv("TEMPDIR")) || #ifdef P_tmpdir - (dir = P_tmpdir) || + (dir = P_tmpdir) || #endif - (dir = "/tmp"); - - result.clear(); - StringRef d(dir); - result.append(d.begin(), d.end()); - return error_code::success(); - } -} - -static error_code createUniqueEntity(const Twine &Model, int &ResultFD, - SmallVectorImpl<char> &ResultPath, - bool MakeAbsolute, unsigned Mode, - FSEntity Type) { - SmallString<128> ModelStorage; - Model.toVector(ModelStorage); - - if (MakeAbsolute) { - // Make model absolute by prepending a temp directory if it's not already. - bool absolute = sys::path::is_absolute(Twine(ModelStorage)); - if (!absolute) { - SmallString<128> TDir; - if (error_code ec = TempDir(TDir)) return ec; - sys::path::append(TDir, Twine(ModelStorage)); - ModelStorage.swap(TDir); - } - } - - // From here on, DO NOT modify model. It may be needed if the randomly chosen - // path already exists. - ResultPath = ModelStorage; - // Null terminate. - ResultPath.push_back(0); - ResultPath.pop_back(); - -retry_random_path: - // Replace '%' with random chars. - for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) { - if (ModelStorage[i] == '%') - ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15]; - } - - // Try to open + create the file. - switch (Type) { - case FS_File: { - int RandomFD = ::open(ResultPath.begin(), O_RDWR | O_CREAT | O_EXCL, Mode); - if (RandomFD == -1) { - int SavedErrno = errno; - // If the file existed, try again, otherwise, error. - if (SavedErrno == errc::file_exists) - goto retry_random_path; - return error_code(SavedErrno, system_category()); - } - - ResultFD = RandomFD; - return error_code::success(); - } - - case FS_Name: { - bool Exists; - error_code EC = sys::fs::exists(ResultPath.begin(), Exists); - if (EC) - return EC; - if (Exists) - goto retry_random_path; - return error_code::success(); - } + (dir = "/tmp"); - case FS_Dir: { - bool Existed; - error_code EC = sys::fs::create_directory(ResultPath.begin(), Existed); - if (EC) - return EC; - if (Existed) - goto retry_random_path; - return error_code::success(); - } - } - llvm_unreachable("Invalid Type"); + result.clear(); + StringRef d(dir); + result.append(d.begin(), d.end()); + return std::error_code(); } namespace llvm { @@ -184,15 +110,15 @@ namespace fs { defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \ defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__) static int -test_dir(char buf[PATH_MAX], char ret[PATH_MAX], - const char *dir, const char *bin) -{ +test_dir(char ret[PATH_MAX], const char *dir, const char *bin) +{ struct stat sb; + char fullpath[PATH_MAX]; - snprintf(buf, PATH_MAX, "%s/%s", dir, bin); - if (realpath(buf, ret) == NULL) + snprintf(fullpath, PATH_MAX, "%s/%s", dir, bin); + if (realpath(fullpath, ret) == NULL) return (1); - if (stat(buf, &sb) != 0) + if (stat(fullpath, &sb) != 0) return (1); return (0); @@ -201,20 +127,21 @@ test_dir(char buf[PATH_MAX], char ret[PATH_MAX], static char * getprogpath(char ret[PATH_MAX], const char *bin) { - char *pv, *s, *t, buf[PATH_MAX]; + char *pv, *s, *t; /* First approach: absolute path. */ if (bin[0] == '/') { - if (test_dir(buf, ret, "/", bin) == 0) + if (test_dir(ret, "/", bin) == 0) return (ret); return (NULL); } /* Second approach: relative path. */ if (strchr(bin, '/') != NULL) { - if (getcwd(buf, PATH_MAX) == NULL) + char cwd[PATH_MAX]; + if (getcwd(cwd, PATH_MAX) == NULL) return (NULL); - if (test_dir(buf, ret, buf, bin) == 0) + if (test_dir(ret, cwd, bin) == 0) return (ret); return (NULL); } @@ -226,7 +153,7 @@ getprogpath(char ret[PATH_MAX], const char *bin) if (pv == NULL) return (NULL); while ((t = strsep(&s, ":")) != NULL) { - if (test_dir(buf, ret, t, bin) == 0) { + if (test_dir(ret, t, bin) == 0) { free(pv); return (ret); } @@ -298,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"); @@ -308,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 @@ -319,10 +246,10 @@ error_code current_path(SmallVectorImpl<char> &result) { #endif while (true) { - if (::getcwd(result.data(), result.capacity()) == 0) { + 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 @@ -330,37 +257,37 @@ 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 &existed) { +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) - return error_code(errno, system_category()); - existed = true; - } else - existed = false; + if (errno != EEXIST || !IgnoreExisting) + return std::error_code(errno, std::generic_category()); + } - return error_code::success(); + return std::error_code(); } -error_code create_hard_link(const Twine &to, const Twine &from) { - // Get arguments. - SmallString<128> from_storage; - SmallString<128> to_storage; - StringRef f = from.toNullTerminatedStringRef(from_storage); - StringRef t = to.toNullTerminatedStringRef(to_storage); - - if (::link(t.begin(), f.begin()) == -1) - return error_code(errno, system_category()); - - return error_code::success(); +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; + if (PN < PE && *PN == '\\') + ++PI; // increment once, the for loop will move over the escaped slash + else + *PI = '/'; + } + } + return std::error_code(); } -error_code create_symlink(const Twine &to, const Twine &from) { +// Note that we are using symbolic link because hard links are not supported by +// all filesystems (SMB doesn't). +std::error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -368,21 +295,20 @@ error_code create_symlink(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 &existed) { +std::error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallString<128> path_storage; StringRef p = path.toNullTerminatedStringRef(path_storage); struct stat buf; - if (stat(p.begin(), &buf) != 0) { - if (errno != errc::no_such_file_or_directory) - return error_code(errno, system_category()); - existed = false; - return error_code::success(); + if (lstat(p.begin(), &buf) != 0) { + 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 @@ -390,20 +316,18 @@ error_code remove(const Twine &path, bool &existed) { // check ensures that what we're trying to erase is a regular file. It // effectively prevents LLVM from erasing things like /dev/null, any block // special file, or other things that aren't "regular" files. - if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) + if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode)) return make_error_code(errc::operation_not_permitted); if (::remove(p.begin()) == -1) { - if (errno != errc::no_such_file_or_directory) - return error_code(errno, system_category()); - existed = false; - } else - existed = true; + 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; @@ -411,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) { @@ -466,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 @@ -505,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); @@ -517,33 +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.toPosixTime(); + Times[0].tv_sec = Time.toEpochTime(); Times[0].tv_nsec = 0; Times[1] = Times[0]; if (::futimens(FD, Times)) + return std::error_code(errno, std::generic_category()); + return std::error_code(); #elif defined(HAVE_FUTIMES) timeval Times[2]; - Times[0].tv_sec = Time.toPosixTime(); + Times[0].tv_sec = Time.toEpochTime(); Times[0].tv_usec = 0; Times[1] = Times[0]; if (::futimes(FD, Times)) + return std::error_code(errno, std::generic_category()); + return std::error_code(); #else -#error Missing futimes() and futimens() +#warning Missing futimes() and futimens() + return make_error_code(errc::function_not_supported); #endif - return error_code(errno, system_category()); - return error_code::success(); } -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(); @@ -551,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) @@ -559,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; @@ -567,17 +496,17 @@ error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { #ifdef MAP_FILE flags |= MAP_FILE; #endif - Mapping = ::mmap(0, Size, prot, flags, FD, Offset); + 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() { @@ -592,13 +521,13 @@ 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; } ec = init(ofd, true, offset); if (ec) - Mapping = 0; + Mapping = nullptr; } mapped_file_region::mapped_file_region(int fd, @@ -606,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() { @@ -618,7 +547,7 @@ mapped_file_region::mapped_file_region(int fd, ec = init(fd, closefd, offset); if (ec) - Mapping = 0; + Mapping = nullptr; } mapped_file_region::~mapped_file_region() { @@ -626,12 +555,10 @@ mapped_file_region::~mapped_file_region() { ::munmap(Mapping, Size); } -#if LLVM_HAS_RVALUE_REFERENCES mapped_file_region::mapped_file_region(mapped_file_region &&other) : Mode(other.Mode), Size(other.Size), Mapping(other.Mapping) { - other.Mapping = 0; + other.Mapping = nullptr; } -#endif mapped_file_region::mapmode mapped_file_region::flags() const { assert(Mapping && "Mapping failed but used anyway!"); @@ -645,7 +572,7 @@ uint64_t mapped_file_region::size() const { char *mapped_file_region::data() const { assert(Mapping && "Mapping failed but used anyway!"); - assert(Mode != readonly && "Cannot get non const data for readonly mapping!"); + assert(Mode != readonly && "Cannot get non-const data for readonly mapping!"); return reinterpret_cast<char*>(Mapping); } @@ -658,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 == 0) - return error_code(errno, system_category()); + if (!directory) + return std::error_code(errno, std::generic_category()); it.IterationHandle = reinterpret_cast<intptr_t>(directory); // Add something for replace_filename to replace. @@ -672,20 +599,20 @@ 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 == 0 && errno != 0) { - return error_code(errno, system_category()); - } else if (cur_dir != 0) { + if (cur_dir == nullptr && errno != 0) { + 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] == '.') || (name.size() == 2 && name[0] == '.' && name[1] == '.')) @@ -694,86 +621,31 @@ 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 == 0) - 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(); + return std::error_code(); } -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(0, 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(); -} - -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)) && "Cannot specify both 'excl' and 'append' file creation flags!"); - int OpenFlags = O_WRONLY | O_CREAT; + int OpenFlags = O_CREAT; + + if (Flags & F_RW) + OpenFlags |= O_RDWR; + else + OpenFlags |= O_WRONLY; if (Flags & F_Append) OpenFlags |= O_APPEND; @@ -787,11 +659,26 @@ 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 + +namespace path { + +bool home_directory(SmallVectorImpl<char> &result) { + if (char *RequestedDir = getenv("HOME")) { + result.clear(); + result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); + return true; + } + + return false; +} + +} // end namespace path + } // end namespace sys } // end namespace llvm diff --git a/contrib/llvm/lib/Support/Unix/Process.inc b/contrib/llvm/lib/Support/Unix/Process.inc index c5778e7..d2c5dbc 100644 --- a/contrib/llvm/lib/Support/Unix/Process.inc +++ b/contrib/llvm/lib/Support/Unix/Process.inc @@ -47,7 +47,6 @@ using namespace llvm; using namespace sys; - process::id_type self_process::get_id() { return getpid(); } @@ -135,7 +134,7 @@ size_t Process::GetMallocUsage() { void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time, TimeValue &sys_time) { elapsed = TimeValue::now(); - llvm::tie(user_time, sys_time) = getRUsageTimes(); + std::tie(user_time, sys_time) = getRUsageTimes(); } #if defined(HAVE_MACH_MACH_H) && !defined(__GNU__) @@ -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() { @@ -270,7 +270,7 @@ static bool terminalHasColors(int fd) { MutexGuard G(M); int errret = 0; - if (setupterm((char *)0, fd, &errret) != 0) + if (setupterm((char *)nullptr, fd, &errret) != 0) // Regardless of why, if we can't get terminfo, we shouldn't try to print // colors. return false; @@ -292,7 +292,7 @@ static bool terminalHasColors(int fd) { // Now extract the structure allocated by setupterm and free its memory // through a really silly dance. - struct term *termp = set_curterm((struct term *)0); + struct term *termp = set_curterm((struct term *)nullptr); (void)del_curterm(termp); // Drop any errors here. // Return true if we found a color capabilities for the current terminal. @@ -343,7 +343,7 @@ const char *Process::ResetColor() { return "\033[0m"; } -#if !defined(HAVE_ARC4RANDOM) +#if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM static unsigned GetRandomNumberSeed() { // Attempt to get the initial seed from /dev/urandom, if possible. if (FILE *RandomSource = ::fopen("/dev/urandom", "r")) { @@ -364,7 +364,7 @@ static unsigned GetRandomNumberSeed() { #endif unsigned llvm::sys::Process::GetRandomNumber() { -#if defined(HAVE_ARC4RANDOM) +#if defined(HAVE_DECL_ARC4RANDOM) && HAVE_DECL_ARC4RANDOM return arc4random(); #else static int x = (::srand(GetRandomNumberSeed()), 0); diff --git a/contrib/llvm/lib/Support/Unix/Program.inc b/contrib/llvm/lib/Support/Unix/Program.inc index 78b2971..06a33cd 100644 --- a/contrib/llvm/lib/Support/Unix/Program.inc +++ b/contrib/llvm/lib/Support/Unix/Program.inc @@ -48,6 +48,7 @@ #endif namespace llvm { + using namespace sys; ProcessInfo::ProcessInfo() : Pid(0), ReturnCode(0) {} @@ -70,7 +71,7 @@ sys::FindProgramByName(const std::string& progName) { // Get the path. If its empty, we can't do anything to find it. const char *PathStr = getenv("PATH"); - if (PathStr == 0) + if (!PathStr) return ""; // Now we have a colon separated list of directories to search; try them. @@ -99,7 +100,7 @@ sys::FindProgramByName(const std::string& progName) { } static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) { - if (Path == 0) // Noop + if (!Path) // Noop return false; std::string File; if (Path->empty()) @@ -129,7 +130,7 @@ static bool RedirectIO(const StringRef *Path, int FD, std::string* ErrMsg) { #ifdef HAVE_POSIX_SPAWN static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg, posix_spawn_file_actions_t *FileActions) { - if (Path == 0) // Noop + if (!Path) // Noop return false; const char *File; if (Path->empty()) @@ -195,7 +196,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, #ifdef HAVE_POSIX_SPAWN if (memoryLimit == 0) { posix_spawn_file_actions_t FileActionsStore; - posix_spawn_file_actions_t *FileActions = 0; + posix_spawn_file_actions_t *FileActions = nullptr; // If we call posix_spawn_file_actions_addopen we have to make sure the // c strings we pass to it stay alive until the call to posix_spawn, @@ -203,7 +204,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, std::string RedirectsStorage[3]; if (redirects) { - std::string *RedirectsStr[3] = {0, 0, 0}; + std::string *RedirectsStr[3] = {nullptr, nullptr, nullptr}; for (int I = 0; I < 3; ++I) { if (redirects[I]) { RedirectsStorage[I] = *redirects[I]; @@ -218,7 +219,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, if (RedirectIO_PS(RedirectsStr[0], 0, ErrMsg, FileActions) || RedirectIO_PS(RedirectsStr[1], 1, ErrMsg, FileActions)) return false; - if (redirects[1] == 0 || redirects[2] == 0 || + if (redirects[1] == nullptr || redirects[2] == nullptr || *redirects[1] != *redirects[2]) { // Just redirect stderr if (RedirectIO_PS(RedirectsStr[2], 2, ErrMsg, FileActions)) @@ -242,8 +243,9 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, // Explicitly initialized to prevent what appears to be a valgrind false // positive. pid_t PID = 0; - int Err = posix_spawn(&PID, Program.str().c_str(), FileActions, /*attrp*/0, - const_cast<char **>(args), const_cast<char **>(envp)); + int Err = posix_spawn(&PID, Program.str().c_str(), FileActions, + /*attrp*/nullptr, const_cast<char **>(args), + const_cast<char **>(envp)); if (FileActions) posix_spawn_file_actions_destroy(FileActions); @@ -294,7 +296,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, // Execute! std::string PathStr = Program; - if (envp != 0) + if (envp != nullptr) execve(PathStr.c_str(), const_cast<char **>(args), const_cast<char **>(envp)); @@ -348,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. @@ -360,7 +366,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, // Turn off the alarm and restore the signal handler alarm(0); - sigaction(SIGALRM, &Old, 0); + sigaction(SIGALRM, &Old, nullptr); // Wait for child to die if (wait(&status) != ChildPid) @@ -381,7 +387,7 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, // We exited normally without timeout, so turn off the timer. if (SecondsToWait && !WaitUntilTerminates) { alarm(0); - sigaction(SIGALRM, &Old, 0); + sigaction(SIGALRM, &Old, nullptr); } // Return the proper exit status. Detect error conditions @@ -418,24 +424,20 @@ ProcessInfo sys::Wait(const ProcessInfo &PI, unsigned SecondsToWait, #else if (ErrMsg) *ErrMsg = "Program::Wait is not implemented on this platform yet!"; + ProcessInfo WaitResult; WaitResult.ReturnCode = -2; #endif return WaitResult; } -error_code sys::ChangeStdinToBinary(){ - // Do nothing, as Unix doesn't differentiate between text and binary. - return make_error_code(errc::success); -} - -error_code sys::ChangeStdoutToBinary(){ + 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::ChangeStderrToBinary(){ + 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/contrib/llvm/lib/Support/Unix/RWMutex.inc b/contrib/llvm/lib/Support/Unix/RWMutex.inc index 40e87ff..edcbd52 100644 --- a/contrib/llvm/lib/Support/Unix/RWMutex.inc +++ b/contrib/llvm/lib/Support/Unix/RWMutex.inc @@ -16,28 +16,36 @@ //=== is guaranteed to work on *all* UNIX variants. //===----------------------------------------------------------------------===// +#include "llvm/Support/Mutex.h" + namespace llvm { using namespace sys; -RWMutexImpl::RWMutexImpl() { } +// This naive implementation treats readers the same as writers. This +// will therefore deadlock if a thread tries to acquire a read lock +// multiple times. + +RWMutexImpl::RWMutexImpl() : data_(new Mutex(false)) { } -RWMutexImpl::~RWMutexImpl() { } +RWMutexImpl::~RWMutexImpl() { + delete static_cast<Mutex *>(data_); +} bool RWMutexImpl::reader_acquire() { - return true; + return static_cast<Mutex *>(data_)->acquire(); } bool RWMutexImpl::reader_release() { - return true; + return static_cast<Mutex *>(data_)->release(); } bool RWMutexImpl::writer_acquire() { - return true; + return static_cast<Mutex *>(data_)->acquire(); } bool RWMutexImpl::writer_release() { - return true; + return static_cast<Mutex *>(data_)->release(); } } diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc index b4c78d6..1841fea 100644 --- a/contrib/llvm/lib/Support/Unix/Signals.inc +++ b/contrib/llvm/lib/Support/Unix/Signals.inc @@ -44,7 +44,7 @@ static RETSIGTYPE SignalHandler(int Sig); // defined below. static SmartMutex<true> SignalsMutex; /// InterruptFunction - The function to call if ctrl-c is pressed. -static void (*InterruptFunction)() = 0; +static void (*InterruptFunction)() = nullptr; static std::vector<std::string> FilesToRemove; static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun; @@ -55,7 +55,7 @@ static std::vector<std::pair<void(*)(void*), void*> > CallBacksToRun; static const int IntSigs[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2 }; -static const int *const IntSigsEnd = array_endof(IntSigs); +static const int *const IntSigsEnd = std::end(IntSigs); // KillSigs - Signals that represent that we have a bug, and our prompt // termination has been ordered. @@ -74,7 +74,7 @@ static const int KillSigs[] = { , SIGEMT #endif }; -static const int *const KillSigsEnd = array_endof(KillSigs); +static const int *const KillSigsEnd = std::end(KillSigs); static unsigned NumRegisteredSignals = 0; static struct { @@ -113,7 +113,7 @@ static void UnregisterHandlers() { // Restore all of the signal handlers to how they were before we showed up. for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i) sigaction(RegisteredSignalInfo[i].SigNo, - &RegisteredSignalInfo[i].SA, 0); + &RegisteredSignalInfo[i].SA, nullptr); NumRegisteredSignals = 0; } @@ -160,7 +160,7 @@ static RETSIGTYPE SignalHandler(int Sig) { // Unmask all potentially blocked kill signals. sigset_t SigMask; sigfillset(&SigMask); - sigprocmask(SIG_UNBLOCK, &SigMask, 0); + sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); SignalsMutex.acquire(); RemoveFilesToRemove(); @@ -169,7 +169,7 @@ static RETSIGTYPE SignalHandler(int Sig) { if (InterruptFunction) { void (*IF)() = InterruptFunction; SignalsMutex.release(); - InterruptFunction = 0; + InterruptFunction = nullptr; IF(); // run the interrupt function. return; } @@ -212,7 +212,7 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) { bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { SignalsMutex.acquire(); - std::string *OldPtr = FilesToRemove.empty() ? 0 : &FilesToRemove[0]; + std::string *OldPtr = FilesToRemove.empty() ? nullptr : &FilesToRemove[0]; FilesToRemove.push_back(Filename); // We want to call 'c_str()' on every std::string in this vector so that if @@ -279,8 +279,8 @@ void llvm::sys::PrintStackTrace(FILE *FD) { const char* name = strrchr(dlinfo.dli_fname, '/'); int nwidth; - if (name == NULL) nwidth = strlen(dlinfo.dli_fname); - else nwidth = strlen(name) - 1; + if (!name) nwidth = strlen(dlinfo.dli_fname); + else nwidth = strlen(name) - 1; if (nwidth > width) width = nwidth; } @@ -292,22 +292,22 @@ void llvm::sys::PrintStackTrace(FILE *FD) { fprintf(FD, "%-2d", i); const char* name = strrchr(dlinfo.dli_fname, '/'); - if (name == NULL) fprintf(FD, " %-*s", width, dlinfo.dli_fname); - else fprintf(FD, " %-*s", width, name+1); + if (!name) fprintf(FD, " %-*s", width, dlinfo.dli_fname); + else fprintf(FD, " %-*s", width, name+1); fprintf(FD, " %#0*lx", (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); - if (dlinfo.dli_sname != NULL) { + if (dlinfo.dli_sname != nullptr) { fputc(' ', FD); # if HAVE_CXXABI_H int res; - char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res); + char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res); # else char* d = NULL; # endif - if (d == NULL) fputs(dlinfo.dli_sname, FD); - else fputs(d, FD); + if (!d) fputs(dlinfo.dli_sname, FD); + else fputs(d, FD); free(d); // FIXME: When we move to C++11, use %t length modifier. It's not in @@ -331,7 +331,7 @@ static void PrintStackTraceSignalHandler(void *) { /// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or /// SIGSEGV) is delivered to the process, print a stack trace and then exit. void llvm::sys::PrintStackTraceOnErrorSignal() { - AddSignalHandler(PrintStackTraceSignalHandler, 0); + AddSignalHandler(PrintStackTraceSignalHandler, nullptr); #if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES) // Environment variable to disable any kind of crash dialog. diff --git a/contrib/llvm/lib/Support/Unix/TimeValue.inc b/contrib/llvm/lib/Support/Unix/TimeValue.inc index 80532b0..7d4acf7 100644 --- a/contrib/llvm/lib/Support/Unix/TimeValue.inc +++ b/contrib/llvm/lib/Support/Unix/TimeValue.inc @@ -26,15 +26,17 @@ std::string TimeValue::str() const { struct tm Storage; struct tm *LT = ::localtime_r(&OurTime, &Storage); assert(LT); - char Buffer[25]; - strftime(Buffer, 25, "%b %e %H:%M %Y", LT); - return std::string(Buffer); + char Buffer1[sizeof("YYYY-MM-DD HH:MM:SS")]; + strftime(Buffer1, sizeof(Buffer1), "%Y-%m-%d %H:%M:%S", LT); + char Buffer2[sizeof("YYYY-MM-DD HH:MM:SS.MMMUUUNNN")]; + snprintf(Buffer2, sizeof(Buffer2), "%s.%.9u", Buffer1, this->nanoseconds()); + return std::string(Buffer2); } TimeValue TimeValue::now() { struct timeval the_time; timerclear(&the_time); - if (0 != ::gettimeofday(&the_time,0)) { + if (0 != ::gettimeofday(&the_time,nullptr)) { // This is *really* unlikely to occur because the only gettimeofday // errors concern the timezone parameter which we're passing in as 0. // In the unlikely case it does happen, just return MinTime, no error diff --git a/contrib/llvm/lib/Support/Unix/system_error.inc b/contrib/llvm/lib/Support/Unix/system_error.inc deleted file mode 100644 index 681e919..0000000 --- a/contrib/llvm/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/contrib/llvm/lib/Support/Valgrind.cpp b/contrib/llvm/lib/Support/Valgrind.cpp index 2b250a3..2c6d6aa 100644 --- a/contrib/llvm/lib/Support/Valgrind.cpp +++ b/contrib/llvm/lib/Support/Valgrind.cpp @@ -55,13 +55,21 @@ void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) { #if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG) // These functions require no implementation, tsan just looks at the arguments -// they're called with. +// they're called with. However, they are required to be weak as some other +// application or library may already be providing these definitions for the +// same reason we are. extern "C" { +LLVM_ATTRIBUTE_WEAK void AnnotateHappensAfter(const char *file, int line, + const volatile void *cv); +void AnnotateHappensAfter(const char *file, int line, const volatile void *cv) { +} +LLVM_ATTRIBUTE_WEAK void AnnotateHappensBefore(const char *file, int line, + const volatile void *cv); void AnnotateHappensBefore(const char *file, int line, const volatile void *cv) {} -void AnnotateHappensAfter(const char *file, int line, - const volatile void *cv) {} +LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesBegin(const char *file, int line); void AnnotateIgnoreWritesBegin(const char *file, int line) {} +LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line); void AnnotateIgnoreWritesEnd(const char *file, int line) {} } #endif diff --git a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc index 5a7b219..5ed0b70 100644 --- a/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc +++ b/contrib/llvm/lib/Support/Windows/DynamicLibrary.inc @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #ifdef __MINGW32__ #include <imagehlp.h> @@ -58,7 +58,7 @@ extern "C" { stricmp(ModuleName, "msvcr70") != 0 && #ifndef __MINGW32__ // Mingw32 uses msvcrt.dll by default. Don't ignore it. - // Otherwise, user should be aware, what he's doing :) + // Otherwise the user should be aware what they are doing. stricmp(ModuleName, "msvcrt") != 0 && #endif stricmp(ModuleName, "msvcrt20") != 0 && @@ -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/contrib/llvm/lib/Support/Windows/Host.inc b/contrib/llvm/lib/Support/Windows/Host.inc index 2e6d6f1..0c02bf9 100644 --- a/contrib/llvm/lib/Support/Windows/Host.inc +++ b/contrib/llvm/lib/Support/Windows/Host.inc @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include <cstdio> #include <string> using namespace llvm; std::string sys::getDefaultTargetTriple() { - return LLVM_DEFAULT_TARGET_TRIPLE; + return Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE); } diff --git a/contrib/llvm/lib/Support/Windows/Memory.inc b/contrib/llvm/lib/Support/Windows/Memory.inc index 1260452..ae8371a 100644 --- a/contrib/llvm/lib/Support/Windows/Memory.inc +++ b/contrib/llvm/lib/Support/Windows/Memory.inc @@ -15,9 +15,10 @@ #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 "Windows.h" +#include "WindowsSupport.h" namespace { @@ -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/contrib/llvm/lib/Support/Windows/Mutex.inc b/contrib/llvm/lib/Support/Windows/Mutex.inc index 583dc63..ab79d07 100644 --- a/contrib/llvm/lib/Support/Windows/Mutex.inc +++ b/contrib/llvm/lib/Support/Windows/Mutex.inc @@ -16,7 +16,7 @@ //=== is guaranteed to work on *all* Win32 variants. //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include "llvm/Support/Mutex.h" namespace llvm { diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc index 0b39198..7a1bc0447 100644 --- a/contrib/llvm/lib/Support/Windows/Path.inc +++ b/contrib/llvm/lib/Support/Windows/Path.inc @@ -17,12 +17,17 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" -#include "Windows.h" +#include "llvm/Support/WindowsError.h" #include <fcntl.h> #include <io.h> #include <sys/stat.h> #include <sys/types.h> +// These two headers must be included last, and make sure shlobj is required +// after Windows.h to make sure it picks up our definition of _WIN32_WINNT +#include "WindowsSupport.h" +#include <shlobj.h> + #undef max // MinGW doesn't define this. @@ -40,175 +45,35 @@ using namespace llvm; using llvm::sys::windows::UTF8ToUTF16; using llvm::sys::windows::UTF16ToUTF8; -namespace { - typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)( - /*__in*/ LPCWSTR lpSymlinkFileName, - /*__in*/ LPCWSTR lpTargetFileName, - /*__in*/ DWORD dwFlags); - - PtrCreateSymbolicLinkW create_symbolic_link_api = - PtrCreateSymbolicLinkW(::GetProcAddress( - ::GetModuleHandleW(L"Kernel32.dll"), "CreateSymbolicLinkW")); - - error_code TempDir(SmallVectorImpl<wchar_t> &result) { - retry_temp_dir: - DWORD len = ::GetTempPathW(result.capacity(), result.begin()); - - if (len == 0) - return windows_error(::GetLastError()); - - if (len > result.capacity()) { - result.reserve(len); - goto retry_temp_dir; - } - - result.set_size(len); - return error_code::success(); - } - - bool is_separator(const wchar_t value) { - switch (value) { - case L'\\': - case L'/': - return true; - default: - return false; - } - } +static std::error_code windows_error(DWORD E) { + return mapWindowsError(E); } -// FIXME: mode should be used here and default to user r/w only, -// it currently comes in as a UNIX mode. -static error_code createUniqueEntity(const Twine &model, int &result_fd, - SmallVectorImpl<char> &result_path, - bool makeAbsolute, unsigned mode, - FSEntity Type) { - // Use result_path as temp storage. - result_path.set_size(0); - StringRef m = model.toStringRef(result_path); - - SmallVector<wchar_t, 128> model_utf16; - if (error_code ec = UTF8ToUTF16(m, model_utf16)) return ec; - - if (makeAbsolute) { - // Make model absolute by prepending a temp directory if it's not already. - bool absolute = sys::path::is_absolute(m); - - if (!absolute) { - SmallVector<wchar_t, 64> temp_dir; - if (error_code ec = TempDir(temp_dir)) return ec; - // Handle c: by removing it. - if (model_utf16.size() > 2 && model_utf16[1] == L':') { - model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2); - } - model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end()); - } - } +static std::error_code TempDir(SmallVectorImpl<char> &Result) { + SmallVector<wchar_t, 64> Res; +retry_temp_dir: + DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin()); - // Replace '%' with random chars. From here on, DO NOT modify model. It may be - // needed if the randomly chosen path already exists. - SmallVector<wchar_t, 128> random_path_utf16; - - // Get a Crypto Provider for CryptGenRandom. - HCRYPTPROV HCPC; - if (!::CryptAcquireContextW(&HCPC, - NULL, - NULL, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) + if (Len == 0) return windows_error(::GetLastError()); - ScopedCryptContext CryptoProvider(HCPC); - -retry_random_path: - random_path_utf16.set_size(0); - for (SmallVectorImpl<wchar_t>::const_iterator i = model_utf16.begin(), - e = model_utf16.end(); - i != e; ++i) { - if (*i == L'%') { - BYTE val = 0; - if (!::CryptGenRandom(CryptoProvider, 1, &val)) - return windows_error(::GetLastError()); - random_path_utf16.push_back(L"0123456789abcdef"[val & 15]); - } - else - random_path_utf16.push_back(*i); - } - // Make random_path_utf16 null terminated. - random_path_utf16.push_back(0); - random_path_utf16.pop_back(); - - HANDLE TempFileHandle = INVALID_HANDLE_VALUE; - - switch (Type) { - case FS_File: { - // Try to create + open the path. - TempFileHandle = - ::CreateFileW(random_path_utf16.begin(), GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ, NULL, - // Return ERROR_FILE_EXISTS if the file - // already exists. - CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL); - if (TempFileHandle == INVALID_HANDLE_VALUE) { - // If the file existed, try again, otherwise, error. - error_code ec = windows_error(::GetLastError()); - if (ec == windows_error::file_exists) - goto retry_random_path; - - return ec; - } - - // Convert the Windows API file handle into a C-runtime handle. - int fd = ::_open_osfhandle(intptr_t(TempFileHandle), 0); - if (fd == -1) { - ::CloseHandle(TempFileHandle); - ::DeleteFileW(random_path_utf16.begin()); - // MSDN doesn't say anything about _open_osfhandle setting errno or - // GetLastError(), so just return invalid_handle. - return windows_error::invalid_handle; - } - result_fd = fd; - break; + if (Len > Res.capacity()) { + Res.reserve(Len); + goto retry_temp_dir; } - case FS_Name: { - DWORD attributes = ::GetFileAttributesW(random_path_utf16.begin()); - if (attributes != INVALID_FILE_ATTRIBUTES) - goto retry_random_path; - error_code EC = make_error_code(windows_error(::GetLastError())); - if (EC != windows_error::file_not_found && - EC != windows_error::path_not_found) - return EC; - break; - } - - case FS_Dir: - if (!::CreateDirectoryW(random_path_utf16.begin(), NULL)) { - error_code EC = windows_error(::GetLastError()); - if (EC != windows_error::already_exists) - return EC; - goto retry_random_path; - } - break; - } + Res.set_size(Len); + return UTF16ToUTF8(Res.begin(), Res.size(), Result); +} - // Set result_path to the utf-8 representation of the path. - if (error_code ec = UTF16ToUTF8(random_path_utf16.begin(), - random_path_utf16.size(), result_path)) { - switch (Type) { - case FS_File: - ::CloseHandle(TempFileHandle); - ::DeleteFileW(random_path_utf16.begin()); - case FS_Name: - break; - case FS_Dir: - ::RemoveDirectoryW(random_path_utf16.begin()); - break; - } - return ec; +static bool is_separator(const wchar_t value) { + switch (value) { + case L'\\': + case L'/': + return true; + default: + return false; } - - return error_code::success(); } namespace llvm { @@ -259,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; @@ -281,50 +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 &existed) { +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) - existed = true; - else - return ec; - } else - existed = false; + DWORD LastError = ::GetLastError(); + if (LastError != ERROR_ALREADY_EXISTS || !IgnoreExisting) + return windows_error(LastError); + } - return error_code::success(); + return std::error_code(); } -error_code create_hard_link(const Twine &to, const Twine &from) { - // Get arguments. - SmallString<128> from_storage; - SmallString<128> to_storage; - StringRef f = from.toStringRef(from_storage); - StringRef t = to.toStringRef(to_storage); - - // 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 (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL)) - return windows_error(::GetLastError()); - - return error_code::success(); +std::error_code normalize_separators(SmallVectorImpl<char> &Path) { + (void) Path; + return std::error_code(); } -error_code create_symlink(const Twine &to, const Twine &from) { - // Only do it if the function is available at runtime. - if (!create_symbolic_link_api) - return make_error_code(errc::function_not_supported); - +// We can't use symbolic links for windows. +std::error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -334,56 +179,49 @@ error_code create_symlink(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 (!create_symbolic_link_api(wide_from.begin(), wide_to.begin(), 0)) + 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 &existed) { +std::error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallString<128> path_storage; SmallVector<wchar_t, 128> path_utf16; - file_status st; - error_code EC = status(path, st); - if (EC) { - if (EC == windows_error::file_not_found || - EC == windows_error::path_not_found) { - existed = false; - return error_code::success(); - } - return EC; + file_status ST; + if (std::error_code EC = status(path, ST)) { + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; + 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 (ST.type() == file_type::directory_file) { if (!::RemoveDirectoryW(c_str(path_utf16))) { - error_code ec = windows_error(::GetLastError()); - if (ec != windows_error::file_not_found) - return ec; - existed = false; - } else - existed = true; - } else { - if (!::DeleteFileW(c_str(path_utf16))) { - error_code ec = windows_error(::GetLastError()); - if (ec != windows_error::file_not_found) - return ec; - existed = false; - } else - existed = true; + std::error_code EC = windows_error(::GetLastError()); + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; + } + return std::error_code(); } - - return error_code::success(); + if (!::DeleteFileW(c_str(path_utf16))) { + std::error_code EC = windows_error(::GetLastError()); + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; + } + 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; @@ -393,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 @@ -413,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) { @@ -489,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) { @@ -520,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; @@ -532,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; @@ -557,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()); @@ -613,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; @@ -627,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()) { @@ -697,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); @@ -718,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) @@ -732,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) { @@ -753,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() @@ -805,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() @@ -834,7 +634,6 @@ mapped_file_region::~mapped_file_region() { ::UnmapViewOfFile(Mapping); } -#if LLVM_HAS_RVALUE_REFERENCES mapped_file_region::mapped_file_region(mapped_file_region &&other) : Mode(other.Mode) , Size(other.Size) @@ -846,7 +645,6 @@ mapped_file_region::mapped_file_region(mapped_file_region &&other) other.FileHandle = INVALID_HANDLE_VALUE; other.FileDescriptor = 0; } -#endif mapped_file_region::mapmode mapped_file_region::flags() const { assert(Mapping && "Mapping failed but used anyway!"); @@ -859,7 +657,7 @@ uint64_t mapped_file_region::size() const { } char *mapped_file_region::data() const { - assert(Mode != readonly && "Cannot get non const data for readonly mapping!"); + assert(Mode != readonly && "Cannot get non-const data for readonly mapping!"); assert(Mapping && "Mapping failed but used anyway!"); return reinterpret_cast<char*>(Mapping); } @@ -875,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. @@ -904,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()); @@ -924,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); @@ -953,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(); -} - -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; + return std::error_code(); } -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)) && @@ -1015,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; @@ -1027,19 +814,24 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, else CreationDisposition = CREATE_ALWAYS; - HANDLE H = ::CreateFileW(PathUTF16.begin(), GENERIC_WRITE, + DWORD Access = GENERIC_WRITE; + if (Flags & F_RW) + Access |= GENERIC_READ; + + HANDLE H = ::CreateFileW(PathUTF16.begin(), Access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 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; } @@ -1047,75 +839,89 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, if (Flags & F_Append) OpenFlags |= _O_APPEND; - if (!(Flags & F_Binary)) + if (Flags & F_Text) OpenFlags |= _O_TEXT; 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 +namespace path { + +bool home_directory(SmallVectorImpl<char> &result) { + wchar_t Path[MAX_PATH]; + if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, + /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK) + return false; + + if (UTF16ToUTF8(Path, ::wcslen(Path), result)) + return false; + + return true; +} + +} // end namespace path + namespace windows { -llvm::error_code UTF8ToUTF16(llvm::StringRef utf8, - llvm::SmallVectorImpl<wchar_t> &utf16) { - int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - utf8.begin(), utf8.size(), - utf16.begin(), 0); +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()); + if (len == 0) + return windows_error(::GetLastError()); - utf16.reserve(len + 1); - utf16.set_size(len); + utf16.reserve(len + 1); + utf16.set_size(len); - len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - utf8.begin(), utf8.size(), - utf16.begin(), utf16.size()); + len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8.begin(), + utf8.size(), utf16.begin(), utf16.size()); - if (len == 0) - return llvm::windows_error(::GetLastError()); + if (len == 0) + 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) { - // Get length. - int len = ::WideCharToMultiByte(CP_UTF8, 0, - utf16, utf16_len, - utf8.begin(), 0, - NULL, NULL); +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()); + if (len == 0) + return windows_error(::GetLastError()); - utf8.reserve(len); - utf8.set_size(len); + utf8.reserve(len); + utf8.set_size(len); - // Now do the actual conversion. - len = ::WideCharToMultiByte(CP_UTF8, 0, - utf16, utf16_len, - utf8.data(), utf8.size(), - NULL, NULL); + // Now do the actual conversion. + len = ::WideCharToMultiByte(CP_UTF8, 0, utf16, utf16_len, utf8.data(), + utf8.size(), NULL, NULL); - if (len == 0) - return llvm::windows_error(::GetLastError()); + if (len == 0) + 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/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc index f9a3db9..61749a7 100644 --- a/contrib/llvm/lib/Support/Windows/Process.inc +++ b/contrib/llvm/lib/Support/Windows/Process.inc @@ -12,11 +12,15 @@ //===----------------------------------------------------------------------===// #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. +#include "WindowsSupport.h" -#include "Windows.h" #include <direct.h> #include <io.h> -#include <malloc.h> #include <psapi.h> #include <shellapi.h> @@ -45,7 +49,6 @@ using namespace llvm; using namespace sys; - process::id_type self_process::get_id() { return GetCurrentProcessId(); } @@ -80,16 +83,14 @@ TimeValue self_process::get_system_time() const { return getTimeValueFromFILETIME(KernelTime); } -// This function retrieves the page size using GetSystemInfo and is present -// solely so it can be called once to initialize the self_process member below. +// This function retrieves the page size using GetNativeSystemInfo() and is +// present solely so it can be called once to initialize the self_process member +// below. static unsigned getPageSize() { - // NOTE: A 32-bit application running under WOW64 is supposed to use - // GetNativeSystemInfo. However, this interface is not present prior - // to Windows XP so to use it requires dynamic linking. It is not clear - // how this affects the reported page size, if at all. One could argue - // that LLVM ought to run as 64-bits on a 64-bit system, anyway. + // GetNativeSystemInfo() provides the physical page size which may differ + // from GetSystemInfo() in 32-bit applications running under WOW64. SYSTEM_INFO info; - GetSystemInfo(&info); + GetNativeSystemInfo(&info); // FIXME: FileOffset in MapViewOfFile() should be aligned to not dwPageSize, // but dwAllocationGranularity. return static_cast<unsigned>(info.dwPageSize); @@ -152,7 +153,7 @@ void Process::PreventCoreFiles() { Optional<std::string> Process::GetEnv(StringRef Name) { // Convert the argument to UTF-16 to pass it to _wgetenv(). SmallVector<wchar_t, 128> NameUTF16; - if (error_code ec = windows::UTF8ToUTF16(Name, NameUTF16)) + if (windows::UTF8ToUTF16(Name, NameUTF16)) return None; // Environment variable can be encoded in non-UTF8 encoding, and there's no @@ -173,42 +174,103 @@ Optional<std::string> Process::GetEnv(StringRef Name) { // Convert the result from UTF-16 to UTF-8. SmallVector<char, MAX_PATH> Res; - if (error_code ec = windows::UTF16ToUTF8(Buf.data(), Size, Res)) + if (windows::UTF16ToUTF8(Buf.data(), Size, Res)) return None; return std::string(Res.data()); } -error_code +static std::error_code windows_error(DWORD E) { + return mapWindowsError(E); +} + +static void AllocateAndPush(const SmallVectorImpl<char> &S, + SmallVectorImpl<const char *> &Vector, + SpecificBumpPtrAllocator<char> &Allocator) { + char *Buffer = Allocator.Allocate(S.size() + 1); + ::memcpy(Buffer, S.data(), S.size()); + Buffer[S.size()] = '\0'; + Vector.push_back(Buffer); +} + +/// Convert Arg from UTF-16 to UTF-8 and push it onto Args. +static std::error_code +ConvertAndPushArg(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, + SpecificBumpPtrAllocator<char> &Allocator) { + SmallVector<char, MAX_PATH> ArgString; + if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), ArgString)) + return ec; + AllocateAndPush(ArgString, Args, Allocator); + return std::error_code(); +} + +/// \brief Perform wildcard expansion of Arg, or just push it into Args if it +/// doesn't have wildcards or doesn't match any files. +static std::error_code +WildcardExpand(const wchar_t *Arg, SmallVectorImpl<const char *> &Args, + SpecificBumpPtrAllocator<char> &Allocator) { + if (!wcspbrk(Arg, L"*?")) { + // Arg does not contain any wildcard characters. This is the common case. + return ConvertAndPushArg(Arg, Args, Allocator); + } + + if (wcscmp(Arg, L"/?") == 0 || wcscmp(Arg, L"-?") == 0) { + // Don't wildcard expand /?. Always treat it as an option. + return ConvertAndPushArg(Arg, Args, Allocator); + } + + // Extract any directory part of the argument. + SmallVector<char, MAX_PATH> Dir; + if (std::error_code ec = windows::UTF16ToUTF8(Arg, wcslen(Arg), Dir)) + return ec; + sys::path::remove_filename(Dir); + const int DirSize = Dir.size(); + + // Search for matching files. + WIN32_FIND_DATAW FileData; + HANDLE FindHandle = FindFirstFileW(Arg, &FileData); + if (FindHandle == INVALID_HANDLE_VALUE) { + return ConvertAndPushArg(Arg, Args, Allocator); + } + + std::error_code ec; + do { + SmallVector<char, MAX_PATH> FileName; + ec = windows::UTF16ToUTF8(FileData.cFileName, wcslen(FileData.cFileName), + FileName); + if (ec) + break; + + // Push the filename onto Dir, and remove it afterwards. + llvm::sys::path::append(Dir, StringRef(FileName.data(), FileName.size())); + AllocateAndPush(Dir, Args, Allocator); + Dir.resize(DirSize); + } while (FindNextFileW(FindHandle, &FileData)); + + FindClose(FindHandle); + return ec; +} + +std::error_code Process::GetArgumentVector(SmallVectorImpl<const char *> &Args, ArrayRef<const char *>, SpecificBumpPtrAllocator<char> &ArgAllocator) { - int NewArgCount; - error_code ec; - - wchar_t **UnicodeCommandLine = CommandLineToArgvW(GetCommandLineW(), - &NewArgCount); + int ArgCount; + wchar_t **UnicodeCommandLine = + CommandLineToArgvW(GetCommandLineW(), &ArgCount); if (!UnicodeCommandLine) return windows_error(::GetLastError()); - Args.reserve(NewArgCount); + Args.reserve(ArgCount); + std::error_code ec; - for (int i = 0; i < NewArgCount; ++i) { - SmallVector<char, MAX_PATH> NewArgString; - ec = windows::UTF16ToUTF8(UnicodeCommandLine[i], - wcslen(UnicodeCommandLine[i]), - NewArgString); + for (int i = 0; i < ArgCount; ++i) { + ec = WildcardExpand(UnicodeCommandLine[i], Args, ArgAllocator); if (ec) break; - - char *Buffer = ArgAllocator.Allocate(NewArgString.size() + 1); - ::memcpy(Buffer, NewArgString.data(), NewArgString.size() + 1); - Args.push_back(Buffer); } - LocalFree(UnicodeCommandLine); - if (ec) - return ec; - return error_code::success(); + LocalFree(UnicodeCommandLine); + return ec; } bool Process::StandardInIsUserInput() { @@ -358,3 +420,17 @@ const char *Process::ResetColor() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors()); return 0; } + +unsigned Process::GetRandomNumber() { + HCRYPTPROV HCPC; + if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) + report_fatal_error("Could not acquire a cryptographic context"); + + ScopedCryptContext CryptoProvider(HCPC); + unsigned Ret; + if (!::CryptGenRandom(CryptoProvider, sizeof(Ret), + reinterpret_cast<BYTE *>(&Ret))) + report_fatal_error("Could not generate a random number"); + return Ret; +} diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc index dc09738..b2f71ae 100644 --- a/contrib/llvm/lib/Support/Windows/Program.inc +++ b/contrib/llvm/lib/Support/Windows/Program.inc @@ -11,8 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" -#include "llvm/ADT/OwningPtr.h" +#include "WindowsSupport.h" #include "llvm/Support/FileSystem.h" #include <cstdio> #include <fcntl.h> @@ -187,7 +186,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, } // Now build the command line. - OwningArrayPtr<char> command(new char[len+1]); + std::unique_ptr<char[]> command(new char[len+1]); char *p = command.get(); for (unsigned i = 0; args[i]; i++) { @@ -227,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; @@ -291,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")); @@ -299,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")); @@ -423,25 +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); -} - -error_code sys::ChangeStderrToBinary(){ - int result = _setmode( _fileno(stderr), _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/contrib/llvm/lib/Support/Windows/RWMutex.inc b/contrib/llvm/lib/Support/Windows/RWMutex.inc index c431844..00d0e93 100644 --- a/contrib/llvm/lib/Support/Windows/RWMutex.inc +++ b/contrib/llvm/lib/Support/Windows/RWMutex.inc @@ -16,7 +16,7 @@ //=== is guaranteed to work on *all* Win32 variants. //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" namespace llvm { using namespace sys; diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc index 4b40d51..35ba6f8 100644 --- a/contrib/llvm/lib/Support/Windows/Signals.inc +++ b/contrib/llvm/lib/Support/Windows/Signals.inc @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FileSystem.h" - -#include "Windows.h" #include <algorithm> #include <stdio.h> #include <vector> +// The Windows.h header must be after LLVM and standard headers. +#include "WindowsSupport.h" + #ifdef __MINGW32__ #include <imagehlp.h> #else @@ -317,8 +318,7 @@ static void Cleanup() { if (FilesToRemove != NULL) while (!FilesToRemove->empty()) { - bool Existed; - llvm::sys::fs::remove(FilesToRemove->back(), Existed); + llvm::sys::fs::remove(FilesToRemove->back()); FilesToRemove->pop_back(); } diff --git a/contrib/llvm/lib/Support/Windows/ThreadLocal.inc b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc index 057deb3..14ce619 100644 --- a/contrib/llvm/lib/Support/Windows/ThreadLocal.inc +++ b/contrib/llvm/lib/Support/Windows/ThreadLocal.inc @@ -16,14 +16,14 @@ //=== is guaranteed to work on *all* Win32 variants. //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include "llvm/Support/ThreadLocal.h" namespace llvm { using namespace sys; ThreadLocalImpl::ThreadLocalImpl() : data() { - typedef int SIZE_TOO_BIG[sizeof(DWORD) <= sizeof(data) ? 1 : -1]; + static_assert(sizeof(DWORD) <= sizeof(data), "size too big"); DWORD* tls = reinterpret_cast<DWORD*>(&data); *tls = TlsAlloc(); assert(*tls != TLS_OUT_OF_INDEXES); diff --git a/contrib/llvm/lib/Support/Windows/TimeValue.inc b/contrib/llvm/lib/Support/Windows/TimeValue.inc index 98b07d6..0223ab4 100644 --- a/contrib/llvm/lib/Support/Windows/TimeValue.inc +++ b/contrib/llvm/lib/Support/Windows/TimeValue.inc @@ -11,7 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" #include <cctype> #include <time.h> @@ -32,6 +34,7 @@ TimeValue TimeValue::now() { } std::string TimeValue::str() const { + std::string S; struct tm *LT; #ifdef __MINGW32__ // Old versions of mingw don't have _localtime64_s. Remove this once we drop support @@ -47,13 +50,11 @@ std::string TimeValue::str() const { LT = &Storage; #endif - char Buffer[25]; - // FIXME: the windows version of strftime doesn't support %e - strftime(Buffer, 25, "%b %d %H:%M %Y", LT); - assert((Buffer[3] == ' ' && isdigit(Buffer[5]) && Buffer[6] == ' ') && - "Unexpected format in strftime()!"); - // Emulate %e on %d to mute '0'. - if (Buffer[4] == '0') - Buffer[4] = ' '; - return std::string(Buffer); + char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")]; + strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", LT); + raw_string_ostream OS(S); + OS << format("%s.%.9u", static_cast<const char *>(Buffer), + this->nanoseconds()); + OS.flush(); + return S; } diff --git a/contrib/llvm/lib/Support/Windows/Windows.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h index 1f3417d..f68835b 100644 --- a/contrib/llvm/lib/Support/Windows/Windows.h +++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h @@ -1,4 +1,4 @@ -//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===// +//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,10 @@ // //===----------------------------------------------------------------------===// // -// This file defines things specific to Win32 implementations. +// This file defines things specific to Windows implementations. In addition to +// providing some helpers for working with win32 APIs, this header wraps +// <windows.h> with some portability macros. Always include WindowsSupport.h +// instead of including <windows.h> directly. // //===----------------------------------------------------------------------===// @@ -18,6 +21,7 @@ // mingw-w64 tends to define it as 0x0502 in its headers. #undef _WIN32_WINNT +#undef _WIN32_IE // Require at least Windows XP(5.1) API. #define _WIN32_WINNT 0x0501 @@ -28,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> @@ -159,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/contrib/llvm/lib/Support/Windows/system_error.inc b/contrib/llvm/lib/Support/Windows/system_error.inc deleted file mode 100644 index 37ec81d..0000000 --- a/contrib/llvm/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/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp index 9495cd4..3be02ee 100644 --- a/contrib/llvm/lib/Support/YAMLParser.cpp +++ b/contrib/llvm/lib/Support/YAMLParser.cpp @@ -378,9 +378,6 @@ private: /// sequence of ns-uri-char. StringRef scan_ns_uri_char(); - /// @brief Scan ns-plain-one-line[133] starting at \a Cur. - StringRef scan_ns_plain_one_line(); - /// @brief Consume a minimal well-formed code unit subsequence starting at /// \a Cur. Return false if it is not the same Unicode scalar value as /// \a Expected. This updates \a Column. @@ -873,42 +870,6 @@ StringRef Scanner::scan_ns_uri_char() { return StringRef(Start, Current - Start); } -StringRef Scanner::scan_ns_plain_one_line() { - StringRef::iterator start = Current; - // The first character must already be verified. - ++Current; - while (true) { - if (Current == End) { - break; - } else if (*Current == ':') { - // Check if the next character is a ns-char. - if (Current + 1 == End) - break; - StringRef::iterator i = skip_ns_char(Current + 1); - if (Current + 1 != i) { - Current = i; - Column += 2; // Consume both the ':' and ns-char. - } else - break; - } else if (*Current == '#') { - // Check if the previous character was a ns-char. - // The & 0x80 check is to check for the trailing byte of a utf-8 - if (*(Current - 1) & 0x80 || skip_ns_char(Current - 1) == Current) { - ++Current; - ++Column; - } else - break; - } else { - StringRef::iterator i = skip_nb_char(Current); - if (i == Current) - break; - Current = i; - ++Column; - } - } - return StringRef(start, Current - start); -} - bool Scanner::consume(uint32_t Expected) { if (Expected >= 0x80) report_fatal_error("Not dealing with this yet"); @@ -1561,12 +1522,10 @@ bool Scanner::fetchMoreTokens() { } Stream::Stream(StringRef Input, SourceMgr &SM) - : scanner(new Scanner(Input, SM)) - , CurrentDoc(0) {} + : scanner(new Scanner(Input, SM)), CurrentDoc() {} Stream::Stream(MemoryBuffer *InputBuffer, SourceMgr &SM) - : scanner(new Scanner(InputBuffer, SM)) - , CurrentDoc(0) {} + : scanner(new Scanner(InputBuffer, SM)), CurrentDoc() {} Stream::~Stream() {} @@ -1601,11 +1560,9 @@ void Stream::skip() { i->skip(); } -Node::Node(unsigned int Type, OwningPtr<Document> &D, StringRef A, StringRef T) - : Doc(D) - , TypeID(Type) - , Anchor(A) - , Tag(T) { +Node::Node(unsigned int Type, std::unique_ptr<Document> &D, StringRef A, + StringRef T) + : Doc(D), TypeID(Type), Anchor(A), Tag(T) { SMLoc Start = SMLoc::getFromPointer(peekNext().Range.begin()); SourceRange = SMRange(Start, Start); } @@ -1617,11 +1574,11 @@ std::string Node::getVerbatimTag() const { if (Raw.find_last_of('!') == 0) { Ret = Doc->getTagMap().find("!")->second; Ret += Raw.substr(1); - return llvm_move(Ret); + return std::move(Ret); } else if (Raw.startswith("!!")) { Ret = Doc->getTagMap().find("!!")->second; Ret += Raw.substr(2); - return llvm_move(Ret); + return std::move(Ret); } else { StringRef TagHandle = Raw.substr(0, Raw.find_last_of('!') + 1); std::map<StringRef, StringRef>::const_iterator It = @@ -1635,7 +1592,7 @@ std::string Node::getVerbatimTag() const { setError(Twine("Unknown tag handle ") + TagHandle, T); } Ret += Raw.substr(Raw.find_last_of('!') + 1); - return llvm_move(Ret); + return std::move(Ret); } } @@ -1919,14 +1876,14 @@ Node *KeyValueNode::getValue() { void MappingNode::increment() { if (failed()) { IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; return; } if (CurrentEntry) { CurrentEntry->skip(); if (Type == MT_Inline) { IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; return; } } @@ -1939,13 +1896,13 @@ void MappingNode::increment() { case Token::TK_BlockEnd: getNext(); IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; default: setError("Unexpected token. Expected Key or Block End", T); case Token::TK_Error: IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } } else { switch (T.Kind) { @@ -1958,14 +1915,14 @@ void MappingNode::increment() { case Token::TK_Error: // Set this to end iterator. IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; default: setError( "Unexpected token. Expected Key, Flow Entry, or Flow " "Mapping End." , T); IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } } } @@ -1973,7 +1930,7 @@ void MappingNode::increment() { void SequenceNode::increment() { if (failed()) { IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; return; } if (CurrentEntry) @@ -1984,37 +1941,37 @@ void SequenceNode::increment() { case Token::TK_BlockEntry: getNext(); CurrentEntry = parseBlockNode(); - if (CurrentEntry == 0) { // An error occurred. + if (!CurrentEntry) { // An error occurred. IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } break; case Token::TK_BlockEnd: getNext(); IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; default: setError( "Unexpected token. Expected Block Entry or Block End." , T); case Token::TK_Error: IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } } else if (SeqType == ST_Indentless) { switch (T.Kind) { case Token::TK_BlockEntry: getNext(); CurrentEntry = parseBlockNode(); - if (CurrentEntry == 0) { // An error occurred. + if (!CurrentEntry) { // An error occurred. IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } break; default: case Token::TK_Error: IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; } } else if (SeqType == ST_Flow) { switch (T.Kind) { @@ -2028,7 +1985,7 @@ void SequenceNode::increment() { case Token::TK_Error: // Set this to end iterator. IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; case Token::TK_StreamEnd: case Token::TK_DocumentEnd: @@ -2036,13 +1993,13 @@ void SequenceNode::increment() { setError("Could not find closing ]!", T); // Set this to end iterator. IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; default: if (!WasPreviousTokenFlowEntry) { setError("Expected , between entries!", T); IsAtEnd = true; - CurrentEntry = 0; + CurrentEntry = nullptr; break; } // Otherwise it must be a flow entry. @@ -2056,7 +2013,7 @@ void SequenceNode::increment() { } } -Document::Document(Stream &S) : stream(S), Root(0) { +Document::Document(Stream &S) : stream(S), Root(nullptr) { // Tag maps starts with two default mappings. TagMap["!"] = "!"; TagMap["!!"] = "tag:yaml.org,2002:"; @@ -2113,7 +2070,7 @@ parse_property: case Token::TK_Anchor: if (AnchorInfo.Kind == Token::TK_Anchor) { setError("Already encountered an anchor for this node!", T); - return 0; + return nullptr; } AnchorInfo = getNext(); // Consume TK_Anchor. T = peekNext(); @@ -2121,7 +2078,7 @@ parse_property: case Token::TK_Tag: if (TagInfo.Kind == Token::TK_Tag) { setError("Already encountered a tag for this node!", T); - return 0; + return nullptr; } TagInfo = getNext(); // Consume TK_Tag. T = peekNext(); @@ -2189,10 +2146,10 @@ parse_property: // !!null null. return new (NodeAllocator) NullNode(stream.CurrentDoc); case Token::TK_Error: - return 0; + return nullptr; } llvm_unreachable("Control flow shouldn't reach here."); - return 0; + return nullptr; } bool Document::parseDirectives() { diff --git a/contrib/llvm/lib/Support/YAMLTraits.cpp b/contrib/llvm/lib/Support/YAMLTraits.cpp index 42bff96..5212624 100644 --- a/contrib/llvm/lib/Support/YAMLTraits.cpp +++ b/contrib/llvm/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" @@ -14,8 +15,8 @@ #include "llvm/Support/Format.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" -#include <cstring> #include <cctype> +#include <cstring> using namespace llvm; using namespace yaml; @@ -47,7 +48,7 @@ Input::Input(StringRef InputContent, void *DiagHandlerCtxt) : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr)), - CurrentNode(NULL) { + CurrentNode(nullptr) { if (DiagHandler) SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt); DocIterator = Strm->begin(); @@ -56,16 +57,14 @@ 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() {} void Input::EmptyHNode::anchor() {} void Input::ScalarHNode::anchor() {} -bool Input::outputting() const { +bool Input::outputting() { return false; } @@ -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) { @@ -158,10 +157,9 @@ void Input::endMapping() { MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode); if (!MN) return; - for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(), - End = MN->Mapping.end(); i != End; ++i) { - if (!MN->isValidKey(i->first())) { - setError(i->second, Twine("unknown key '") + i->first() + "'"); + for (const auto &NN : MN->Mapping) { + if (!MN->isValidKey(NN.first())) { + setError(NN.second, Twine("unknown key '") + NN.first() + "'"); break; } } @@ -255,9 +253,8 @@ bool Input::bitSetMatch(const char *Str, bool) { return false; if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { unsigned Index = 0; - for (std::vector<HNode *>::iterator i = SQ->Entries.begin(), - End = SQ->Entries.end(); i != End; ++i) { - if (ScalarHNode *SN = dyn_cast<ScalarHNode>(*i)) { + for (HNode *N : SQ->Entries) { + if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N)) { if (SN->value().equals(Str)) { BitValuesUsed[Index] = true; return true; @@ -287,7 +284,7 @@ void Input::endBitSetScalar() { } } -void Input::scalarString(StringRef &S) { +void Input::scalarString(StringRef &S, bool) { if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { S = SN->value(); } else { @@ -319,9 +316,8 @@ Input::HNode *Input::createHNodes(Node *N) { return new ScalarHNode(N, KeyStr); } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) { SequenceHNode *SQHNode = new SequenceHNode(N); - for (SequenceNode::iterator i = SQ->begin(), End = SQ->end(); i != End; - ++i) { - HNode *Entry = this->createHNodes(i); + for (Node &SN : *SQ) { + HNode *Entry = this->createHNodes(&SN); if (EC) break; SQHNode->Entries.push_back(Entry); @@ -329,9 +325,8 @@ Input::HNode *Input::createHNodes(Node *N) { return SQHNode; } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) { MapHNode *mapHNode = new MapHNode(N); - for (MappingNode::iterator i = Map->begin(), End = Map->end(); i != End; - ++i) { - ScalarNode *KeyScalar = dyn_cast<ScalarNode>(i->getKey()); + for (KeyValueNode &KVN : *Map) { + ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KVN.getKey()); StringStorage.clear(); StringRef KeyStr = KeyScalar->getValue(StringStorage); if (!StringStorage.empty()) { @@ -341,7 +336,7 @@ Input::HNode *Input::createHNodes(Node *N) { memcpy(Buf, &StringStorage[0], Len); KeyStr = StringRef(Buf, Len); } - HNode *ValueHNode = this->createHNodes(i->getValue()); + HNode *ValueHNode = this->createHNodes(KVN.getValue()); if (EC) break; mapHNode->Mapping[KeyStr] = ValueHNode; @@ -351,14 +346,13 @@ Input::HNode *Input::createHNodes(Node *N) { return new EmptyHNode(N); } else { setError(N, "unknown node kind"); - return NULL; + return nullptr; } } bool Input::MapHNode::isValidKey(StringRef Key) { - for (SmallVectorImpl<const char *>::iterator i = ValidKeys.begin(), - End = ValidKeys.end(); i != End; ++i) { - if (Key.equals(*i)) + for (const char *K : ValidKeys) { + if (Key.equals(K)) return true; } return false; @@ -373,17 +367,13 @@ bool Input::canElideEmptySequence() { } Input::MapHNode::~MapHNode() { - for (MapHNode::NameToNode::iterator i = Mapping.begin(), End = Mapping.end(); - i != End; ++i) { - delete i->second; - } + for (auto &N : Mapping) + delete N.second; } Input::SequenceHNode::~SequenceHNode() { - for (std::vector<HNode*>::iterator i = Entries.begin(), End = Entries.end(); - i != End; ++i) { - delete *i; - } + for (HNode *N : Entries) + delete N; } @@ -406,7 +396,7 @@ Output::Output(raw_ostream &yout, void *context) Output::~Output() { } -bool Output::outputting() const { +bool Output::outputting() { return true; } @@ -550,10 +540,7 @@ void Output::endBitSetScalar() { this->outputUpToEndOfLine(" ]"); } -void Output::scalarString(StringRef &S) { - const char ScalarSafeChars[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t"; - +void Output::scalarString(StringRef &S, bool MustQuote) { this->newLineCheck(); if (S.empty()) { // Print '' for the empty string because leaving the field empty is not @@ -561,10 +548,8 @@ void Output::scalarString(StringRef &S) { this->outputUpToEndOfLine("''"); return; } - if (S.find_first_not_of(ScalarSafeChars) == StringRef::npos && - !isspace(S.front()) && !isspace(S.back())) { - // If the string consists only of safe characters, print it out without - // quotes. + if (!MustQuote) { + // Only quote if we must. this->outputUpToEndOfLine(S); return; } @@ -689,6 +674,17 @@ StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *, Val = Scalar; return StringRef(); } + +void ScalarTraits<std::string>::output(const std::string &Val, void *, + raw_ostream &Out) { + Out << Val; +} + +StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *, + std::string &Val) { + Val = Scalar.str(); + return StringRef(); +} void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *, raw_ostream &Out) { diff --git a/contrib/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm/lib/Support/raw_ostream.cpp index cb96489..0790be5 100644 --- a/contrib/llvm/lib/Support/raw_ostream.cpp +++ b/contrib/llvm/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) @@ -87,8 +87,8 @@ void raw_ostream::SetBuffered() { void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode) { - assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || - (Mode != Unbuffered && BufferStart && Size)) && + assert(((Mode == Unbuffered && !BufferStart && Size == 0) || + (Mode != Unbuffered && BufferStart && Size != 0)) && "stream must be unbuffered or have at least one byte"); // Make sure the current buffer is free of content (we can't flush here; the // child buffer management logic will be in write_impl). @@ -227,11 +227,17 @@ raw_ostream &raw_ostream::operator<<(double N) { // On MSVCRT and compatible, output of %e is incompatible to Posix // by default. Number of exponent digits should be at least 2. "%+03d" // FIXME: Implement our formatter to here or Support/Format.h! +#if __cplusplus >= 201103L && defined(__MINGW32__) + // FIXME: It should be generic to C++11. + if (N == 0.0 && std::signbit(N)) + return *this << "-0.000000e+00"; +#else int fpcl = _fpclass(N); // negative zero if (fpcl == _FPCLASS_NZ) return *this << "-0.000000e+00"; +#endif char buf[16]; unsigned len; @@ -427,7 +433,7 @@ void format_object_base::home() { raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, sys::fs::OpenFlags Flags) : Error(false), UseAtomicWrites(false), pos(0) { - assert(Filename != 0 && "Filename is null"); + assert(Filename && "Filename is null"); ErrorInfo.clear(); // Handle "-" as stdout. Note that when we do this, we consider ourself @@ -437,14 +443,14 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo, FD = STDOUT_FILENO; // If user requested binary then put stdout into binary mode if // possible. - if (Flags & sys::fs::F_Binary) + if (!(Flags & sys::fs::F_Text)) sys::ChangeStdoutToBinary(); // Close stdout when we're done, to detect any output errors. ShouldClose = true; 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) + "': " + @@ -463,9 +469,10 @@ raw_fd_ostream::raw_fd_ostream(int fd, bool shouldClose, bool unbuffered) : raw_ostream(unbuffered), FD(fd), ShouldClose(shouldClose), Error(false), UseAtomicWrites(false) { #ifdef O_BINARY - // Setting STDOUT and STDERR to binary mode is necessary in Win32 + // Setting STDOUT to binary mode is necessary in Win32 // to avoid undesirable linefeed conversion. - if (fd == STDOUT_FILENO || fd == STDERR_FILENO) + // Don't touch STDERR, or w*printf() (in assert()) would barf wide chars. + if (fd == STDOUT_FILENO) setmode(fd, O_BINARY); #endif @@ -653,7 +660,7 @@ bool raw_fd_ostream::has_colors() const { /// Use it like: outs() << "foo" << "bar"; raw_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. - // Delete the file descriptor when the program exists, forcing error + // Delete the file descriptor when the program exits, forcing error // detection. If you don't want this behavior, don't use outs(). static raw_fd_ostream S(STDOUT_FILENO, true); return S; @@ -722,24 +729,17 @@ void raw_svector_ostream::resync() { } void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { - // If we're writing bytes from the end of the buffer into the smallvector, we - // don't need to copy the bytes, just commit the bytes because they are - // already in the right place. if (Ptr == OS.end()) { - assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!"); - OS.set_size(OS.size() + Size); + // Grow the buffer to include the scratch area without copying. + size_t NewSize = OS.size() + Size; + assert(NewSize <= OS.capacity() && "Invalid write_impl() call!"); + OS.set_size(NewSize); } else { - assert(GetNumBytesInBuffer() == 0 && - "Should be writing from buffer if some bytes in it"); - // Otherwise, do copy the bytes. - OS.append(Ptr, Ptr+Size); + assert(!GetNumBytesInBuffer()); + OS.append(Ptr, Ptr + Size); } - // Grow the vector if necessary. - if (OS.capacity() - OS.size() < 64) - OS.reserve(OS.capacity() * 2); - - // Update the buffer position. + OS.reserve(OS.size() + 64); SetBuffer(OS.end(), OS.capacity() - OS.size()); } diff --git a/contrib/llvm/lib/Support/regcclass.h b/contrib/llvm/lib/Support/regcclass.h index 2cea3e4..7fd6604 100644 --- a/contrib/llvm/lib/Support/regcclass.h +++ b/contrib/llvm/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/contrib/llvm/lib/Support/regcname.h b/contrib/llvm/lib/Support/regcname.h index 3c0bb24..891d255 100644 --- a/contrib/llvm/lib/Support/regcname.h +++ b/contrib/llvm/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/contrib/llvm/lib/Support/regcomp.c b/contrib/llvm/lib/Support/regcomp.c index 74d9186..0b5b765 100644 --- a/contrib/llvm/lib/Support/regcomp.c +++ b/contrib/llvm/lib/Support/regcomp.c @@ -532,10 +532,10 @@ p_simp_re(struct parse *p, sopno subno; # define BACKSL (1<<CHAR_BIT) - pos = HERE(); /* repetion op, if any, covers from here */ + pos = HERE(); /* repetition op, if any, covers from here */ - assert(MORE()); /* caller should have ensured this */ - c = GETNEXT(); + assert(MORE()); /* caller should have ensured this */ + c = GETNEXT(); if (c == '\\') { REQUIRE(MORE(), REG_EESCAPE); c = BACKSL | GETNEXT(); diff --git a/contrib/llvm/lib/Support/regengine.inc b/contrib/llvm/lib/Support/regengine.inc index 7e41f96..62d8c26 100644 --- a/contrib/llvm/lib/Support/regengine.inc +++ b/contrib/llvm/lib/Support/regengine.inc @@ -205,7 +205,7 @@ matcher(struct re_guts *g, const char *string, size_t nmatch, if (nmatch == 1 && !g->backrefs) break; /* no further info needed */ - /* oh my, he wants the subexpressions... */ + /* oh my, they want the subexpressions... */ if (m->pmatch == NULL) m->pmatch = (llvm_regmatch_t *)malloc((m->g->nsub + 1) * sizeof(llvm_regmatch_t)); diff --git a/contrib/llvm/lib/Support/regex2.h b/contrib/llvm/lib/Support/regex2.h index 21659c3..d81bfbc 100644 --- a/contrib/llvm/lib/Support/regex2.h +++ b/contrib/llvm/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/contrib/llvm/lib/Support/regutils.h b/contrib/llvm/lib/Support/regutils.h index d0ee100..49a975c 100644 --- a/contrib/llvm/lib/Support/regutils.h +++ b/contrib/llvm/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/contrib/llvm/lib/Support/system_error.cpp b/contrib/llvm/lib/Support/system_error.cpp deleted file mode 100644 index b22745a..0000000 --- a/contrib/llvm/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: - virtual const char* name() const LLVM_OVERRIDE; - virtual std::string message(int ev) const LLVM_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: - virtual const char* name() const LLVM_OVERRIDE; - virtual std::string message(int ev) const LLVM_OVERRIDE; - virtual error_condition default_error_condition(int ev) const LLVM_OVERRIDE; -}; - -const char* -_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 |