aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /lib/Support
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp22
-rw-r--r--lib/Support/APInt.cpp2
-rw-r--r--lib/Support/ARMBuildAttrs.cpp95
-rw-r--r--lib/Support/Allocator.cpp159
-rw-r--r--lib/Support/Android.mk10
-rw-r--r--lib/Support/Atomic.cpp12
-rw-r--r--lib/Support/BlockFrequency.cpp31
-rw-r--r--lib/Support/CMakeLists.txt40
-rw-r--r--lib/Support/CommandLine.cpp60
-rw-r--r--lib/Support/Compression.cpp13
-rw-r--r--lib/Support/ConstantRange.cpp734
-rw-r--r--lib/Support/CrashRecoveryContext.cpp8
-rw-r--r--lib/Support/DAGDeltaAlgorithm.cpp6
-rw-r--r--lib/Support/DataStream.cpp2
-rw-r--r--lib/Support/Dwarf.cpp21
-rw-r--r--lib/Support/DynamicLibrary.cpp4
-rw-r--r--lib/Support/ErrorHandling.cpp2
-rw-r--r--lib/Support/FileOutputBuffer.cpp22
-rw-r--r--lib/Support/FileUtilities.cpp5
-rw-r--r--lib/Support/GraphWriter.cpp3
-rw-r--r--lib/Support/Host.cpp28
-rw-r--r--lib/Support/LEB128.cpp44
-rw-r--r--lib/Support/LineIterator.cpp68
-rw-r--r--lib/Support/LockFileManager.cpp88
-rw-r--r--lib/Support/MemoryBuffer.cpp101
-rw-r--r--lib/Support/Mutex.cpp7
-rw-r--r--lib/Support/Path.cpp182
-rw-r--r--lib/Support/PrettyStackTrace.cpp2
-rw-r--r--lib/Support/Process.cpp13
-rw-r--r--lib/Support/Regex.cpp22
-rw-r--r--lib/Support/SmallPtrSet.cpp78
-rw-r--r--lib/Support/SourceMgr.cpp5
-rw-r--r--lib/Support/Statistic.cpp23
-rw-r--r--lib/Support/StreamableMemoryObject.cpp23
-rw-r--r--lib/Support/StringRef.cpp1
-rw-r--r--lib/Support/TargetRegistry.cpp36
-rw-r--r--lib/Support/ThreadLocal.cpp5
-rw-r--r--lib/Support/Threading.cpp2
-rw-r--r--lib/Support/Timer.cpp5
-rw-r--r--lib/Support/ToolOutputFile.cpp6
-rw-r--r--lib/Support/Triple.cpp224
-rw-r--r--lib/Support/Twine.cpp4
-rw-r--r--lib/Support/Unix/Host.inc2
-rw-r--r--lib/Support/Unix/Memory.inc15
-rw-r--r--lib/Support/Unix/Path.inc207
-rw-r--r--lib/Support/Unix/Process.inc6
-rw-r--r--lib/Support/Unix/Program.inc6
-rw-r--r--lib/Support/Unix/RWMutex.inc20
-rw-r--r--lib/Support/Unix/Signals.inc2
-rw-r--r--lib/Support/Valgrind.cpp14
-rw-r--r--lib/Support/Windows/DynamicLibrary.inc2
-rw-r--r--lib/Support/Windows/Host.inc4
-rw-r--r--lib/Support/Windows/Memory.inc2
-rw-r--r--lib/Support/Windows/Mutex.inc2
-rw-r--r--lib/Support/Windows/Path.inc355
-rw-r--r--lib/Support/Windows/Process.inc24
-rw-r--r--lib/Support/Windows/Program.inc12
-rw-r--r--lib/Support/Windows/RWMutex.inc2
-rw-r--r--lib/Support/Windows/Signals.inc8
-rw-r--r--lib/Support/Windows/ThreadLocal.inc2
-rw-r--r--lib/Support/Windows/TimeValue.inc2
-rw-r--r--lib/Support/Windows/WindowsSupport.h (renamed from lib/Support/Windows/Windows.h)8
-rw-r--r--lib/Support/YAMLParser.cpp59
-rw-r--r--lib/Support/YAMLTraits.cpp17
-rw-r--r--lib/Support/raw_ostream.cpp13
-rw-r--r--lib/Support/regcomp.c6
-rw-r--r--lib/Support/system_error.cpp10
67 files changed, 1236 insertions, 1782 deletions
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<AttrType>(Attr), HasTagPrefix);
+}
+
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix) {
+ for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
+ TI != TE; ++TI)
+ if (ARMAttributeTags[TI].Attr == Attr)
+ return ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4);
+ return "";
+}
+
+int AttrTypeFromString(StringRef Tag) {
+ bool HasTagPrefix = Tag.startswith("Tag_");
+ for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
+ TI != TE; ++TI)
+ if (StringRef(ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4)) == Tag)
+ return ARMAttributeTags[TI].Attr;
+ return -1;
+}
+}
+}
+
diff --git a/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<OptionCategory*,16> OptionCatSet;
static ManagedStatic<OptionCatSet> RegisteredOptionCategories;
@@ -118,8 +124,13 @@ static ManagedStatic<OptionCatSet> RegisteredOptionCategories;
// Initialise the general option category.
OptionCategory llvm::cl::GeneralCategory("General options");
-void OptionCategory::registerCategory()
-{
+void OptionCategory::registerCategory() {
+ assert(std::count_if(RegisteredOptionCategories->begin(),
+ RegisteredOptionCategories->end(),
+ [this](const OptionCategory *Category) {
+ return getName() == Category->getName();
+ }) == 0 && "Duplicate option categories");
+
RegisteredOptionCategories->insert(this);
}
@@ -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<const char *> &NewArgv) {
- OwningPtr<MemoryBuffer> MemBuf;
+ std::unique_ptr<MemoryBuffer> 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<const char *> &Argv) {
unsigned RspFiles = 0;
- bool AllExpanded = false;
+ bool AllExpanded = true;
// Don't cache Argv.size() because it can change.
for (unsigned I = 0; I != Argv.size(); ) {
@@ -655,7 +665,10 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
// the cwd of the process or the response file?
SmallVector<const char *, 0> ExpandedArgv;
if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv)) {
+ // We couldn't read this file, so we leave it in the argument stream and
+ // move on.
AllExpanded = false;
+ ++I;
continue;
}
Argv.erase(Argv.begin() + I);
@@ -675,7 +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<OptionCategory *> SortedCategories;
std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions;
- // Collect registered option categories into vector in preperation for
+ // Collect registered option categories into vector in preparation for
// sorting.
for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(),
E = RegisteredOptionCategories->end();
- I != E; ++I)
+ I != E; ++I) {
SortedCategories.push_back(*I);
+ }
// Sort the different option categories alphabetically.
assert(SortedCategories.size() > 0 && "No option categories registered!");
@@ -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<MemoryBuffer> &CompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &CompressedBuffer,
CompressionLevel Level) {
unsigned long CompressedSize = ::compressBound(InputBuffer.size());
- OwningArrayPtr<char> TmpBuffer(new char[CompressedSize]);
+ std::unique_ptr<char[]> 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<MemoryBuffer> &UncompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
size_t UncompressedSize) {
- OwningArrayPtr<char> TmpBuffer(new char[UncompressedSize]);
+ std::unique_ptr<char[]> 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<MemoryBuffer> &CompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &CompressedBuffer,
CompressionLevel Level) {
return zlib::StatusUnsupported;
}
zlib::Status zlib::uncompress(StringRef InputBuffer,
- OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ std::unique_ptr<MemoryBuffer> &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
- // <d1> <d2>
- if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) {
- APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper;
- if (d1.ult(d2))
- return ConstantRange(Lower, CR.Upper);
- return ConstantRange(CR.Lower, Upper);
- }
-
- // ----U L----- : this
- // L----U : CR
- if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper))
- return ConstantRange(CR.Lower, Upper);
-
- // ------U L---- : this
- // L-----U : CR
- assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) &&
- "ConstantRange::unionWith missed a case with one range wrapped");
- return ConstantRange(Lower, CR.Upper);
- }
-
- // ------U L---- and ------U L---- : this
- // -U L----------- and ------------U L : CR
- if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper))
- return ConstantRange(getBitWidth());
-
- APInt L = Lower, U = Upper;
- if (CR.Upper.ugt(U))
- U = CR.Upper;
- if (CR.Lower.ult(L))
- L = CR.Lower;
-
- return ConstantRange(L, U);
-}
-
-/// zeroExtend - Return a new range in the specified integer type, which must
-/// be strictly larger than the current type. The returned range will
-/// correspond to the possible range of values as if the source range had been
-/// zero extended.
-ConstantRange ConstantRange::zeroExtend(uint32_t DstTySize) const {
- if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
-
- unsigned SrcTySize = getBitWidth();
- assert(SrcTySize < DstTySize && "Not a value extension");
- if (isFullSet() || isWrappedSet()) {
- // Change into [0, 1 << src bit width)
- APInt LowerExt(DstTySize, 0);
- if (!Upper) // special case: [X, 0) -- not really wrapping around
- LowerExt = Lower.zext(DstTySize);
- return ConstantRange(LowerExt, APInt::getOneBitSet(DstTySize, SrcTySize));
- }
-
- return ConstantRange(Lower.zext(DstTySize), Upper.zext(DstTySize));
-}
-
-/// signExtend - Return a new range in the specified integer type, which must
-/// be strictly larger than the current type. The returned range will
-/// correspond to the possible range of values as if the source range had been
-/// sign extended.
-ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
- if (isEmptySet()) return ConstantRange(DstTySize, /*isFullSet=*/false);
-
- unsigned SrcTySize = getBitWidth();
- assert(SrcTySize < DstTySize && "Not a value extension");
-
- // special case: [X, INT_MIN) -- not really wrapping around
- if (Upper.isMinSignedValue())
- return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize));
-
- if (isFullSet() || isSignWrappedSet()) {
- return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
- APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
- }
-
- return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize));
-}
-
-/// truncate - Return a new range in the specified integer type, which must be
-/// strictly smaller than the current type. The returned range will
-/// correspond to the possible range of values as if the source range had been
-/// truncated to the specified type.
-ConstantRange ConstantRange::truncate(uint32_t DstTySize) const {
- assert(getBitWidth() > DstTySize && "Not a value truncation");
- if (isEmptySet())
- return ConstantRange(DstTySize, /*isFullSet=*/false);
- if (isFullSet())
- return ConstantRange(DstTySize, /*isFullSet=*/true);
-
- APInt MaxValue = APInt::getMaxValue(DstTySize).zext(getBitWidth());
- APInt MaxBitValue(getBitWidth(), 0);
- MaxBitValue.setBit(DstTySize);
-
- APInt LowerDiv(Lower), UpperDiv(Upper);
- ConstantRange Union(DstTySize, /*isFullSet=*/false);
-
- // Analyze wrapped sets in their two parts: [0, Upper) \/ [Lower, MaxValue]
- // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and
- // then we do the union with [MaxValue, Upper)
- if (isWrappedSet()) {
- // if Upper is greater than Max Value, it covers the whole truncated range.
- if (Upper.uge(MaxValue))
- return ConstantRange(DstTySize, /*isFullSet=*/true);
-
- Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize));
- UpperDiv = APInt::getMaxValue(getBitWidth());
-
- // Union covers the MaxValue case, so return if the remaining range is just
- // MaxValue.
- if (LowerDiv == UpperDiv)
- return Union;
- }
-
- // Chop off the most significant bits that are past the destination bitwidth.
- if (LowerDiv.uge(MaxValue)) {
- APInt Div(getBitWidth(), 0);
- APInt::udivrem(LowerDiv, MaxBitValue, Div, LowerDiv);
- UpperDiv = UpperDiv - MaxBitValue * Div;
- }
-
- if (UpperDiv.ule(MaxValue))
- return ConstantRange(LowerDiv.trunc(DstTySize),
- UpperDiv.trunc(DstTySize)).unionWith(Union);
-
- // The truncated value wrapps around. Check if we can do better than fullset.
- APInt UpperModulo = UpperDiv - MaxBitValue;
- if (UpperModulo.ult(LowerDiv))
- return ConstantRange(LowerDiv.trunc(DstTySize),
- UpperModulo.trunc(DstTySize)).unionWith(Union);
-
- return ConstantRange(DstTySize, /*isFullSet=*/true);
-}
-
-/// zextOrTrunc - make this range have the bit width given by \p DstTySize. The
-/// value is zero extended, truncated, or left alone to make it that width.
-ConstantRange ConstantRange::zextOrTrunc(uint32_t DstTySize) const {
- unsigned SrcTySize = getBitWidth();
- if (SrcTySize > DstTySize)
- return truncate(DstTySize);
- if (SrcTySize < DstTySize)
- return zeroExtend(DstTySize);
- return *this;
-}
-
-/// sextOrTrunc - make this range have the bit width given by \p DstTySize. The
-/// value is sign extended, truncated, or left alone to make it that width.
-ConstantRange ConstantRange::sextOrTrunc(uint32_t DstTySize) const {
- unsigned SrcTySize = getBitWidth();
- if (SrcTySize > DstTySize)
- return truncate(DstTySize);
- if (SrcTySize < DstTySize)
- return signExtend(DstTySize);
- return *this;
-}
-
-ConstantRange
-ConstantRange::add(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- if (isFullSet() || Other.isFullSet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize();
- APInt NewLower = getLower() + Other.getLower();
- APInt NewUpper = getUpper() + Other.getUpper() - 1;
- if (NewLower == NewUpper)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- ConstantRange X = ConstantRange(NewLower, NewUpper);
- if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y))
- // We've wrapped, therefore, full set.
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- return X;
-}
-
-ConstantRange
-ConstantRange::sub(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- if (isFullSet() || Other.isFullSet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- APInt Spread_X = getSetSize(), Spread_Y = Other.getSetSize();
- APInt NewLower = getLower() - Other.getUpper() + 1;
- APInt NewUpper = getUpper() - Other.getLower();
- if (NewLower == NewUpper)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- ConstantRange X = ConstantRange(NewLower, NewUpper);
- if (X.getSetSize().ult(Spread_X) || X.getSetSize().ult(Spread_Y))
- // We've wrapped, therefore, full set.
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- return X;
-}
-
-ConstantRange
-ConstantRange::multiply(const ConstantRange &Other) const {
- // TODO: If either operand is a single element and the multiply is known to
- // be non-wrapping, round the result min and max value to the appropriate
- // multiple of that element. If wrapping is possible, at least adjust the
- // range according to the greatest power-of-two factor of the single element.
-
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
-
- APInt this_min = getUnsignedMin().zext(getBitWidth() * 2);
- APInt this_max = getUnsignedMax().zext(getBitWidth() * 2);
- APInt Other_min = Other.getUnsignedMin().zext(getBitWidth() * 2);
- APInt Other_max = Other.getUnsignedMax().zext(getBitWidth() * 2);
-
- ConstantRange Result_zext = ConstantRange(this_min * Other_min,
- this_max * Other_max + 1);
- return Result_zext.truncate(getBitWidth());
-}
-
-ConstantRange
-ConstantRange::smax(const ConstantRange &Other) const {
- // X smax Y is: range(smax(X_smin, Y_smin),
- // smax(X_smax, Y_smax))
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- APInt NewL = APIntOps::smax(getSignedMin(), Other.getSignedMin());
- APInt NewU = APIntOps::smax(getSignedMax(), Other.getSignedMax()) + 1;
- if (NewU == NewL)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
- return ConstantRange(NewL, NewU);
-}
-
-ConstantRange
-ConstantRange::umax(const ConstantRange &Other) const {
- // X umax Y is: range(umax(X_umin, Y_umin),
- // umax(X_umax, Y_umax))
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- APInt NewL = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
- APInt NewU = APIntOps::umax(getUnsignedMax(), Other.getUnsignedMax()) + 1;
- if (NewU == NewL)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
- return ConstantRange(NewL, NewU);
-}
-
-ConstantRange
-ConstantRange::udiv(const ConstantRange &RHS) const {
- if (isEmptySet() || RHS.isEmptySet() || RHS.getUnsignedMax() == 0)
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- if (RHS.isFullSet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- APInt Lower = getUnsignedMin().udiv(RHS.getUnsignedMax());
-
- APInt RHS_umin = RHS.getUnsignedMin();
- if (RHS_umin == 0) {
- // We want the lowest value in RHS excluding zero. Usually that would be 1
- // except for a range in the form of [X, 1) in which case it would be X.
- if (RHS.getUpper() == 1)
- RHS_umin = RHS.getLower();
- else
- RHS_umin = APInt(getBitWidth(), 1);
- }
-
- APInt Upper = getUnsignedMax().udiv(RHS_umin) + 1;
-
- // If the LHS is Full and the RHS is a wrapped interval containing 1 then
- // this could occur.
- if (Lower == Upper)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- return ConstantRange(Lower, Upper);
-}
-
-ConstantRange
-ConstantRange::binaryAnd(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
-
- // TODO: replace this with something less conservative
-
- APInt umin = APIntOps::umin(Other.getUnsignedMax(), getUnsignedMax());
- if (umin.isAllOnesValue())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
- return ConstantRange(APInt::getNullValue(getBitWidth()), umin + 1);
-}
-
-ConstantRange
-ConstantRange::binaryOr(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
-
- // TODO: replace this with something less conservative
-
- APInt umax = APIntOps::umax(getUnsignedMin(), Other.getUnsignedMin());
- if (umax.isMinValue())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
- return ConstantRange(umax, APInt::getNullValue(getBitWidth()));
-}
-
-ConstantRange
-ConstantRange::shl(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
-
- APInt min = getUnsignedMin().shl(Other.getUnsignedMin());
- APInt max = getUnsignedMax().shl(Other.getUnsignedMax());
-
- // there's no overflow!
- APInt Zeros(getBitWidth(), getUnsignedMax().countLeadingZeros());
- if (Zeros.ugt(Other.getUnsignedMax()))
- return ConstantRange(min, max + 1);
-
- // FIXME: implement the other tricky cases
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-}
-
-ConstantRange
-ConstantRange::lshr(const ConstantRange &Other) const {
- if (isEmptySet() || Other.isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
-
- APInt max = getUnsignedMax().lshr(Other.getUnsignedMin());
- APInt min = getUnsignedMin().lshr(Other.getUnsignedMax());
- if (min == max + 1)
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
-
- return ConstantRange(min, max + 1);
-}
-
-ConstantRange ConstantRange::inverse() const {
- if (isFullSet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/false);
- if (isEmptySet())
- return ConstantRange(getBitWidth(), /*isFullSet=*/true);
- return ConstantRange(Upper, Lower);
-}
-
-/// print - Print out the bounds to a stream...
-///
-void ConstantRange::print(raw_ostream &OS) const {
- if (isFullSet())
- OS << "full-set";
- else if (isEmptySet())
- OS << "empty-set";
- else
- OS << "[" << Lower << "," << Upper << ")";
-}
-
-/// dump - Allow printing from a debugger easily...
-///
-void ConstantRange::dump() const {
- print(dbgs());
-}
diff --git a/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<RunSafelyOnThreadInfo*>(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 <cstdio>
#include <cstring>
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 <cassert>
#include <cstdlib>
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<FileOutputBuffer> &Result,
+ std::unique_ptr<FileOutputBuffer> &Result,
unsigned Flags) {
// If file already exists, it must be a regular file (to be mappable).
sys::fs::file_status Stat;
@@ -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<mapped_file_region> MappedFile(new mapped_file_region(
+ std::unique_ptr<mapped_file_region> MappedFile(new mapped_file_region(
FD, true, mapped_file_region::readwrite, Size, 0, EC));
if (EC)
return EC;
Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath));
if (Result)
- MappedFile.take();
+ MappedFile.release();
return error_code::success();
}
+error_code FileOutputBuffer::create(StringRef FilePath,
+ size_t Size,
+ OwningPtr<FileOutputBuffer> &Result,
+ unsigned Flags) {
+ std::unique_ptr<FileOutputBuffer> 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<MemoryBuffer> F1;
+ std::unique_ptr<MemoryBuffer> F1;
if (error_code ec = MemoryBuffer::getFile(NameA, F1)) {
if (Error)
*Error = ec.message();
return 2;
}
- OwningPtr<MemoryBuffer> F2;
+ std::unique_ptr<MemoryBuffer> 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<const char*> &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<const char *>(Lines[I].substr(8).ltrim("\t :"))
+ .Case("0x06f", "krait") // APQ8064
+ .Default("generic");
+
return "generic";
}
#elif defined(__linux__) && defined(__s390x__)
-std::string sys::getHostCPUName() {
+StringRef sys::getHostCPUName() {
// STIDP is a privileged operation, so use /proc/cpuinfo instead.
// Note: We cannot mmap /proc/cpuinfo here and then process the resulting
// memory buffer because the 'file' has 0 size (it can be read from only
@@ -664,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 <sys/stat.h>
#include <sys/types.h>
@@ -29,21 +30,17 @@ using namespace llvm;
/// \returns The process ID of the process that owns this lock file
Optional<std::pair<std::string, int> >
LockFileManager::readLockFile(StringRef LockFileName) {
- // Check whether the lock file exists. If not, clearly there's nothing
- // to read, so we just return.
- bool Exists = false;
- if (sys::fs::exists(LockFileName, Exists) || !Exists)
- return None;
-
// Read the owning host and PID out of the lock file. If it appears that the
// owning process is dead, the lock file is invalid.
- OwningPtr<MemoryBuffer> MB;
- if (MemoryBuffer::getFile(LockFileName, MB))
+ std::unique_ptr<MemoryBuffer> 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<const char*>(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<char*>(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<MemoryBuffer> &result,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> &Result,
+ int64_t FileSize) {
+ std::unique_ptr<MemoryBuffer> 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<const char *>(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<MemoryBuffer> &result) {
+ std::unique_ptr<MemoryBuffer> &Result) {
const ssize_t ChunkSize = 4096*4;
SmallString<ChunkSize> 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<MemoryBuffer> &result, int64_t FileSize,
+ std::unique_ptr<MemoryBuffer> &Result,
+ int64_t FileSize,
bool RequiresNullTerminator);
error_code MemoryBuffer::getFile(Twine Filename,
- OwningPtr<MemoryBuffer> &result,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> &Result,
+ int64_t FileSize,
+ bool RequiresNullTerminator) {
+ std::unique_ptr<MemoryBuffer> 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<MemoryBuffer> &Result,
+ std::unique_ptr<MemoryBuffer> &Result,
uint64_t FileSize, uint64_t MapSize,
int64_t Offset, bool RequiresNullTerminator);
static error_code getFileAux(const char *Filename,
- OwningPtr<MemoryBuffer> &result, int64_t FileSize,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> &result,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> SB(Buf);
+ std::unique_ptr<MemoryBuffer> SB(Buf);
char *BufPtr = const_cast<char*>(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<MemoryBuffer> &Result,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> &Result,
+ uint64_t FileSize,
+ bool RequiresNullTerminator) {
+ std::unique_ptr<MemoryBuffer> 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<MemoryBuffer> &Result,
+ std::unique_ptr<MemoryBuffer> &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<MemoryBuffer> &Result,
+ uint64_t MapSize, int64_t Offset) {
+ std::unique_ptr<MemoryBuffer> 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<MemoryBuffer> &result) {
+error_code MemoryBuffer::getSTDIN(std::unique_ptr<MemoryBuffer> &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, "<stdin>", result);
+ return getMemoryBufferForStream(0, "<stdin>", Result);
+}
+
+error_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &Result) {
+ std::unique_ptr<MemoryBuffer> 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 <cctype>
#include <cstdio>
#include <cstring>
@@ -26,16 +27,18 @@
#include <io.h>
#endif
+using namespace llvm;
+
namespace {
using llvm::StringRef;
using llvm::sys::path::is_separator;
#ifdef LLVM_ON_WIN32
const char *separators = "\\/";
- const char prefered_separator = '\\';
+ const char preferred_separator = '\\';
#else
const char separators = '/';
- const char prefered_separator = '/';
+ const char preferred_separator = '/';
#endif
StringRef find_first_component(StringRef path) {
@@ -161,10 +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<char> &ResultPath,
- bool MakeAbsolute, unsigned Mode, FSEntity Type);
+static error_code TempDir(SmallVectorImpl<char> &result);
+
+static error_code createUniqueEntity(const Twine &Model, int &ResultFD,
+ SmallVectorImpl<char> &ResultPath,
+ bool MakeAbsolute, unsigned Mode,
+ FSEntity Type) {
+ SmallString<128> ModelStorage;
+ Model.toVector(ModelStorage);
+
+ if (MakeAbsolute) {
+ // Make model absolute by prepending a temp directory if it's not already.
+ 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<char> &path, const Twine &a,
if (!component_has_sep && !(path.empty() || is_root_name)) {
// Add a separator.
- path.push_back(prefered_separator);
+ path.push_back(preferred_separator);
}
path.append(i->begin(), i->end());
@@ -507,8 +572,9 @@ bool is_separator(char value) {
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
result.clear();
-#ifdef __APPLE__
+#if defined(_CS_DARWIN_USER_TEMP_DIR) && defined(_CS_DARWIN_USER_CACHE_DIR)
// On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
+ // macros defined in <unistd.h> on darwin >= 9
int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
: _CS_DARWIN_USER_CACHE_DIR;
size_t ConfLen = confstr(ConfName, 0, 0);
@@ -749,20 +815,27 @@ error_code make_absolute(SmallVectorImpl<char> &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 <CrashReporterClient.h>
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<void *>::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<MemoryBuffer> NewBuf;
+ std::unique_ptr<MemoryBuffer> 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 <cassert>
+#include <cstddef>
#include <cstring>
@@ -24,20 +25,18 @@ public:
assert(LastChar >= FirstChar && "Invalid start/end range");
}
- virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
- virtual uint64_t getExtent() const LLVM_OVERRIDE {
+ uint64_t getBase() const override { return 0; }
+ uint64_t getExtent() const override {
return LastChar - FirstChar;
}
- virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE;
- virtual int readBytes(uint64_t address,
- uint64_t size,
- uint8_t *buf) const LLVM_OVERRIDE;
- virtual const uint8_t *getPointer(uint64_t address,
- uint64_t size) const LLVM_OVERRIDE;
- virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE {
+ int readByte(uint64_t address, uint8_t* ptr) const override;
+ int readBytes(uint64_t address, uint64_t size,
+ uint8_t *buf) const override;
+ const uint8_t *getPointer(uint64_t address, uint64_t size) const override;
+ bool isValidAddress(uint64_t address) const override {
return validAddress(address);
}
- virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE {
+ bool isObjectEnd(uint64_t address) const override {
return objectEnd(address);
}
@@ -48,10 +47,10 @@ private:
// These are implemented as inline functions here to avoid multiple virtual
// calls per public function
bool validAddress(uint64_t address) const {
- return static_cast<ptrdiff_t>(address) < LastChar - FirstChar;
+ return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar;
}
bool objectEnd(uint64_t address) const {
- return static_cast<ptrdiff_t>(address) == LastChar - FirstChar;
+ return static_cast<std::ptrdiff_t>(address) == LastChar - FirstChar;
}
RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
diff --git a/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 <bitset>
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<void**>(&data);
*pd = const_cast<void*>(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<pthread_key_t*>(&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 <process.h>
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<Triple::ArchType>(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<Triple::EnvironmentType>(EnvironmentName)
+ .StartsWith("eabihf", Triple::EABIHF)
.StartsWith("eabi", Triple::EABI)
.StartsWith("gnueabihf", Triple::GNUEABIHF)
.StartsWith("gnueabi", Triple::GNUEABI)
.StartsWith("gnux32", Triple::GNUX32)
+ .StartsWith("code16", Triple::CODE16)
.StartsWith("gnu", Triple::GNU)
- .StartsWith("macho", Triple::MachO)
.StartsWith("android", Triple::Android)
- .StartsWith("elf", Triple::ELF)
+ .StartsWith("msvc", Triple::MSVC)
+ .StartsWith("itanium", Triple::Itanium)
+ .StartsWith("cygnus", Triple::Cygnus)
.Default(Triple::UnknownEnvironment);
}
+static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
+ return StringSwitch<Triple::ObjectFormatType>(EnvironmentName)
+ .EndsWith("coff", Triple::COFF)
+ .EndsWith("elf", Triple::ELF)
+ .EndsWith("macho", Triple::MachO)
+ .Default(Triple::UnknownObjectFormat);
+}
+
+static 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<void *>(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 <limits.h>
#include <stdio.h>
#if HAVE_SYS_STAT_H
@@ -86,95 +85,22 @@ namespace {
operator int() const {return FileDescriptor;}
};
+}
- error_code TempDir(SmallVectorImpl<char> &result) {
- // FIXME: Don't use TMPDIR if program is SUID or SGID enabled.
- const char *dir = 0;
- (dir = std::getenv("TMPDIR" )) ||
- (dir = std::getenv("TMP" )) ||
- (dir = std::getenv("TEMP" )) ||
- (dir = std::getenv("TEMPDIR")) ||
+static error_code TempDir(SmallVectorImpl<char> &result) {
+ // FIXME: Don't use TMPDIR if program is SUID or SGID enabled.
+ const char *dir = 0;
+ (dir = std::getenv("TMPDIR")) || (dir = std::getenv("TMP")) ||
+ (dir = std::getenv("TEMP")) || (dir = std::getenv("TEMPDIR")) ||
#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<char> &ResultPath,
- bool MakeAbsolute, unsigned Mode,
- FSEntity Type) {
- SmallString<128> ModelStorage;
- Model.toVector(ModelStorage);
-
- if (MakeAbsolute) {
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = sys::path::is_absolute(Twine(ModelStorage));
- if (!absolute) {
- SmallString<128> TDir;
- if (error_code ec = TempDir(TDir)) return ec;
- sys::path::append(TDir, Twine(ModelStorage));
- ModelStorage.swap(TDir);
- }
- }
-
- // From here on, DO NOT modify model. It may be needed if the randomly chosen
- // path already exists.
- ResultPath = ModelStorage;
- // Null terminate.
- ResultPath.push_back(0);
- ResultPath.pop_back();
-
-retry_random_path:
- // Replace '%' with random chars.
- for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
- if (ModelStorage[i] == '%')
- ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
- }
-
- // Try to open + create the file.
- switch (Type) {
- case FS_File: {
- int RandomFD = ::open(ResultPath.begin(), O_RDWR | O_CREAT | O_EXCL, Mode);
- if (RandomFD == -1) {
- int SavedErrno = errno;
- // If the file existed, try again, otherwise, error.
- if (SavedErrno == errc::file_exists)
- goto retry_random_path;
- return error_code(SavedErrno, system_category());
- }
-
- ResultFD = RandomFD;
- return error_code::success();
- }
-
- case FS_Name: {
- bool Exists;
- error_code EC = sys::fs::exists(ResultPath.begin(), Exists);
- if (EC)
- return EC;
- if (Exists)
- goto retry_random_path;
- return error_code::success();
- }
-
- 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<char> &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<char> &Path) {
+ for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
+ if (*PI == '\\') {
+ auto PN = PI + 1;
+ if (PN < PE && *PN == '\\')
+ ++PI; // increment once, the for loop will move over the escaped slash
+ else
+ *PI = '/';
+ }
+ }
return 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<char*>(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<char> &result) {
+ if (char *RequestedDir = getenv("HOME")) {
+ result.clear();
+ result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return true;
+ }
+
+ return false;
+}
+
+} // end namespace path
+
} // end namespace sys
} // end namespace llvm
diff --git a/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<const char*> 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<Mutex *>(data_);
+}
bool RWMutexImpl::reader_acquire() {
- return true;
+ return static_cast<Mutex *>(data_)->acquire();
}
bool RWMutexImpl::reader_release() {
- return true;
+ return static_cast<Mutex *>(data_)->release();
}
bool RWMutexImpl::writer_acquire() {
- return true;
+ return static_cast<Mutex *>(data_)->acquire();
}
bool RWMutexImpl::writer_release() {
- return true;
+ return static_cast<Mutex *>(data_)->release();
}
}
diff --git a/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<int>(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 <imagehlp.h>
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 <cstdio>
#include <string>
using namespace llvm;
std::string sys::getDefaultTargetTriple() {
- return LLVM_DEFAULT_TARGET_TRIPLE;
+ return Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE);
}
diff --git a/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 <fcntl.h>
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
+// These two headers must be included last, and make sure shlobj is required
+// after Windows.h to make sure it picks up our definition of _WIN32_WINNT
+#include "WindowsSupport.h"
+#include <shlobj.h>
+
#undef max
// MinGW doesn't define this.
@@ -40,175 +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<wchar_t> &result) {
- retry_temp_dir:
- DWORD len = ::GetTempPathW(result.capacity(), result.begin());
-
- if (len == 0)
- return windows_error(::GetLastError());
-
- if (len > result.capacity()) {
- result.reserve(len);
- goto retry_temp_dir;
- }
-
- result.set_size(len);
- return error_code::success();
- }
+static error_code TempDir(SmallVectorImpl<char> &Result) {
+ SmallVector<wchar_t, 64> 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<char> &result_path,
- bool makeAbsolute, unsigned mode,
- FSEntity Type) {
- // Use result_path as temp storage.
- result_path.set_size(0);
- StringRef m = model.toStringRef(result_path);
-
- SmallVector<wchar_t, 128> model_utf16;
- if (error_code ec = UTF8ToUTF16(m, model_utf16)) return ec;
-
- if (makeAbsolute) {
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = sys::path::is_absolute(m);
-
- if (!absolute) {
- SmallVector<wchar_t, 64> temp_dir;
- if (error_code ec = TempDir(temp_dir)) return ec;
- // Handle c: by removing it.
- if (model_utf16.size() > 2 && model_utf16[1] == L':') {
- model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2);
- }
- model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end());
- }
- }
-
- // Replace '%' with random chars. From here on, DO NOT modify model. It may be
- // needed if the randomly chosen path already exists.
- SmallVector<wchar_t, 128> random_path_utf16;
-
- // Get a Crypto Provider for CryptGenRandom.
- HCRYPTPROV HCPC;
- if (!::CryptAcquireContextW(&HCPC,
- NULL,
- NULL,
- PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT))
+ if (Len == 0)
return windows_error(::GetLastError());
- ScopedCryptContext CryptoProvider(HCPC);
-
-retry_random_path:
- random_path_utf16.set_size(0);
- for (SmallVectorImpl<wchar_t>::const_iterator i = model_utf16.begin(),
- e = model_utf16.end();
- i != e; ++i) {
- if (*i == L'%') {
- BYTE val = 0;
- if (!::CryptGenRandom(CryptoProvider, 1, &val))
- return windows_error(::GetLastError());
- random_path_utf16.push_back(L"0123456789abcdef"[val & 15]);
- }
- else
- random_path_utf16.push_back(*i);
- }
- // Make random_path_utf16 null terminated.
- random_path_utf16.push_back(0);
- random_path_utf16.pop_back();
-
- HANDLE TempFileHandle = INVALID_HANDLE_VALUE;
-
- switch (Type) {
- case FS_File: {
- // Try to create + open the path.
- TempFileHandle =
- ::CreateFileW(random_path_utf16.begin(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL,
- // Return ERROR_FILE_EXISTS if the file
- // already exists.
- CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL);
- if (TempFileHandle == INVALID_HANDLE_VALUE) {
- // If the file existed, try again, otherwise, error.
- error_code ec = windows_error(::GetLastError());
- if (ec == windows_error::file_exists)
- goto retry_random_path;
-
- return ec;
- }
-
- // Convert the Windows API file handle into a C-runtime handle.
- int fd = ::_open_osfhandle(intptr_t(TempFileHandle), 0);
- if (fd == -1) {
- ::CloseHandle(TempFileHandle);
- ::DeleteFileW(random_path_utf16.begin());
- // MSDN doesn't say anything about _open_osfhandle setting errno or
- // GetLastError(), so just return invalid_handle.
- return windows_error::invalid_handle;
- }
- result_fd = fd;
- break;
- }
-
- 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<char> &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<wchar_t, 128> 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<wchar_t, 128> wide_from;
- SmallVector<wchar_t, 128> wide_to;
- if (error_code ec = UTF8ToUTF16(f, wide_from)) return ec;
- if (error_code ec = UTF8ToUTF16(t, wide_to)) return ec;
-
- if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL))
- return windows_error(::GetLastError());
-
+error_code normalize_separators(SmallVectorImpl<char> &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<wchar_t, 128> path_utf16;
- file_status st;
- error_code EC = status(path, st);
- if (EC) {
- if (EC == windows_error::file_not_found ||
- EC == windows_error::path_not_found) {
- existed = false;
- return error_code::success();
- }
- return EC;
+ file_status ST;
+ if (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<char*>(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<char> &result) {
+ wchar_t Path[MAX_PATH];
+ if (::SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0,
+ /*SHGFP_TYPE_CURRENT*/0, Path) != S_OK)
+ return false;
+
+ if (UTF16ToUTF8(Path, ::wcslen(Path), result))
+ return false;
+
+ return true;
+}
+
+} // end namespace path
+
namespace windows {
llvm::error_code UTF8ToUTF16(llvm::StringRef utf8,
llvm::SmallVectorImpl<wchar_t> &utf16) {
- int len = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- utf8.begin(), utf8.size(),
- utf16.begin(), 0);
+ 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<char> &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 <malloc.h>
+
+// The Windows.h header must be after LLVM and standard headers.
+#include "WindowsSupport.h"
-#include "Windows.h"
#include <direct.h>
#include <io.h>
-#include <malloc.h>
#include <psapi.h>
#include <shellapi.h>
@@ -152,7 +154,7 @@ void Process::PreventCoreFiles() {
Optional<std::string> Process::GetEnv(StringRef Name) {
// Convert the argument to UTF-16 to pass it to _wgetenv().
SmallVector<wchar_t, 128> NameUTF16;
- if (error_code ec = windows::UTF8ToUTF16(Name, NameUTF16))
+ if (windows::UTF8ToUTF16(Name, NameUTF16))
return None;
// Environment variable can be encoded in non-UTF8 encoding, and there's no
@@ -173,7 +175,7 @@ Optional<std::string> Process::GetEnv(StringRef Name) {
// Convert the result from UTF-16 to UTF-8.
SmallVector<char, MAX_PATH> Res;
- if (error_code ec = windows::UTF16ToUTF8(Buf.data(), Size, Res))
+ if (windows::UTF16ToUTF8(Buf.data(), Size, Res))
return None;
return std::string(Res.data());
}
@@ -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<BYTE *>(&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 <cstdio>
#include <fcntl.h>
@@ -187,7 +186,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
}
// Now build the command line.
- OwningArrayPtr<char> command(new char[len+1]);
+ std::unique_ptr<char[]> command(new char[len+1]);
char *p = command.get();
for (unsigned i = 0; args[i]; i++) {
@@ -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<const char*> 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 <algorithm>
#include <stdio.h>
#include <vector>
+// The Windows.h header must be after LLVM and standard headers.
+#include "WindowsSupport.h"
+
#ifdef __MINGW32__
#include <imagehlp.h>
#else
@@ -317,8 +318,7 @@ static void Cleanup() {
if (FilesToRemove != NULL)
while (!FilesToRemove->empty()) {
- bool Existed;
- llvm::sys::fs::remove(FilesToRemove->back(), Existed);
+ llvm::sys::fs::remove(FilesToRemove->back());
FilesToRemove->pop_back();
}
diff --git a/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 <cctype>
#include <time.h>
diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/WindowsSupport.h
index 1f3417d..6bef444 100644
--- a/lib/Support/Windows/Windows.h
+++ b/lib/Support/Windows/WindowsSupport.h
@@ -1,4 +1,4 @@
-//===- Win32/Win32.h - Common Win32 Include File ----------------*- C++ -*-===//
+//===- WindowsSupport.h - Common Windows Include File -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,10 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines things specific to Win32 implementations.
+// This file defines things specific to Windows implementations. In addition to
+// providing some helpers for working with win32 APIs, this header wraps
+// <windows.h> with some portability macros. Always include WindowsSupport.h
+// instead of including <windows.h> directly.
//
//===----------------------------------------------------------------------===//
@@ -18,6 +21,7 @@
// mingw-w64 tends to define it as 0x0502 in its headers.
#undef _WIN32_WINNT
+#undef _WIN32_IE
// Require at least Windows XP(5.1) API.
#define _WIN32_WINNT 0x0501
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<Document> &D, StringRef A, StringRef T)
- : Doc(D)
- , TypeID(Type)
- , Anchor(A)
- , Tag(T) {
+Node::Node(unsigned int Type, std::unique_ptr<Document> &D, StringRef A,
+ StringRef T)
+ : Doc(D), TypeID(Type), Anchor(A), Tag(T) {
SMLoc Start = SMLoc::getFromPointer(peekNext().Range.begin());
SourceRange = SMRange(Start, Start);
}
@@ -1617,11 +1574,11 @@ std::string Node::getVerbatimTag() const {
if (Raw.find_last_of('!') == 0) {
Ret = Doc->getTagMap().find("!")->second;
Ret += Raw.substr(1);
- return llvm_move(Ret);
+ return std::move(Ret);
} else if (Raw.startswith("!!")) {
Ret = Doc->getTagMap().find("!!")->second;
Ret += Raw.substr(2);
- return llvm_move(Ret);
+ return std::move(Ret);
} else {
StringRef TagHandle = Raw.substr(0, Raw.find_last_of('!') + 1);
std::map<StringRef, StringRef>::const_iterator It =
@@ -1635,7 +1592,7 @@ std::string Node::getVerbatimTag() const {
setError(Twine("Unknown tag handle ") + TagHandle, T);
}
Ret += Raw.substr(Raw.find_last_of('!') + 1);
- return llvm_move(Ret);
+ return std::move(Ret);
}
}
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 <cstring>
#include <cctype>
+#include <cstring>
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<StringRef>::input(StringRef Scalar, void *,
Val = Scalar;
return StringRef();
}
+
+void ScalarTraits<std::string>::output(const std::string &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
+ std::string &Val) {
+ Val = Scalar.str();
+ return StringRef();
+}
void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
raw_ostream &Out) {
diff --git a/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<<CHAR_BIT)
- pos = HERE(); /* repetion op, if any, covers from here */
+ pos = HERE(); /* repetition op, if any, covers from here */
- assert(MORE()); /* caller should have ensured this */
- c = GETNEXT();
+ assert(MORE()); /* caller should have ensured this */
+ c = GETNEXT();
if (c == '\\') {
REQUIRE(MORE(), REG_EESCAPE);
c = BACKSL | GETNEXT();
diff --git a/lib/Support/system_error.cpp b/lib/Support/system_error.cpp
index b22745a..299f54a 100644
--- a/lib/Support/system_error.cpp
+++ b/lib/Support/system_error.cpp
@@ -48,8 +48,8 @@ _do_message::message(int ev) const {
class _generic_error_category : public _do_message {
public:
- virtual const char* name() const LLVM_OVERRIDE;
- virtual std::string message(int ev) const LLVM_OVERRIDE;
+ const char* name() const override;
+ std::string message(int ev) const override;
};
const char*
@@ -74,9 +74,9 @@ generic_category() {
class _system_error_category : public _do_message {
public:
- virtual const char* name() const LLVM_OVERRIDE;
- virtual std::string message(int ev) const LLVM_OVERRIDE;
- virtual error_condition default_error_condition(int ev) const LLVM_OVERRIDE;
+ const char* name() const override;
+ std::string message(int ev) const override;
+ error_condition default_error_condition(int ev) const override;
};
const char*