From 36b56886974eae4f9c5ebc96befd3e7bfe5de338 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Wed, 23 Apr 2014 16:57:46 -0700 Subject: Update to LLVM 3.5a. Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617 --- lib/Support/APFloat.cpp | 22 +- lib/Support/APInt.cpp | 2 +- lib/Support/ARMBuildAttrs.cpp | 95 +++++ lib/Support/Allocator.cpp | 159 +------ lib/Support/Android.mk | 10 +- lib/Support/Atomic.cpp | 12 - lib/Support/BlockFrequency.cpp | 31 +- lib/Support/CMakeLists.txt | 40 +- lib/Support/CommandLine.cpp | 60 +-- lib/Support/Compression.cpp | 13 +- lib/Support/ConstantRange.cpp | 734 --------------------------------- lib/Support/CrashRecoveryContext.cpp | 8 +- lib/Support/DAGDeltaAlgorithm.cpp | 6 +- lib/Support/DataStream.cpp | 2 +- lib/Support/Dwarf.cpp | 21 + lib/Support/DynamicLibrary.cpp | 4 +- lib/Support/ErrorHandling.cpp | 2 +- lib/Support/FileOutputBuffer.cpp | 22 +- lib/Support/FileUtilities.cpp | 5 +- lib/Support/GraphWriter.cpp | 3 +- lib/Support/Host.cpp | 28 +- lib/Support/LEB128.cpp | 44 ++ lib/Support/LineIterator.cpp | 68 +++ lib/Support/LockFileManager.cpp | 88 ++-- lib/Support/MemoryBuffer.cpp | 101 +++-- lib/Support/Mutex.cpp | 7 - lib/Support/Path.cpp | 182 ++++---- lib/Support/PrettyStackTrace.cpp | 2 +- lib/Support/Process.cpp | 13 - lib/Support/Regex.cpp | 22 +- lib/Support/SmallPtrSet.cpp | 78 +++- lib/Support/SourceMgr.cpp | 5 +- lib/Support/Statistic.cpp | 23 +- lib/Support/StreamableMemoryObject.cpp | 23 +- lib/Support/StringRef.cpp | 1 - lib/Support/TargetRegistry.cpp | 36 +- lib/Support/ThreadLocal.cpp | 5 +- lib/Support/Threading.cpp | 2 +- lib/Support/Timer.cpp | 5 +- lib/Support/ToolOutputFile.cpp | 6 +- lib/Support/Triple.cpp | 224 +++++++--- lib/Support/Twine.cpp | 4 +- lib/Support/Unix/Host.inc | 2 +- lib/Support/Unix/Memory.inc | 15 +- lib/Support/Unix/Path.inc | 207 ++++------ lib/Support/Unix/Process.inc | 6 +- lib/Support/Unix/Program.inc | 6 +- lib/Support/Unix/RWMutex.inc | 20 +- lib/Support/Unix/Signals.inc | 2 +- lib/Support/Valgrind.cpp | 14 +- lib/Support/Windows/DynamicLibrary.inc | 2 +- lib/Support/Windows/Host.inc | 4 +- lib/Support/Windows/Memory.inc | 2 +- lib/Support/Windows/Mutex.inc | 2 +- lib/Support/Windows/Path.inc | 355 +++++----------- lib/Support/Windows/Process.inc | 24 +- lib/Support/Windows/Program.inc | 12 +- lib/Support/Windows/RWMutex.inc | 2 +- lib/Support/Windows/Signals.inc | 8 +- lib/Support/Windows/ThreadLocal.inc | 2 +- lib/Support/Windows/TimeValue.inc | 2 +- lib/Support/Windows/Windows.h | 168 -------- lib/Support/Windows/WindowsSupport.h | 172 ++++++++ lib/Support/YAMLParser.cpp | 59 +-- lib/Support/YAMLTraits.cpp | 17 +- lib/Support/raw_ostream.cpp | 13 +- lib/Support/regcomp.c | 6 +- lib/Support/system_error.cpp | 10 +- 68 files changed, 1402 insertions(+), 1948 deletions(-) create mode 100644 lib/Support/ARMBuildAttrs.cpp delete mode 100644 lib/Support/ConstantRange.cpp create mode 100644 lib/Support/LEB128.cpp create mode 100644 lib/Support/LineIterator.cpp delete mode 100644 lib/Support/Windows/Windows.h create mode 100644 lib/Support/Windows/WindowsSupport.h (limited to 'lib/Support') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 676e2d4..85ce31b 100644 --- a/lib/Support/APFloat.cpp +++ b/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(); @@ -3776,7 +3794,7 @@ APFloat::opStatus APFloat::next(bool nextDown) { // change the payload. if (isSignaling()) { result = opInvalidOp; - // For consistency, propogate the sign of the sNaN to the qNaN. + // For consistency, propagate the sign of the sNaN to the qNaN. makeNaN(false, isNegative(), 0); } break; @@ -3816,7 +3834,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/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 89f96bd..0c46725 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -1096,7 +1096,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) { diff --git a/lib/Support/ARMBuildAttrs.cpp b/lib/Support/ARMBuildAttrs.cpp new file mode 100644 index 0000000..960a0f1 --- /dev/null +++ b/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(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/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp index 6e7a541..7e17748 100644 --- a/lib/Support/Allocator.cpp +++ b/lib/Support/Allocator.cpp @@ -21,142 +21,22 @@ 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; +SlabAllocator::~SlabAllocator() { } - Ptr = AlignPtr((char*)(NewSlab + 1), Alignment); - assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size); - __msan_allocated_memory(Ptr, Size); - return Ptr; - } +MallocSlabAllocator::~MallocSlabAllocator() { } - // 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; +MemSlab *MallocSlabAllocator::Allocate(size_t Size) { + MemSlab *Slab = (MemSlab*)Allocator.Allocate(Size, 0); + Slab->Size = Size; + Slab->NextPtr = 0; + return Slab; } -unsigned BumpPtrAllocator::GetNumSlabs() const { - unsigned NumSlabs = 0; - for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { - ++NumSlabs; - } - return NumSlabs; +void MallocSlabAllocator::Deallocate(MemSlab *Slab) { + Allocator.Deallocate(Slab); } -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 { +void BumpPtrAllocatorBase::PrintStats() const { unsigned NumSlabs = 0; size_t TotalMemory = 0; for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { @@ -171,19 +51,12 @@ 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); +size_t BumpPtrAllocatorBase::getTotalMemory() const { + size_t TotalMemory = 0; + for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) { + TotalMemory += Slab->Size; + } + return TotalMemory; } void PrintRecyclerStats(size_t Size, diff --git a/lib/Support/Android.mk b/lib/Support/Android.mk index e4c1175..ab65988 100644 --- a/lib/Support/Android.mk +++ b/lib/Support/Android.mk @@ -5,11 +5,12 @@ support_SRC_FILES := \ APFloat.cpp \ APInt.cpp \ APSInt.cpp \ + ARMBuildAttrs.cpp \ Atomic.cpp \ BlockFrequency.cpp \ BranchProbability.cpp \ CommandLine.cpp \ - ConstantRange.cpp \ + Compression.cpp \ ConvertUTF.c \ ConvertUTFWrapper.cpp \ CrashRecoveryContext.cpp \ @@ -33,6 +34,8 @@ support_SRC_FILES := \ IntrusiveRefCntPtr.cpp \ IsInf.cpp \ IsNAN.cpp \ + LEB128.cpp \ + LineIterator.cpp \ Locale.cpp \ LockFileManager.cpp \ MD5.cpp \ @@ -71,6 +74,8 @@ support_SRC_FILES := \ Unicode.cpp \ Valgrind.cpp \ Watchdog.cpp \ + YAMLParser.cpp \ + YAMLTraits.cpp \ circular_raw_ostream.cpp \ raw_os_ostream.cpp \ raw_ostream.cpp \ @@ -81,6 +86,7 @@ support_SRC_FILES := \ regstrlcpy.c \ system_error.cpp + # For the host # ===================================================== include $(CLEAR_VARS) @@ -101,6 +107,7 @@ include $(BUILD_HOST_STATIC_LIBRARY) # For the device # ===================================================== +ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS)) include $(CLEAR_VARS) LOCAL_SRC_FILES := $(support_SRC_FILES) @@ -113,3 +120,4 @@ LOCAL_MODULE_TAGS := optional include $(LLVM_DEVICE_BUILD_MK) include $(BUILD_STATIC_LIBRARY) +endif diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp index 13d16d4..9559ad7 100644 --- a/lib/Support/Atomic.cpp +++ b/lib/Support/Atomic.cpp @@ -13,9 +13,6 @@ #include "llvm/Support/Atomic.h" #include "llvm/Config/llvm-config.h" -#if defined(ANDROID_TARGET_BUILD) -#include "cutils/atomic.h" -#endif using namespace llvm; @@ -50,9 +47,6 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, if (result == old_value) *ptr = new_value; return result; -#elif defined(ANDROID_TARGET_BUILD) - return android_atomic_cmpxchg((int32_t)old_value, (int32_t)new_value, - (volatile int*)ptr); #elif defined(GNU_ATOMICS) return __sync_val_compare_and_swap(ptr, old_value, new_value); #elif defined(_MSC_VER) @@ -66,8 +60,6 @@ sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { #if LLVM_HAS_ATOMICS == 0 ++(*ptr); return *ptr; -#elif defined(ANDROID_TARGET_BUILD) - return android_atomic_inc((volatile int*)ptr); #elif defined(GNU_ATOMICS) return __sync_add_and_fetch(ptr, 1); #elif defined(_MSC_VER) @@ -81,8 +73,6 @@ sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { #if LLVM_HAS_ATOMICS == 0 --(*ptr); return *ptr; -#elif defined(ANDROID_TARGET_BUILD) - return android_atomic_dec((volatile int*)ptr); #elif defined(GNU_ATOMICS) return __sync_sub_and_fetch(ptr, 1); #elif defined(_MSC_VER) @@ -96,8 +86,6 @@ sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) { #if LLVM_HAS_ATOMICS == 0 *ptr += val; return *ptr; -#elif defined(ANDROID_TARGET_BUILD) - return android_atomic_add((int32_t)val, (volatile int*)ptr); #elif defined(GNU_ATOMICS) return __sync_add_and_fetch(ptr, val); #elif defined(_MSC_VER) diff --git a/lib/Support/BlockFrequency.cpp b/lib/Support/BlockFrequency.cpp index 00efe90..00cf75b 100644 --- a/lib/Support/BlockFrequency.cpp +++ b/lib/Support/BlockFrequency.cpp @@ -145,28 +145,19 @@ 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 { + // Shift right by count. + Frequency >>= count; -raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) { - Freq.print(OS); - return OS; + // Saturate to 1 if we are 0. + Frequency |= Frequency == 0; + return *this; } +uint32_t BlockFrequency::scale(const BranchProbability &Prob) { + return scale(Prob.getNumerator(), Prob.getDenominator()); } + diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 3aecf3f..b4c674d 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -2,13 +2,13 @@ add_llvm_library(LLVMSupport APFloat.cpp APInt.cpp APSInt.cpp + ARMBuildAttrs.cpp Allocator.cpp BlockFrequency.cpp BranchProbability.cpp circular_raw_ostream.cpp CommandLine.cpp Compression.cpp - ConstantRange.cpp ConvertUTF.c ConvertUTFWrapper.cpp CrashRecoveryContext.cpp @@ -30,6 +30,8 @@ add_llvm_library(LLVMSupport IntrusiveRefCntPtr.cpp IsInf.cpp IsNAN.cpp + LEB128.cpp + LineIterator.cpp Locale.cpp LockFileManager.cpp ManagedStatic.cpp @@ -87,6 +89,8 @@ add_llvm_library(LLVMSupport TimeValue.cpp Valgrind.cpp Watchdog.cpp + + ADDITIONAL_HEADERS Unix/Host.inc Unix/Memory.inc Unix/Mutex.inc @@ -113,3 +117,37 @@ add_llvm_library(LLVMSupport Windows/TimeValue.inc Windows/Watchdog.inc ) +set(system_libs) +if( NOT MSVC ) + if( MINGW ) + set(system_libs ${system_libs} imagehlp psapi shell32) + elseif( CMAKE_HOST_UNIX ) + if( HAVE_LIBRT ) + set(system_libs ${system_libs} rt) + endif() + if( HAVE_LIBDL ) + set(system_libs ${system_libs} ${CMAKE_DL_LIBS}) + endif() + if(LLVM_ENABLE_TERMINFO) + if(HAVE_TERMINFO) + set(system_libs ${system_libs} ${TERMINFO_LIBS}) + endif() + endif() + if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD ) + set(system_libs ${system_libs} pthread) + endif() + if ( LLVM_ENABLE_ZLIB AND HAVE_LIBZ ) + set(system_libs ${system_libs} z) + endif() + endif( MINGW ) +endif( NOT MSVC ) + + +if(POLICY CMP0022 AND BUILD_SHARED_LIBS) + # FIXME: Should this be really PUBLIC? + target_link_libraries(LLVMSupport PUBLIC ${system_libs}) +else() + target_link_libraries(LLVMSupport ${cmake_2_8_12_INTERFACE} ${system_libs}) +endif() + +set_property(TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS "${system_libs}") diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 44a88d8..b3c2614 100644 --- a/lib/Support/CommandLine.cpp +++ b/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" @@ -111,6 +110,13 @@ void Option::addArgument() { MarkOptionsChanged(); } +void Option::removeArgument() { + assert(NextRegistered != 0 && "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 OptionCatSet; static ManagedStatic RegisteredOptionCategories; @@ -118,8 +124,13 @@ static ManagedStatic 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); } @@ -246,12 +257,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) { @@ -312,13 +322,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 +339,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; @@ -609,7 +619,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, static bool ExpandResponseFile(const char *FName, StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl &NewArgv) { - OwningPtr MemBuf; + std::unique_ptr MemBuf; if (MemoryBuffer::getFile(FName, MemBuf)) return false; StringRef Str(MemBuf->getBufferStart(), MemBuf->getBufferSize()); @@ -634,7 +644,7 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver, bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl &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 +665,10 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, // the cwd of the process or the response file? SmallVector 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 +688,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; @@ -1474,7 +1487,7 @@ public: MoreHelp->clear(); // Halt the program since help information was printed - exit(1); + exit(0); } }; @@ -1486,25 +1499,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 SortedCategories; std::map > 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!"); @@ -1711,7 +1723,7 @@ public: if (OverrideVersionPrinter != 0) { (*OverrideVersionPrinter)(); - exit(1); + exit(0); } print(); @@ -1725,7 +1737,7 @@ public: (*I)(); } - exit(1); + exit(0); } }; } // End anonymous namespace diff --git a/lib/Support/Compression.cpp b/lib/Support/Compression.cpp index b5ddb70..5e53361 100644 --- a/lib/Support/Compression.cpp +++ b/lib/Support/Compression.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #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" @@ -48,10 +47,10 @@ static zlib::Status encodeZlibReturnValue(int ReturnValue) { bool zlib::isAvailable() { return true; } zlib::Status zlib::compress(StringRef InputBuffer, - OwningPtr &CompressedBuffer, + std::unique_ptr &CompressedBuffer, CompressionLevel Level) { unsigned long CompressedSize = ::compressBound(InputBuffer.size()); - OwningArrayPtr TmpBuffer(new char[CompressedSize]); + std::unique_ptr TmpBuffer(new char[CompressedSize]); int CLevel = encodeZlibCompressionLevel(Level); Status Res = encodeZlibReturnValue(::compress2( (Bytef *)TmpBuffer.get(), &CompressedSize, @@ -66,9 +65,9 @@ zlib::Status zlib::compress(StringRef InputBuffer, } zlib::Status zlib::uncompress(StringRef InputBuffer, - OwningPtr &UncompressedBuffer, + std::unique_ptr &UncompressedBuffer, size_t UncompressedSize) { - OwningArrayPtr TmpBuffer(new char[UncompressedSize]); + std::unique_ptr TmpBuffer(new char[UncompressedSize]); Status Res = encodeZlibReturnValue( ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize, (const Bytef *)InputBuffer.data(), InputBuffer.size())); @@ -88,12 +87,12 @@ uint32_t zlib::crc32(StringRef Buffer) { #else bool zlib::isAvailable() { return false; } zlib::Status zlib::compress(StringRef InputBuffer, - OwningPtr &CompressedBuffer, + std::unique_ptr &CompressedBuffer, CompressionLevel Level) { return zlib::StatusUnsupported; } zlib::Status zlib::uncompress(StringRef InputBuffer, - OwningPtr &UncompressedBuffer, + std::unique_ptr &UncompressedBuffer, size_t UncompressedSize) { return zlib::StatusUnsupported; } diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp deleted file mode 100644 index 265b6e9..0000000 --- a/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 - // - 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/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index 92c370d..ccc0089 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -132,7 +132,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 @@ -334,8 +334,8 @@ const std::string &CrashRecoveryContext::getBacktrace() const { namespace { struct RunSafelyOnThreadInfo { - void (*UserFn)(void*); - void *UserData; + void (*Fn)(void*); + void *Data; CrashRecoveryContext *CRC; bool Result; }; @@ -344,7 +344,7 @@ struct RunSafelyOnThreadInfo { static void RunSafelyOnThread_Dispatch(void *UserData) { RunSafelyOnThreadInfo *Info = reinterpret_cast(UserData); - Info->Result = Info->CRC->RunSafely(Info->UserFn, Info->UserData); + Info->Result = Info->CRC->RunSafely(Info->Fn, Info->Data); } bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData, unsigned RequestedStackSize) { diff --git a/lib/Support/DAGDeltaAlgorithm.cpp b/lib/Support/DAGDeltaAlgorithm.cpp index 34e82cf..29acb7d 100644 --- a/lib/Support/DAGDeltaAlgorithm.cpp +++ b/lib/Support/DAGDeltaAlgorithm.cpp @@ -162,12 +162,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/lib/Support/DataStream.cpp b/lib/Support/DataStream.cpp index 0bd0c68..1caeddf 100644 --- a/lib/Support/DataStream.cpp +++ b/lib/Support/DataStream.cpp @@ -58,7 +58,7 @@ 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); } diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp index c000b63..6604cc7 100644 --- a/lib/Support/Dwarf.cpp +++ b/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"; @@ -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"; @@ -576,6 +589,14 @@ 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"; } diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp index a825c68..5d77153 100644 --- a/lib/Support/DynamicLibrary.cpp +++ b/lib/Support/DynamicLibrary.cpp @@ -14,12 +14,12 @@ //===----------------------------------------------------------------------===// #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 #include diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp index 1eafb96..1aa8303 100644 --- a/lib/Support/ErrorHandling.cpp +++ b/lib/Support/ErrorHandling.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #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" @@ -20,7 +21,6 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" -#include "llvm-c/Core.h" #include #include diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp index ed084fa..8f2c9fc 100644 --- a/lib/Support/FileOutputBuffer.cpp +++ b/lib/Support/FileOutputBuffer.cpp @@ -28,13 +28,12 @@ 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 &Result, + std::unique_ptr &Result, unsigned Flags) { // If file already exists, it must be a regular file (to be mappable). sys::fs::file_status Stat; @@ -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,18 +73,28 @@ error_code FileOutputBuffer::create(StringRef FilePath, if (EC) return EC; - OwningPtr MappedFile(new mapped_file_region( + std::unique_ptr 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(); } +error_code FileOutputBuffer::create(StringRef FilePath, + size_t Size, + OwningPtr &Result, + unsigned Flags) { + std::unique_ptr FOB; + error_code ec = create(FilePath, Size, FOB, Flags); + Result = std::move(FOB); + return ec; +} + error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { // Unmap buffer, letting OS flush dirty pages to file on disk. Region.reset(0); diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp index 7f5d540..b2dc47d 100644 --- a/lib/Support/FileUtilities.cpp +++ b/lib/Support/FileUtilities.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #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" @@ -177,13 +176,13 @@ 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 F1; + std::unique_ptr F1; if (error_code ec = MemoryBuffer::getFile(NameA, F1)) { if (Error) *Error = ec.message(); return 2; } - OwningPtr F2; + std::unique_ptr F2; if (error_code ec = MemoryBuffer::getFile(NameB, F2)) { if (Error) *Error = ec.message(); diff --git a/lib/Support/GraphWriter.cpp b/lib/Support/GraphWriter.cpp index 85be415..83aa255 100644 --- a/lib/Support/GraphWriter.cpp +++ b/lib/Support/GraphWriter.cpp @@ -87,8 +87,7 @@ ExecGraphViewer(StringRef ExecPath, std::vector &args, errs() << "Error: " << ErrMsg << "\n"; return false; } - bool Existed; - sys::fs::remove(Filename, Existed); + sys::fs::remove(Filename); errs() << " done. \n"; } else { diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index 6e9a5c9..b6e2cb1 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -98,8 +98,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 +193,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"; @@ -448,7 +449,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 +478,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. @@ -567,7 +568,7 @@ std::string sys::getHostCPUName() { .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 +620,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(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,7 +676,7 @@ std::string sys::getHostCPUName() { return "generic"; } #else -std::string sys::getHostCPUName() { +StringRef sys::getHostCPUName() { return "generic"; } #endif diff --git a/lib/Support/LEB128.cpp b/lib/Support/LEB128.cpp new file mode 100644 index 0000000..449626f --- /dev/null +++ b/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/lib/Support/LineIterator.cpp b/lib/Support/LineIterator.cpp new file mode 100644 index 0000000..056d817 --- /dev/null +++ b/lib/Support/LineIterator.cpp @@ -0,0 +1,68 @@ +//===- 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 : 0), + CommentMarker(CommentMarker), LineNumber(1), + CurrentLine(Buffer.getBufferSize() ? Buffer.getBufferStart() : 0, 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 = 0; + 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/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp index eeec274..cd1cbcb 100644 --- a/lib/Support/LockFileManager.cpp +++ b/lib/Support/LockFileManager.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -29,21 +30,17 @@ using namespace llvm; /// \returns The process ID of the process that owns this lock file Optional > 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 MB; - if (MemoryBuffer::getFile(LockFileName, MB)) + std::unique_ptr MB; + if (MemoryBuffer::getFile(LockFileName, MB)) { + sys::fs::remove(LockFileName); return None; + } 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)) @@ -71,7 +68,11 @@ bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) { LockFileManager::LockFileManager(StringRef FileName) { this->FileName = FileName; - LockFileName = FileName; + if (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 @@ -111,41 +112,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. + error_code EC = + sys::fs::create_link(UniqueLockFileName.str(), LockFileName.str()); + if (EC == errc::success) + 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,9 +167,8 @@ 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() { @@ -192,23 +195,22 @@ void LockFileManager::waitForUnlock() { #else nanosleep(&Interval, NULL); #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) { + if (sys::fs::exists(FileName.str())) { return; } diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index dcd5529..2d593a8 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -91,12 +91,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(this + 1); } - virtual BufferKind getBufferKind() const LLVM_OVERRIDE { + BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; } }; @@ -131,9 +131,10 @@ 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(operator new(RealLen, std::nothrow)); if (!Mem) return 0; @@ -165,13 +166,23 @@ MemoryBuffer *MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { /// in *ErrStr with a reason. If stdin is empty, this API (unlike getSTDIN) /// returns an empty buffer. error_code MemoryBuffer::getFileOrSTDIN(StringRef Filename, - OwningPtr &result, + std::unique_ptr &Result, int64_t FileSize) { if (Filename == "-") - return getSTDIN(result); - return getFile(Filename, result, FileSize); + return getSTDIN(Result); + return getFile(Filename, Result, FileSize); } +error_code MemoryBuffer::getFileOrSTDIN(StringRef Filename, + OwningPtr &Result, + int64_t FileSize) { + std::unique_ptr MB; + error_code ec = getFileOrSTDIN(Filename, MB, FileSize); + Result = std::move(MB); + return ec; +} + + //===----------------------------------------------------------------------===// // MemoryBuffer::getFile implementation. //===----------------------------------------------------------------------===// @@ -206,12 +217,12 @@ public: } } - virtual const char *getBufferIdentifier() const LLVM_OVERRIDE { + const char *getBufferIdentifier() const override { // The name is stored after the class itself. return reinterpret_cast(this + 1); } - virtual BufferKind getBufferKind() const LLVM_OVERRIDE { + BufferKind getBufferKind() const override { return MemoryBuffer_MMap; } }; @@ -219,7 +230,7 @@ public: static error_code getMemoryBufferForStream(int FD, StringRef BufferName, - OwningPtr &result) { + std::unique_ptr &Result) { const ssize_t ChunkSize = 4096*4; SmallString Buffer; ssize_t ReadBytes; @@ -234,39 +245,50 @@ static error_code getMemoryBufferForStream(int FD, Buffer.set_size(Buffer.size() + ReadBytes); } while (ReadBytes != 0); - result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); + Result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName)); return error_code::success(); } static error_code getFileAux(const char *Filename, - OwningPtr &result, int64_t FileSize, + std::unique_ptr &Result, + int64_t FileSize, bool RequiresNullTerminator); error_code MemoryBuffer::getFile(Twine Filename, - OwningPtr &result, + std::unique_ptr &Result, int64_t FileSize, bool RequiresNullTerminator) { // Ensure the path is null terminated. SmallString<256> PathBuf; StringRef NullTerminatedName = Filename.toNullTerminatedStringRef(PathBuf); - return getFileAux(NullTerminatedName.data(), result, FileSize, + return getFileAux(NullTerminatedName.data(), Result, FileSize, RequiresNullTerminator); } +error_code MemoryBuffer::getFile(Twine Filename, + OwningPtr &Result, + int64_t FileSize, + bool RequiresNullTerminator) { + std::unique_ptr MB; + error_code ec = getFile(Filename, MB, FileSize, RequiresNullTerminator); + Result = std::move(MB); + return ec; +} + static error_code getOpenFileImpl(int FD, const char *Filename, - OwningPtr &Result, + std::unique_ptr &Result, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator); static error_code getFileAux(const char *Filename, - OwningPtr &result, int64_t FileSize, + std::unique_ptr &Result, int64_t FileSize, bool RequiresNullTerminator) { int FD; error_code EC = sys::fs::openFileForRead(Filename, FD); if (EC) return EC; - error_code ret = getOpenFileImpl(FD, Filename, result, FileSize, FileSize, 0, + error_code ret = getOpenFileImpl(FD, Filename, Result, FileSize, FileSize, 0, RequiresNullTerminator); close(FD); return ret; @@ -324,7 +346,7 @@ static bool shouldUseMmap(int FD, } static error_code getOpenFileImpl(int FD, const char *Filename, - OwningPtr &result, + std::unique_ptr &Result, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator) { static int PageSize = sys::process::get_self()->page_size(); @@ -345,7 +367,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, Result); FileSize = Status.getSize(); } @@ -355,7 +377,7 @@ 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( + Result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile( RequiresNullTerminator, FD, MapSize, Offset, EC)); if (!EC) return error_code::success(); @@ -368,7 +390,7 @@ static error_code getOpenFileImpl(int FD, const char *Filename, return make_error_code(errc::not_enough_memory); } - OwningPtr SB(Buf); + std::unique_ptr SB(Buf); char *BufPtr = const_cast(SB->getBufferStart()); size_t BytesLeft = MapSize; @@ -399,34 +421,61 @@ static error_code getOpenFileImpl(int FD, const char *Filename, BufPtr += NumRead; } - result.swap(SB); + Result.swap(SB); return error_code::success(); } error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, - OwningPtr &Result, + std::unique_ptr &Result, uint64_t FileSize, bool RequiresNullTerminator) { return getOpenFileImpl(FD, Filename, Result, FileSize, FileSize, 0, RequiresNullTerminator); } +error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, + OwningPtr &Result, + uint64_t FileSize, + bool RequiresNullTerminator) { + std::unique_ptr MB; + error_code ec = getOpenFileImpl(FD, Filename, MB, FileSize, FileSize, 0, + RequiresNullTerminator); + Result = std::move(MB); + return ec; +} + error_code MemoryBuffer::getOpenFileSlice(int FD, const char *Filename, - OwningPtr &Result, + std::unique_ptr &Result, uint64_t MapSize, int64_t Offset) { return getOpenFileImpl(FD, Filename, Result, -1, MapSize, Offset, false); } +error_code MemoryBuffer::getOpenFileSlice(int FD, const char *Filename, + OwningPtr &Result, + uint64_t MapSize, int64_t Offset) { + std::unique_ptr MB; + error_code ec = getOpenFileImpl(FD, Filename, MB, -1, MapSize, Offset, false); + Result = std::move(MB); + return ec; +} + //===----------------------------------------------------------------------===// // MemoryBuffer::getSTDIN implementation. //===----------------------------------------------------------------------===// -error_code MemoryBuffer::getSTDIN(OwningPtr &result) { +error_code MemoryBuffer::getSTDIN(std::unique_ptr &Result) { // 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, "", result); + return getMemoryBufferForStream(0, "", Result); +} + +error_code MemoryBuffer::getSTDIN(OwningPtr &Result) { + std::unique_ptr MB; + error_code ec = getSTDIN(MB); + Result = std::move(MB); + return ec; } diff --git a/lib/Support/Mutex.cpp b/lib/Support/Mutex.cpp index 4e4a026..37c9d73 100644 --- a/lib/Support/Mutex.cpp +++ b/lib/Support/Mutex.cpp @@ -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); diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp index c869b30..5b73631 100644 --- a/lib/Support/Path.cpp +++ b/lib/Support/Path.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Process.h" #include #include #include @@ -26,16 +27,18 @@ #include #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 +164,75 @@ enum FSEntity { }; // Implemented in Unix/Path.inc and Windows/Path.inc. -static llvm::error_code -createUniqueEntity(const llvm::Twine &Model, int &ResultFD, - llvm::SmallVectorImpl &ResultPath, - bool MakeAbsolute, unsigned Mode, FSEntity Type); +static error_code TempDir(SmallVectorImpl &result); + +static error_code createUniqueEntity(const Twine &Model, int &ResultFD, + SmallVectorImpl &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 (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 (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 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(); + } + + case FS_Dir: { + if (error_code EC = sys::fs::create_directory(ResultPath.begin(), false)) { + if (EC == errc::file_exists) + goto retry_random_path; + return EC; + } + return error_code::success(); + } + } + llvm_unreachable("Invalid Type"); +} namespace llvm { namespace sys { @@ -239,21 +307,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 +468,7 @@ void append(SmallVectorImpl &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()); @@ -507,8 +572,9 @@ bool is_separator(char value) { void system_temp_directory(bool erasedOnReboot, SmallVectorImpl &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 on darwin >= 9 int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR : _CS_DARWIN_USER_CACHE_DIR; size_t ConfLen = confstr(ConfName, 0, 0); @@ -749,20 +815,27 @@ error_code make_absolute(SmallVectorImpl &path) { "occurred above!"); } -error_code create_directories(const Twine &path, bool &existed) { - SmallString<128> path_storage; - StringRef p = path.toStringRef(path_storage); +error_code create_directories(const Twine &Path, bool IgnoreExisting) { + SmallString<128> PathStorage; + StringRef P = Path.toStringRef(PathStorage); - StringRef parent = path::parent_path(p); - if (!parent.empty()) { - bool parent_exists; - if (error_code ec = fs::exists(parent, parent_exists)) return ec; + // Be optimistic and try to create the directory + 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; - if (!parent_exists) - if (error_code ec = create_directories(parent, existed)) 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; - return create_directory(p, existed); + if ((EC = create_directories(Parent))) + return EC; + + return create_directory(P, IgnoreExisting); } bool exists(file_status status) { @@ -797,23 +870,10 @@ error_code is_regular_file(const Twine &path, bool &result) { 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(); -} - 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) { @@ -943,6 +1003,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; @@ -983,45 +1044,6 @@ error_code identify_magic(const Twine &path, file_magic &result) { 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 - -error_code remove_all(const Twine &path, uint32_t &num_removed) { - SmallString<128> path_storage; - StringRef p = path.toStringRef(path_storage); - - file_status fs; - if (error_code ec = status(path, fs)) - return ec; - num_removed = 0; - return remove_all_r(p, fs.type(), num_removed); -} - error_code directory_entry::status(file_status &result) const { return fs::status(Path, result); } diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp index 722f4ca..d4e205c 100644 --- a/lib/Support/PrettyStackTrace.cpp +++ b/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 diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp index d5168f0..0380ed9 100644 --- a/lib/Support/Process.cpp +++ b/lib/Support/Process.cpp @@ -34,14 +34,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 @@ -75,11 +67,6 @@ TimeValue self_process::get_wall_time() const { } -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - - #define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m" #define ALLCOLORS(FGBG,BOLD) {\ diff --git a/lib/Support/Regex.cpp b/lib/Support/Regex.cpp index 5413641..1115534 100644 --- a/lib/Support/Regex.cpp +++ b/lib/Support/Regex.cpp @@ -33,8 +33,10 @@ 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) { @@ -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/lib/Support/SmallPtrSet.cpp b/lib/Support/SmallPtrSet.cpp index dd417b4..844e416 100644 --- a/lib/Support/SmallPtrSet.cpp +++ b/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,7 +98,7 @@ 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::getHashValue(Ptr) & (CurArraySize-1); unsigned ArraySize = CurArraySize; unsigned ProbeAmt = 1; @@ -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/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp index d4b94f8..4bfd96a 100644 --- a/lib/Support/SourceMgr.cpp +++ b/lib/Support/SourceMgr.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #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" @@ -55,7 +54,7 @@ SourceMgr::~SourceMgr() { size_t SourceMgr::AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile) { - OwningPtr NewBuf; + std::unique_ptr NewBuf; IncludedFile = Filename; MemoryBuffer::getFile(IncludedFile.c_str(), NewBuf); @@ -67,7 +66,7 @@ size_t SourceMgr::AddIncludeFile(const std::string &Filename, if (!NewBuf) return ~0U; - return AddNewSourceBuffer(NewBuf.take(), IncludeLoc); + return AddNewSourceBuffer(NewBuf.release(), IncludeLoc); } diff --git a/lib/Support/Statistic.cpp b/lib/Support/Statistic.cpp index 9c28176..56c3b0f 100644 --- a/lib/Support/Statistic.cpp +++ b/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/lib/Support/StreamableMemoryObject.cpp b/lib/Support/StreamableMemoryObject.cpp index 2ed7c5c..5cb0680 100644 --- a/lib/Support/StreamableMemoryObject.cpp +++ b/lib/Support/StreamableMemoryObject.cpp @@ -10,6 +10,7 @@ #include "llvm/Support/StreamableMemoryObject.h" #include "llvm/Support/Compiler.h" #include +#include #include @@ -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(address) < LastChar - FirstChar; + return static_cast(address) < LastChar - FirstChar; } bool objectEnd(uint64_t address) const { - return static_cast(address) == LastChar - FirstChar; + return static_cast(address) == LastChar - FirstChar; } RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION; diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index bfae754..bd2a37b 100644 --- a/lib/Support/StringRef.cpp +++ b/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 diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index 0c90c17..8d91a53 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -71,42 +71,34 @@ const Target *TargetRegistry::lookupTarget(const std::string &TT, Error = "Unable to find target for this triple (no targets are registered)"; return 0; } - const Target *Best = 0, *EquallyBest = 0; - unsigned BestQuality = 0; + const Target *Matching = 0; + 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 0; + } + Matching = &*it; } } - if (!Best) { + if (!Matching) { Error = "No available targets are compatible with this triple, " "see -version for the available targets."; return 0; } - // 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,7 +112,7 @@ void TargetRegistry::RegisterTarget(Target &T, T.Name = Name; T.ShortDesc = ShortDesc; - T.TripleMatchQualityFn = TQualityFn; + T.ArchMatchFn = ArchMatchFn; T.HasJIT = HasJIT; } diff --git a/lib/Support/ThreadLocal.cpp b/lib/Support/ThreadLocal.cpp index 868b6ea..aebbcad 100644 --- a/lib/Support/ThreadLocal.cpp +++ b/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(&data); *pd = const_cast(d); } @@ -50,7 +51,7 @@ 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(&data); int errorcode = pthread_key_create(key, NULL); assert(errorcode == 0); diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp index 13fba2e..9d7ac6c 100644 --- a/lib/Support/Threading.cpp +++ b/lib/Support/Threading.cpp @@ -103,7 +103,7 @@ void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, ::pthread_attr_destroy(&Attr); } #elif LLVM_ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32) -#include "Windows/Windows.h" +#include "Windows/WindowsSupport.h" #include struct ThreadInfo { diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp index 100b21e..7cf4d37 100644 --- a/lib/Support/Timer.cpp +++ b/lib/Support/Timer.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #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" @@ -66,8 +65,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; diff --git a/lib/Support/ToolOutputFile.cpp b/lib/Support/ToolOutputFile.cpp index 5c1268a..b5fb20f 100644 --- a/lib/Support/ToolOutputFile.cpp +++ b/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/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 6c978a0..71abb9d 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -19,32 +19,36 @@ 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 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"; } llvm_unreachable("Invalid ArchType!"); @@ -55,40 +59,46 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { default: return 0; - case aarch64: return "aarch64"; + case aarch64: + case aarch64_be: return "aarch64"; case arm: - case thumb: return "arm"; + case armeb: + case thumb: + case thumbeb: return "arm"; + + case arm64: return "arm64"; 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"; } } @@ -127,7 +137,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 +159,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 +174,10 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) { Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { return StringSwitch(Name) .Case("aarch64", aarch64) + .Case("aarch64_be", aarch64_be) .Case("arm", arm) + .Case("armeb", armeb) + .Case("arm64", arm64) .Case("mips", mips) .Case("mipsel", mipsel) .Case("mips64", mips64) @@ -178,6 +194,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) @@ -206,6 +223,8 @@ 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("r600", "r600") .Case("nvptx", "nvptx") .Case("nvptx64", "nvptx64") @@ -226,12 +245,18 @@ 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("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) .Cases("mipsel", "mipsallegrexel", Triple::mipsel) @@ -283,6 +308,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 +323,46 @@ static Triple::OSType parseOS(StringRef OSName) { static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { return StringSwitch(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(EnvironmentName) + .EndsWith("coff", Triple::COFF) + .EndsWith("elf", Triple::ELF) + .EndsWith("macho", Triple::MachO) + .Default(Triple::UnknownObjectFormat); +} + +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 @@ -317,7 +372,10 @@ Triple::Triple(const Twine &Str) Arch(parseArch(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, @@ -331,7 +389,8 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) Arch(parseArch(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, @@ -346,7 +405,10 @@ Triple::Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, Arch(parseArch(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 +433,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 +477,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 +543,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 +695,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 +728,15 @@ void Triple::setEnvironment(EnvironmentType Kind) { setEnvironmentName(getEnvironmentTypeName(Kind)); } +void Triple::setObjectFormat(ObjectFormatType Kind) { + if (Environment == UnknownEnvironment) + return setEnvironmentName(getObjectFormatTypeName(Kind)); + + Twine Env = getEnvironmentTypeName(Environment) + Twine("-") + + getObjectFormatTypeName(Kind); + setEnvironmentName(Env.str()); +} + void Triple::setArchName(StringRef Str) { // Work around a miscompilation bug for Twines in gcc 4.0.3. SmallString<64> Triple; @@ -675,6 +779,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 +790,15 @@ 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: return 32; + case llvm::Triple::arm64: case llvm::Triple::aarch64: + case llvm::Triple::aarch64_be: case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::nvptx64: @@ -722,6 +830,8 @@ Triple Triple::get32BitArchVariant() const { switch (getArch()) { case Triple::UnknownArch: case Triple::aarch64: + case Triple::aarch64_be: + case Triple::arm64: case Triple::msp430: case Triple::systemz: case Triple::ppc64le: @@ -731,6 +841,7 @@ Triple Triple::get32BitArchVariant() const { case Triple::amdil: case Triple::spir: case Triple::arm: + case Triple::armeb: case Triple::hexagon: case Triple::le32: case Triple::mips: @@ -741,6 +852,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 +861,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 +875,20 @@ Triple Triple::get64BitArchVariant() const { case Triple::UnknownArch: case Triple::amdil: case Triple::arm: + case Triple::armeb: case Triple::hexagon: 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 +898,7 @@ Triple Triple::get64BitArchVariant() const { case Triple::sparcv9: case Triple::systemz: case Triple::x86_64: + case Triple::arm64: // Already 64-bit. break; diff --git a/lib/Support/Twine.cpp b/lib/Support/Twine.cpp index 3d04bc3..56ed964 100644 --- a/lib/Support/Twine.cpp +++ b/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/lib/Support/Unix/Host.inc b/lib/Support/Unix/Host.inc index 726e2fb..c5d36ff 100644 --- a/lib/Support/Unix/Host.inc +++ b/lib/Support/Unix/Host.inc @@ -59,5 +59,5 @@ std::string sys::getDefaultTargetTriple() { Triple += getOSVersion(); } - return Triple; + return Triple::normalize(Triple); } diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc index 58fda42..08cd34d 100644 --- a/lib/Support/Unix/Memory.inc +++ b/lib/Support/Unix/Memory.inc @@ -205,7 +205,7 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, void* start = NearBlock ? (unsigned char*)NearBlock->base() + NearBlock->size() : 0; -#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 @@ -220,7 +220,7 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, 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); @@ -253,7 +253,7 @@ bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { } 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(Addr), Len); # endif diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index c9dc871..1c91053 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -17,7 +17,6 @@ //===----------------------------------------------------------------------===// #include "Unix.h" -#include "llvm/Support/Process.h" #include #include #if HAVE_SYS_STAT_H @@ -86,95 +85,22 @@ namespace { operator int() const {return FileDescriptor;} }; +} - error_code TempDir(SmallVectorImpl &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 error_code TempDir(SmallVectorImpl &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")) || #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(); - } -} + (dir = "/tmp"); -static error_code createUniqueEntity(const Twine &Model, int &ResultFD, - SmallVectorImpl &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(); - } - - 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 error_code::success(); } 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); } @@ -333,34 +260,34 @@ error_code current_path(SmallVectorImpl &result) { return error_code::success(); } -error_code create_directory(const Twine &path, bool &existed) { +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) + if (errno != errc::file_exists || !IgnoreExisting) return error_code(errno, system_category()); - existed = true; - } else - existed = false; + } return error_code::success(); } -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()); - +error_code normalize_separators(SmallVectorImpl &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 error_code::success(); } -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). +error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -373,15 +300,14 @@ error_code create_symlink(const Twine &to, const Twine &from) { return error_code::success(); } -error_code remove(const Twine &path, bool &existed) { +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) + if (lstat(p.begin(), &buf) != 0) { + if (errno != errc::no_such_file_or_directory || !IgnoreNonExisting) return error_code(errno, system_category()); - existed = false; return error_code::success(); } @@ -390,15 +316,13 @@ 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) + if (errno != errc::no_such_file_or_directory || !IgnoreNonExisting) return error_code(errno, system_category()); - existed = false; - } else - existed = true; + } return error_code::success(); } @@ -526,21 +450,24 @@ error_code status(int FD, file_status &Result) { 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 error_code(errno, system_category()); + return error_code::success(); #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)) -#else -#error Missing futimes() and futimens() -#endif return error_code(errno, system_category()); return error_code::success(); +#else +#warning Missing futimes() and futimens() + return make_error_code(errc::not_supported); +#endif } error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) { @@ -626,12 +553,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; } -#endif mapped_file_region::mapmode mapped_file_region::flags() const { assert(Mapping && "Mapping failed but used anyway!"); @@ -645,7 +570,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(Mapping); } @@ -773,7 +698,12 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, 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; @@ -793,5 +723,20 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, } } // end namespace fs + +namespace path { + +bool home_directory(SmallVectorImpl &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/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc index c5778e7..9fb4356 100644 --- a/lib/Support/Unix/Process.inc +++ b/lib/Support/Unix/Process.inc @@ -135,7 +135,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__) @@ -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/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 78b2971..b4df928 100644 --- a/lib/Support/Unix/Program.inc +++ b/lib/Support/Unix/Program.inc @@ -418,6 +418,7 @@ 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; @@ -433,11 +434,6 @@ error_code sys::ChangeStdoutToBinary(){ return make_error_code(errc::success); } -error_code sys::ChangeStderrToBinary(){ - // Do nothing, as Unix doesn't differentiate between text and binary. - return make_error_code(errc::success); -} - bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef Args) { static long ArgMax = sysconf(_SC_ARG_MAX); diff --git a/lib/Support/Unix/RWMutex.inc b/lib/Support/Unix/RWMutex.inc index 40e87ff..edcbd52 100644 --- a/lib/Support/Unix/RWMutex.inc +++ b/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(data_); +} bool RWMutexImpl::reader_acquire() { - return true; + return static_cast(data_)->acquire(); } bool RWMutexImpl::reader_release() { - return true; + return static_cast(data_)->release(); } bool RWMutexImpl::writer_acquire() { - return true; + return static_cast(data_)->acquire(); } bool RWMutexImpl::writer_release() { - return true; + return static_cast(data_)->release(); } } diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index 13ae862..b4c78d6 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -271,7 +271,7 @@ void llvm::sys::PrintStackTrace(FILE *FD) { // Use backtrace() to output a backtrace on Linux systems with glibc. int depth = backtrace(StackTrace, static_cast(array_lengthof(StackTrace))); -#if HAVE_DLFCN_H && HAVE_CXXABI_H && __GNUG__ +#if HAVE_DLFCN_H && __GNUG__ int width = 0; for (int i = 0; i < depth; ++i) { Dl_info dlinfo; diff --git a/lib/Support/Valgrind.cpp b/lib/Support/Valgrind.cpp index 2b250a3..2c6d6aa 100644 --- a/lib/Support/Valgrind.cpp +++ b/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/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index 5a7b219..504471e 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #ifdef __MINGW32__ #include diff --git a/lib/Support/Windows/Host.inc b/lib/Support/Windows/Host.inc index 2e6d6f1..0c02bf9 100644 --- a/lib/Support/Windows/Host.inc +++ b/lib/Support/Windows/Host.inc @@ -11,12 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include #include using namespace llvm; std::string sys::getDefaultTargetTriple() { - return LLVM_DEFAULT_TARGET_TRIPLE; + return Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE); } diff --git a/lib/Support/Windows/Memory.inc b/lib/Support/Windows/Memory.inc index 1260452..ebe7878 100644 --- a/lib/Support/Windows/Memory.inc +++ b/lib/Support/Windows/Memory.inc @@ -17,7 +17,7 @@ #include "llvm/Support/Process.h" // The Windows.h header must be the last one included. -#include "Windows.h" +#include "WindowsSupport.h" namespace { diff --git a/lib/Support/Windows/Mutex.inc b/lib/Support/Windows/Mutex.inc index 583dc63..ab79d07 100644 --- a/lib/Support/Windows/Mutex.inc +++ b/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/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index 0b39198..e59888e 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -17,12 +17,16 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/STLExtras.h" -#include "Windows.h" #include #include #include #include +// 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 + #undef max // MinGW doesn't define this. @@ -40,175 +44,31 @@ 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 &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(); - } +static error_code TempDir(SmallVectorImpl &Result) { + SmallVector Res; +retry_temp_dir: + DWORD Len = ::GetTempPathW(Res.capacity(), Res.begin()); - bool is_separator(const wchar_t value) { - switch (value) { - case L'\\': - case L'/': - return true; - default: - return false; - } - } -} - -// 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 &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 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 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()); - } - } - - // Replace '%' with random chars. From here on, DO NOT modify model. It may be - // needed if the randomly chosen path already exists. - SmallVector 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::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; - } - - 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; + if (Len > Res.capacity()) { + Res.reserve(Len); + goto retry_temp_dir; } - 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 { @@ -281,7 +141,7 @@ error_code current_path(SmallVectorImpl &result) { return UTF16ToUTF8(cur_path.begin(), cur_path.size(), result); } -error_code create_directory(const Twine &path, bool &existed) { +error_code create_directory(const Twine &path, bool IgnoreExisting) { SmallString<128> path_storage; SmallVector path_utf16; @@ -291,40 +151,20 @@ error_code create_directory(const Twine &path, bool &existed) { if (!::CreateDirectoryW(path_utf16.begin(), NULL)) { error_code ec = windows_error(::GetLastError()); - if (ec == windows_error::already_exists) - existed = true; - else + if (ec != windows_error::already_exists || !IgnoreExisting) return ec; - } else - existed = false; + } return error_code::success(); } -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 wide_from; - SmallVector 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()); - +error_code normalize_separators(SmallVectorImpl &Path) { + (void) Path; return error_code::success(); } -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. +error_code create_link(const Twine &to, const Twine &from) { // Get arguments. SmallString<128> from_storage; SmallString<128> to_storage; @@ -337,49 +177,40 @@ error_code create_symlink(const Twine &to, const Twine &from) { if (error_code ec = UTF8ToUTF16(f, wide_from)) return ec; if (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(); } -error_code remove(const Twine &path, bool &existed) { +error_code remove(const Twine &path, bool IgnoreNonExisting) { SmallString<128> path_storage; SmallVector 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 (error_code EC = status(path, ST)) { + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; + return error_code::success(); } if (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; + error_code EC = windows_error(::GetLastError()); + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; + } + return error_code::success(); + } + if (!::DeleteFileW(c_str(path_utf16))) { + error_code EC = windows_error(::GetLastError()); + if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting) + return EC; } - return error_code::success(); } @@ -834,7 +665,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 +676,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 +688,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(Mapping); } @@ -1027,7 +856,11 @@ 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); @@ -1047,7 +880,7 @@ 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); @@ -1061,25 +894,41 @@ error_code openFileForWrite(const Twine &Name, int &ResultFD, } } // end namespace fs +namespace path { + +bool home_directory(SmallVectorImpl &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 &utf16) { - int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - utf8.begin(), utf8.size(), - utf16.begin(), 0); + 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 llvm::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 llvm::windows_error(::GetLastError()); + } // Make utf16 null terminated. utf16.push_back(0); @@ -1090,26 +939,24 @@ llvm::error_code UTF8ToUTF16(llvm::StringRef utf8, llvm::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, llvm::SmallVectorImpl &utf8) { - // Get length. - int len = ::WideCharToMultiByte(CP_UTF8, 0, - utf16, utf16_len, - utf8.begin(), 0, - NULL, NULL); - - if (len == 0) - return llvm::windows_error(::GetLastError()); - - 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); - - if (len == 0) - return llvm::windows_error(::GetLastError()); + 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()); + + 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); + + if (len == 0) + return llvm::windows_error(::GetLastError()); + } // Make utf8 null terminated. utf8.push_back(0); diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc index f9a3db9..a87c9e8 100644 --- a/lib/Support/Windows/Process.inc +++ b/lib/Support/Windows/Process.inc @@ -12,11 +12,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Allocator.h" +#include + +// The Windows.h header must be after LLVM and standard headers. +#include "WindowsSupport.h" -#include "Windows.h" #include #include -#include #include #include @@ -152,7 +154,7 @@ void Process::PreventCoreFiles() { Optional Process::GetEnv(StringRef Name) { // Convert the argument to UTF-16 to pass it to _wgetenv(). SmallVector 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,7 +175,7 @@ Optional Process::GetEnv(StringRef Name) { // Convert the result from UTF-16 to UTF-8. SmallVector 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()); } @@ -358,3 +360,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)) + assert(false && "Could not acquire a cryptographic context"); + + ScopedCryptContext CryptoProvider(HCPC); + unsigned Ret; + if (!::CryptGenRandom(CryptoProvider, sizeof(Ret), + reinterpret_cast(&Ret))) + assert(false && "Could not generate a random number"); + return Ret; +} diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc index dc09738..5827c10 100644 --- a/lib/Support/Windows/Program.inc +++ b/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 #include @@ -187,7 +186,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args, } // Now build the command line. - OwningArrayPtr command(new char[len+1]); + std::unique_ptr command(new char[len+1]); char *p = command.get(); for (unsigned i = 0; args[i]; i++) { @@ -437,13 +436,6 @@ error_code sys::ChangeStdoutToBinary(){ 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); -} - bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef Args) { // The documented max length of the command line passed to CreateProcess. static const size_t MaxCommandStringLength = 32768; diff --git a/lib/Support/Windows/RWMutex.inc b/lib/Support/Windows/RWMutex.inc index c431844..00d0e93 100644 --- a/lib/Support/Windows/RWMutex.inc +++ b/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/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index 4b40d51..35ba6f8 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FileSystem.h" - -#include "Windows.h" #include #include #include +// The Windows.h header must be after LLVM and standard headers. +#include "WindowsSupport.h" + #ifdef __MINGW32__ #include #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/lib/Support/Windows/ThreadLocal.inc b/lib/Support/Windows/ThreadLocal.inc index 057deb3..3914cf7 100644 --- a/lib/Support/Windows/ThreadLocal.inc +++ b/lib/Support/Windows/ThreadLocal.inc @@ -16,7 +16,7 @@ //=== is guaranteed to work on *all* Win32 variants. //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include "llvm/Support/ThreadLocal.h" namespace llvm { diff --git a/lib/Support/Windows/TimeValue.inc b/lib/Support/Windows/TimeValue.inc index 98b07d6..6c59024 100644 --- a/lib/Support/Windows/TimeValue.inc +++ b/lib/Support/Windows/TimeValue.inc @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "Windows.h" +#include "WindowsSupport.h" #include #include diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/Windows.h deleted file mode 100644 index 1f3417d..0000000 --- a/lib/Support/Windows/Windows.h +++ /dev/null @@ -1,168 +0,0 @@ -//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines things specific to Win32 implementations. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -//=== WARNING: Implementation here must contain only generic Win32 code that -//=== is guaranteed to work on *all* Win32 variants. -//===----------------------------------------------------------------------===// - -// mingw-w64 tends to define it as 0x0502 in its headers. -#undef _WIN32_WINNT - -// Require at least Windows XP(5.1) API. -#define _WIN32_WINNT 0x0501 -#define _WIN32_IE 0x0600 // MinGW at it again. -#define WIN32_LEAN_AND_MEAN - -#include "llvm/ADT/SmallVector.h" -#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 -#include -#include -#include -#include - -inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { - if (!ErrMsg) - return true; - char *buffer = NULL; - DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL); - if (R) - *ErrMsg = prefix + buffer; - else - *ErrMsg = prefix + "Unknown error"; - - LocalFree(buffer); - return R != 0; -} - -template -class ScopedHandle { - typedef typename HandleTraits::handle_type handle_type; - handle_type Handle; - - ScopedHandle(const ScopedHandle &other); // = delete; - void operator=(const ScopedHandle &other); // = delete; -public: - ScopedHandle() - : Handle(HandleTraits::GetInvalid()) {} - - explicit ScopedHandle(handle_type h) - : Handle(h) {} - - ~ScopedHandle() { - if (HandleTraits::IsValid(Handle)) - HandleTraits::Close(Handle); - } - - handle_type take() { - handle_type t = Handle; - Handle = HandleTraits::GetInvalid(); - return t; - } - - ScopedHandle &operator=(handle_type h) { - if (HandleTraits::IsValid(Handle)) - HandleTraits::Close(Handle); - Handle = h; - return *this; - } - - // True if Handle is valid. - LLVM_EXPLICIT operator bool() const { - return HandleTraits::IsValid(Handle) ? true : false; - } - - operator handle_type() const { - return Handle; - } -}; - -struct CommonHandleTraits { - typedef HANDLE handle_type; - - static handle_type GetInvalid() { - return INVALID_HANDLE_VALUE; - } - - static void Close(handle_type h) { - ::CloseHandle(h); - } - - static bool IsValid(handle_type h) { - return h != GetInvalid(); - } -}; - -struct JobHandleTraits : CommonHandleTraits { - static handle_type GetInvalid() { - return NULL; - } -}; - -struct CryptContextTraits : CommonHandleTraits { - typedef HCRYPTPROV handle_type; - - static handle_type GetInvalid() { - return 0; - } - - static void Close(handle_type h) { - ::CryptReleaseContext(h, 0); - } - - static bool IsValid(handle_type h) { - return h != GetInvalid(); - } -}; - -struct FindHandleTraits : CommonHandleTraits { - static void Close(handle_type h) { - ::FindClose(h); - } -}; - -struct FileHandleTraits : CommonHandleTraits {}; - -typedef ScopedHandle ScopedCommonHandle; -typedef ScopedHandle ScopedFileHandle; -typedef ScopedHandle ScopedCryptContext; -typedef ScopedHandle ScopedFindHandle; -typedef ScopedHandle ScopedJobHandle; - -namespace llvm { -template -class SmallVectorImpl; - -template -typename SmallVectorImpl::const_pointer -c_str(SmallVectorImpl &str) { - str.push_back(0); - str.pop_back(); - return str.data(); -} - -namespace sys { -namespace windows { -error_code UTF8ToUTF16(StringRef utf8, - SmallVectorImpl &utf16); -error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, - SmallVectorImpl &utf8); -} // end namespace windows -} // end namespace sys -} // end namespace llvm. diff --git a/lib/Support/Windows/WindowsSupport.h b/lib/Support/Windows/WindowsSupport.h new file mode 100644 index 0000000..6bef444 --- /dev/null +++ b/lib/Support/Windows/WindowsSupport.h @@ -0,0 +1,172 @@ +//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines things specific to Windows implementations. In addition to +// providing some helpers for working with win32 APIs, this header wraps +// with some portability macros. Always include WindowsSupport.h +// instead of including directly. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +//=== WARNING: Implementation here must contain only generic Win32 code that +//=== is guaranteed to work on *all* Win32 variants. +//===----------------------------------------------------------------------===// + +// 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 +#define _WIN32_IE 0x0600 // MinGW at it again. +#define WIN32_LEAN_AND_MEAN + +#include "llvm/ADT/SmallVector.h" +#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 +#include +#include +#include +#include + +inline bool MakeErrMsg(std::string* ErrMsg, const std::string& prefix) { + if (!ErrMsg) + return true; + char *buffer = NULL; + DWORD R = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), 0, (LPSTR)&buffer, 1, NULL); + if (R) + *ErrMsg = prefix + buffer; + else + *ErrMsg = prefix + "Unknown error"; + + LocalFree(buffer); + return R != 0; +} + +template +class ScopedHandle { + typedef typename HandleTraits::handle_type handle_type; + handle_type Handle; + + ScopedHandle(const ScopedHandle &other); // = delete; + void operator=(const ScopedHandle &other); // = delete; +public: + ScopedHandle() + : Handle(HandleTraits::GetInvalid()) {} + + explicit ScopedHandle(handle_type h) + : Handle(h) {} + + ~ScopedHandle() { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); + } + + handle_type take() { + handle_type t = Handle; + Handle = HandleTraits::GetInvalid(); + return t; + } + + ScopedHandle &operator=(handle_type h) { + if (HandleTraits::IsValid(Handle)) + HandleTraits::Close(Handle); + Handle = h; + return *this; + } + + // True if Handle is valid. + LLVM_EXPLICIT operator bool() const { + return HandleTraits::IsValid(Handle) ? true : false; + } + + operator handle_type() const { + return Handle; + } +}; + +struct CommonHandleTraits { + typedef HANDLE handle_type; + + static handle_type GetInvalid() { + return INVALID_HANDLE_VALUE; + } + + static void Close(handle_type h) { + ::CloseHandle(h); + } + + static bool IsValid(handle_type h) { + return h != GetInvalid(); + } +}; + +struct JobHandleTraits : CommonHandleTraits { + static handle_type GetInvalid() { + return NULL; + } +}; + +struct CryptContextTraits : CommonHandleTraits { + typedef HCRYPTPROV handle_type; + + static handle_type GetInvalid() { + return 0; + } + + static void Close(handle_type h) { + ::CryptReleaseContext(h, 0); + } + + static bool IsValid(handle_type h) { + return h != GetInvalid(); + } +}; + +struct FindHandleTraits : CommonHandleTraits { + static void Close(handle_type h) { + ::FindClose(h); + } +}; + +struct FileHandleTraits : CommonHandleTraits {}; + +typedef ScopedHandle ScopedCommonHandle; +typedef ScopedHandle ScopedFileHandle; +typedef ScopedHandle ScopedCryptContext; +typedef ScopedHandle ScopedFindHandle; +typedef ScopedHandle ScopedJobHandle; + +namespace llvm { +template +class SmallVectorImpl; + +template +typename SmallVectorImpl::const_pointer +c_str(SmallVectorImpl &str) { + str.push_back(0); + str.pop_back(); + return str.data(); +} + +namespace sys { +namespace windows { +error_code UTF8ToUTF16(StringRef utf8, + SmallVectorImpl &utf16); +error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, + SmallVectorImpl &utf8); +} // end namespace windows +} // end namespace sys +} // end namespace llvm. diff --git a/lib/Support/YAMLParser.cpp b/lib/Support/YAMLParser.cpp index 9495cd4..73ce5e0 100644 --- a/lib/Support/YAMLParser.cpp +++ b/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 &D, StringRef A, StringRef T) - : Doc(D) - , TypeID(Type) - , Anchor(A) - , Tag(T) { +Node::Node(unsigned int Type, std::unique_ptr &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::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); } } diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp index 42bff96..5472e0e 100644 --- a/lib/Support/YAMLTraits.cpp +++ b/lib/Support/YAMLTraits.cpp @@ -14,8 +14,8 @@ #include "llvm/Support/Format.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" -#include #include +#include using namespace llvm; using namespace yaml; @@ -65,7 +65,7 @@ void Input::HNode::anchor() {} void Input::EmptyHNode::anchor() {} void Input::ScalarHNode::anchor() {} -bool Input::outputting() const { +bool Input::outputting() { return false; } @@ -406,7 +406,7 @@ Output::Output(raw_ostream &yout, void *context) Output::~Output() { } -bool Output::outputting() const { +bool Output::outputting() { return true; } @@ -689,6 +689,17 @@ StringRef ScalarTraits::input(StringRef Scalar, void *, Val = Scalar; return StringRef(); } + +void ScalarTraits::output(const std::string &Val, void *, + raw_ostream &Out) { + Out << Val; +} + +StringRef ScalarTraits::input(StringRef Scalar, void *, + std::string &Val) { + Val = Scalar.str(); + return StringRef(); +} void ScalarTraits::output(const uint8_t &Val, void *, raw_ostream &Out) { diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index cb96489..3c45743 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -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; @@ -437,7 +443,7 @@ 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; @@ -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 diff --git a/lib/Support/regcomp.c b/lib/Support/regcomp.c index 74d9186..0b5b765 100644 --- a/lib/Support/regcomp.c +++ b/lib/Support/regcomp.c @@ -532,10 +532,10 @@ p_simp_re(struct parse *p, sopno subno; # define BACKSL (1<