aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Support
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
committerStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
commitdce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch)
treedcebc53f2b182f145a2e659393bf9a0472cedf23 /include/llvm/Support
parent220b921aed042f9e520c26cffd8282a94c66c3d5 (diff)
downloadexternal_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'include/llvm/Support')
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h13
-rw-r--r--include/llvm/Support/Allocator.h410
-rw-r--r--include/llvm/Support/ArrayRecycler.h4
-rw-r--r--include/llvm/Support/BlockFrequency.h10
-rw-r--r--include/llvm/Support/BranchProbability.h34
-rw-r--r--include/llvm/Support/COFF.h6
-rw-r--r--include/llvm/Support/Casting.h10
-rw-r--r--include/llvm/Support/CommandLine.h29
-rw-r--r--include/llvm/Support/Compression.h7
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h35
-rw-r--r--include/llvm/Support/Debug.h16
-rw-r--r--include/llvm/Support/DynamicLibrary.h4
-rw-r--r--include/llvm/Support/ELF.h17
-rw-r--r--include/llvm/Support/ErrorHandling.h10
-rw-r--r--include/llvm/Support/FileOutputBuffer.h4
-rw-r--r--include/llvm/Support/FileSystem.h29
-rw-r--r--include/llvm/Support/FileUtilities.h2
-rw-r--r--include/llvm/Support/FormattedStream.h8
-rw-r--r--include/llvm/Support/GCOV.h50
-rw-r--r--include/llvm/Support/GenericDomTree.h45
-rw-r--r--include/llvm/Support/GenericDomTreeConstruction.h12
-rw-r--r--include/llvm/Support/GraphWriter.h9
-rw-r--r--include/llvm/Support/LEB128.h2
-rw-r--r--include/llvm/Support/LineIterator.h5
-rw-r--r--include/llvm/Support/LockFileManager.h12
-rw-r--r--include/llvm/Support/MachO.h48
-rw-r--r--include/llvm/Support/ManagedStatic.h2
-rw-r--r--include/llvm/Support/Memory.h10
-rw-r--r--include/llvm/Support/MemoryBuffer.h36
-rw-r--r--include/llvm/Support/OnDiskHashTable.h571
-rw-r--r--include/llvm/Support/Path.h5
-rw-r--r--include/llvm/Support/Program.h26
-rw-r--r--include/llvm/Support/Regex.h7
-rw-r--r--include/llvm/Support/Registry.h15
-rw-r--r--include/llvm/Support/SMLoc.h4
-rw-r--r--include/llvm/Support/SaveAndRestore.h48
-rw-r--r--include/llvm/Support/Signals.h2
-rw-r--r--include/llvm/Support/SourceMgr.h9
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h2
-rw-r--r--include/llvm/Support/StringPool.h8
-rw-r--r--include/llvm/Support/TargetRegistry.h85
-rw-r--r--include/llvm/Support/Timer.h14
-rw-r--r--include/llvm/Support/Unicode.h5
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h4
-rw-r--r--include/llvm/Support/YAMLParser.h181
-rw-r--r--include/llvm/Support/YAMLTraits.h157
-rw-r--r--include/llvm/Support/circular_raw_ostream.h8
-rw-r--r--include/llvm/Support/raw_ostream.h15
-rw-r--r--include/llvm/Support/system_error.h4
49 files changed, 1470 insertions, 579 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index 69732fc..1631200 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -146,6 +146,19 @@ enum {
AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+ // Tag_ABI_PCS_RW_data, (=15), uleb128
+ AddressRWPCRel = 1, // Address RW static data PC-relative
+ AddressRWSBRel = 2, // Address RW static data SB-relative
+ AddressRWNone = 3, // No RW static data permitted
+
+ // Tag_ABI_PCS_RO_data, (=14), uleb128
+ AddressROPCRel = 1, // Address RO static data PC-relative
+ AddressRONone = 2, // No RO static data permitted
+
+ // Tag_ABI_PCS_GOT_use, (=17), uleb128
+ AddressDirect = 1, // Address imported data directly
+ AddressGOT = 2, // Address imported data indirectly (via GOT)
+
// Tag_ABI_FP_denormal, (=20), uleb128
PreserveFPSign = 2, // sign when flushed-to-zero is preserved
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
index 0641322..7a7e4c0 100644
--- a/include/llvm/Support/Allocator.h
+++ b/include/llvm/Support/Allocator.h
@@ -6,14 +6,22 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines the MallocAllocator and BumpPtrAllocator interfaces.
-//
+/// \file
+///
+/// This file defines the MallocAllocator and BumpPtrAllocator interfaces. Both
+/// of these conform to an LLVM "Allocator" concept which consists of an
+/// Allocate method accepting a size and alignment, and a Deallocate accepting
+/// a pointer and size. Further, the LLVM "Allocator" concept has overloads of
+/// Allocate and Deallocate for setting size and alignment based on the final
+/// type. These overloads are typically provided by a base class template \c
+/// AllocatorBase.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_ALLOCATOR_H
#define LLVM_SUPPORT_ALLOCATOR_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/MathExtras.h"
@@ -24,90 +32,86 @@
#include <cstdlib>
namespace llvm {
-template <typename T> struct ReferenceAdder {
- typedef T &result;
-};
-template <typename T> struct ReferenceAdder<T &> {
- typedef T result;
-};
-class MallocAllocator {
+/// \brief CRTP base class providing obvious overloads for the core \c
+/// Allocate() methods of LLVM-style allocators.
+///
+/// This base class both documents the full public interface exposed by all
+/// LLVM-style allocators, and redirects all of the overloads to a single core
+/// set of methods which the derived class must define.
+template <typename DerivedT> class AllocatorBase {
public:
- MallocAllocator() {}
- ~MallocAllocator() {}
-
- void Reset() {}
-
- void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
-
- template <typename T> T *Allocate() {
- return static_cast<T *>(malloc(sizeof(T)));
+ /// \brief Allocate \a Size bytes of \a Alignment aligned memory. This method
+ /// must be implemented by \c DerivedT.
+ void *Allocate(size_t Size, size_t Alignment) {
+#ifdef __clang__
+ static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
+ &AllocatorBase::Allocate) !=
+ static_cast<void *(DerivedT::*)(size_t, size_t)>(
+ &DerivedT::Allocate),
+ "Class derives from AllocatorBase without implementing the "
+ "core Allocate(size_t, size_t) overload!");
+#endif
+ return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
}
- template <typename T> T *Allocate(size_t Num) {
- return static_cast<T *>(malloc(sizeof(T) * Num));
+ /// \brief Deallocate \a Ptr to \a Size bytes of memory allocated by this
+ /// allocator.
+ void Deallocate(const void *Ptr, size_t Size) {
+#ifdef __clang__
+ static_assert(static_cast<void (AllocatorBase::*)(const void *, size_t)>(
+ &AllocatorBase::Deallocate) !=
+ static_cast<void (DerivedT::*)(const void *, size_t)>(
+ &DerivedT::Deallocate),
+ "Class derives from AllocatorBase without implementing the "
+ "core Deallocate(void *) overload!");
+#endif
+ return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size);
}
- void Deallocate(const void *Ptr) { free(const_cast<void *>(Ptr)); }
+ // The rest of these methods are helpers that redirect to one of the above
+ // core methods.
- void PrintStats() const {}
-};
+ /// \brief Allocate space for a sequence of objects without constructing them.
+ template <typename T> T *Allocate(size_t Num = 1) {
+ return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
+ }
-/// MemSlab - This structure lives at the beginning of every slab allocated by
-/// the bump allocator.
-class MemSlab {
-public:
- size_t Size;
- MemSlab *NextPtr;
+ /// \brief Deallocate space for a sequence of objects without constructing them.
+ template <typename T>
+ typename std::enable_if<
+ !std::is_same<typename std::remove_cv<T>::type, void>::value, void>::type
+ Deallocate(T *Ptr, size_t Num = 1) {
+ Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T));
+ }
};
-/// SlabAllocator - This class can be used to parameterize the underlying
-/// allocation strategy for the bump allocator. In particular, this is used
-/// by the JIT to allocate contiguous swathes of executable memory. The
-/// interface uses MemSlab's instead of void *'s so that the allocator
-/// doesn't have to remember the size of the pointer it allocated.
-class SlabAllocator {
+class MallocAllocator : public AllocatorBase<MallocAllocator> {
public:
- virtual ~SlabAllocator();
- virtual MemSlab *Allocate(size_t Size) = 0;
- virtual void Deallocate(MemSlab *Slab) = 0;
-};
+ void Reset() {}
-/// MallocSlabAllocator - The default slab allocator for the bump allocator
-/// is an adapter class for MallocAllocator that just forwards the method
-/// calls and translates the arguments.
-class MallocSlabAllocator : public SlabAllocator {
- /// Allocator - The underlying allocator that we forward to.
- ///
- MallocAllocator Allocator;
+ void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); }
-public:
- MallocSlabAllocator() : Allocator() {}
- virtual ~MallocSlabAllocator();
- MemSlab *Allocate(size_t Size) override;
- void Deallocate(MemSlab *Slab) override;
-};
+ // Pull in base class overloads.
+ using AllocatorBase<MallocAllocator>::Allocate;
-/// \brief Non-templated base class for the \c BumpPtrAllocatorImpl template.
-class BumpPtrAllocatorBase {
-public:
- void Deallocate(const void * /*Ptr*/) {}
- void PrintStats() const;
+ void Deallocate(const void *Ptr, size_t /*Size*/) {
+ free(const_cast<void *>(Ptr));
+ }
- /// \brief Returns the total physical memory allocated by this allocator.
- size_t getTotalMemory() const;
+ // Pull in base class overloads.
+ using AllocatorBase<MallocAllocator>::Deallocate;
-protected:
- /// \brief The slab that we are currently allocating into.
- MemSlab *CurSlab;
+ void PrintStats() const {}
+};
- /// \brief How many bytes we've allocated.
- ///
- /// Used so that we can compute how much space was wasted.
- size_t BytesAllocated;
+namespace detail {
- BumpPtrAllocatorBase() : CurSlab(0), BytesAllocated(0) {}
-};
+// We call out to an external function to actually print the message as the
+// printing code uses Allocator.h in its implementation.
+void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated,
+ size_t TotalMemory);
+} // End namespace detail.
/// \brief Allocate memory in an ever growing pool, as if by bump-pointer.
///
@@ -119,11 +123,15 @@ protected:
///
/// Note that this also has a threshold for forcing allocations above a certain
/// size into their own slab.
-template <size_t SlabSize = 4096, size_t SizeThreshold = SlabSize>
-class BumpPtrAllocatorImpl : public BumpPtrAllocatorBase {
- BumpPtrAllocatorImpl(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
- void operator=(const BumpPtrAllocatorImpl &) LLVM_DELETED_FUNCTION;
-
+///
+/// The BumpPtrAllocatorImpl template defaults to using a MallocAllocator
+/// object, which wraps malloc, to allocate memory, but it can be changed to
+/// use a custom allocator.
+template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096,
+ size_t SizeThreshold = SlabSize>
+class BumpPtrAllocatorImpl
+ : public AllocatorBase<
+ BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>> {
public:
static_assert(SizeThreshold <= SlabSize,
"The SizeThreshold must be at most the SlabSize to ensure "
@@ -131,26 +139,69 @@ public:
"allocation.");
BumpPtrAllocatorImpl()
- : Allocator(DefaultSlabAllocator), NumSlabs(0) {}
- BumpPtrAllocatorImpl(SlabAllocator &Allocator)
- : Allocator(Allocator), NumSlabs(0) {}
- ~BumpPtrAllocatorImpl() { DeallocateSlabs(CurSlab); }
+ : CurPtr(nullptr), End(nullptr), BytesAllocated(0), Allocator() {}
+ template <typename T>
+ BumpPtrAllocatorImpl(T &&Allocator)
+ : CurPtr(nullptr), End(nullptr), BytesAllocated(0),
+ Allocator(std::forward<T &&>(Allocator)) {}
+
+ // Manually implement a move constructor as we must clear the old allocators
+ // slabs as a matter of correctness.
+ BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
+ : CurPtr(Old.CurPtr), End(Old.End), Slabs(std::move(Old.Slabs)),
+ CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
+ BytesAllocated(Old.BytesAllocated),
+ Allocator(std::move(Old.Allocator)) {
+ Old.CurPtr = Old.End = nullptr;
+ Old.BytesAllocated = 0;
+ Old.Slabs.clear();
+ Old.CustomSizedSlabs.clear();
+ }
+
+ ~BumpPtrAllocatorImpl() {
+ DeallocateSlabs(Slabs.begin(), Slabs.end());
+ DeallocateCustomSizedSlabs();
+ }
+
+ BumpPtrAllocatorImpl &operator=(BumpPtrAllocatorImpl &&RHS) {
+ DeallocateSlabs(Slabs.begin(), Slabs.end());
+ DeallocateCustomSizedSlabs();
+
+ CurPtr = RHS.CurPtr;
+ End = RHS.End;
+ BytesAllocated = RHS.BytesAllocated;
+ Slabs = std::move(RHS.Slabs);
+ CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
+ Allocator = std::move(RHS.Allocator);
+
+ RHS.CurPtr = RHS.End = nullptr;
+ RHS.BytesAllocated = 0;
+ RHS.Slabs.clear();
+ RHS.CustomSizedSlabs.clear();
+ return *this;
+ }
/// \brief Deallocate all but the current slab and reset the current pointer
/// to the beginning of it, freeing all memory allocated so far.
void Reset() {
- if (!CurSlab)
+ if (Slabs.empty())
return;
- DeallocateSlabs(CurSlab->NextPtr);
- CurSlab->NextPtr = 0;
- CurPtr = (char *)(CurSlab + 1);
- End = ((char *)CurSlab) + CurSlab->Size;
+
+ // Reset the state.
BytesAllocated = 0;
+ CurPtr = (char *)Slabs.front();
+ End = CurPtr + SlabSize;
+
+ // Deallocate all but the first slab, and all custome sized slabs.
+ DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
+ Slabs.erase(std::next(Slabs.begin()), Slabs.end());
+ DeallocateCustomSizedSlabs();
+ CustomSizedSlabs.clear();
}
/// \brief Allocate space at the specified alignment.
void *Allocate(size_t Size, size_t Alignment) {
- if (!CurSlab) // Start a new slab if we haven't allocated one already.
+ if (!CurPtr) // Start a new slab if we haven't allocated one already.
StartNewSlab();
// Keep track of how many bytes we've allocated.
@@ -174,18 +225,13 @@ public:
}
// If Size is really big, allocate a separate slab for it.
- size_t PaddedSize = Size + sizeof(MemSlab) + Alignment - 1;
+ size_t PaddedSize = Size + Alignment - 1;
if (PaddedSize > SizeThreshold) {
- ++NumSlabs;
- 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;
+ void *NewSlab = Allocator.Allocate(PaddedSize, 0);
+ CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize));
- Ptr = alignPtr((char *)(NewSlab + 1), Alignment);
- assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + NewSlab->Size);
+ Ptr = alignPtr((char *)NewSlab, Alignment);
+ assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + PaddedSize);
__msan_allocated_memory(Ptr, Size);
return Ptr;
}
@@ -199,36 +245,31 @@ public:
return Ptr;
}
- /// \brief Allocate space for one object without constructing it.
- template <typename T> T *Allocate() {
- return static_cast<T *>(Allocate(sizeof(T), AlignOf<T>::Alignment));
- }
+ // Pull in base class overloads.
+ using AllocatorBase<BumpPtrAllocatorImpl>::Allocate;
- /// \brief Allocate space for an array of objects without constructing them.
- template <typename T> T *Allocate(size_t Num) {
- return static_cast<T *>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment));
- }
+ void Deallocate(const void * /*Ptr*/, size_t /*Size*/) {}
- /// \brief Allocate space for an array of objects with the specified alignment
- /// and without constructing them.
- template <typename T> T *Allocate(size_t Num, size_t Alignment) {
- // Round EltSize up to the specified alignment.
- size_t EltSize = (sizeof(T) + Alignment - 1) & (-Alignment);
- return static_cast<T *>(Allocate(Num * EltSize, Alignment));
- }
+ // Pull in base class overloads.
+ using AllocatorBase<BumpPtrAllocatorImpl>::Deallocate;
- size_t GetNumSlabs() const { return NumSlabs; }
+ size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
-private:
- /// \brief The default allocator used if one is not provided.
- MallocSlabAllocator DefaultSlabAllocator;
+ size_t getTotalMemory() const {
+ size_t TotalMemory = 0;
+ for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)
+ TotalMemory += computeSlabSize(std::distance(Slabs.begin(), I));
+ for (auto &PtrAndSize : CustomSizedSlabs)
+ TotalMemory += PtrAndSize.second;
+ return TotalMemory;
+ }
- /// \brief The underlying allocator we use to get slabs of memory.
- ///
- /// This defaults to MallocSlabAllocator, which wraps malloc, but it could be
- /// changed to use a custom allocator.
- SlabAllocator &Allocator;
+ void PrintStats() const {
+ detail::printBumpPtrAllocatorStats(Slabs.size(), BytesAllocated,
+ getTotalMemory());
+ }
+private:
/// \brief The current pointer into the current slab.
///
/// This points to the next free byte in the slab.
@@ -237,46 +278,67 @@ private:
/// \brief The end of the current slab.
char *End;
- /// \brief How many slabs we've allocated.
+ /// \brief The slabs allocated so far.
+ SmallVector<void *, 4> Slabs;
+
+ /// \brief Custom-sized slabs allocated for too-large allocation requests.
+ SmallVector<std::pair<void *, size_t>, 0> CustomSizedSlabs;
+
+ /// \brief How many bytes we've allocated.
///
- /// Used to scale the size of each slab and reduce the number of allocations
- /// for extremely heavy memory use scenarios.
- size_t NumSlabs;
+ /// Used so that we can compute how much space was wasted.
+ size_t BytesAllocated;
- /// \brief Allocate a new slab and move the bump pointers over into the new
- /// slab, modifying CurPtr and End.
- void StartNewSlab() {
- ++NumSlabs;
+ /// \brief The allocator instance we use to get slabs of memory.
+ AllocatorT Allocator;
+
+ static size_t computeSlabSize(unsigned SlabIdx) {
// Scale the actual allocated slab size based on the number of slabs
// allocated. Every 128 slabs allocated, we double the allocated size to
// reduce allocation frequency, but saturate at multiplying the slab size by
// 2^30.
- // FIXME: Currently, this count includes special slabs for objects above the
- // size threshold. That will be fixed in a subsequent commit to make the
- // growth even more predictable.
- size_t AllocatedSlabSize =
- SlabSize * ((size_t)1 << std::min<size_t>(30, NumSlabs / 128));
-
- MemSlab *NewSlab = Allocator.Allocate(AllocatedSlabSize);
- NewSlab->NextPtr = CurSlab;
- CurSlab = NewSlab;
- CurPtr = (char *)(CurSlab + 1);
- End = ((char *)CurSlab) + CurSlab->Size;
+ return SlabSize * ((size_t)1 << std::min<size_t>(30, SlabIdx / 128));
}
- /// \brief Deallocate all memory slabs after and including this one.
- void DeallocateSlabs(MemSlab *Slab) {
- while (Slab) {
- MemSlab *NextSlab = Slab->NextPtr;
+ /// \brief Allocate a new slab and move the bump pointers over into the new
+ /// slab, modifying CurPtr and End.
+ void StartNewSlab() {
+ size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
+
+ void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
+ Slabs.push_back(NewSlab);
+ CurPtr = (char *)(NewSlab);
+ End = ((char *)NewSlab) + AllocatedSlabSize;
+ }
+
+ /// \brief Deallocate a sequence of slabs.
+ void DeallocateSlabs(SmallVectorImpl<void *>::iterator I,
+ SmallVectorImpl<void *>::iterator E) {
+ for (; I != E; ++I) {
+ size_t AllocatedSlabSize =
+ computeSlabSize(std::distance(Slabs.begin(), I));
#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));
+ sys::Memory::setRangeWritable(*I, AllocatedSlabSize);
+ memset(*I, 0xCD, AllocatedSlabSize);
#endif
- Allocator.Deallocate(Slab);
- Slab = NextSlab;
- --NumSlabs;
+ Allocator.Deallocate(*I, AllocatedSlabSize);
+ }
+ }
+
+ /// \brief Deallocate all memory for custom sized slabs.
+ void DeallocateCustomSizedSlabs() {
+ for (auto &PtrAndSize : CustomSizedSlabs) {
+ void *Ptr = PtrAndSize.first;
+ size_t Size = PtrAndSize.second;
+#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(Ptr, Size);
+ memset(Ptr, 0xCD, Size);
+#endif
+ Allocator.Deallocate(Ptr, Size);
}
}
@@ -297,25 +359,42 @@ template <typename T> class SpecificBumpPtrAllocator {
public:
SpecificBumpPtrAllocator() : Allocator() {}
- SpecificBumpPtrAllocator(SlabAllocator &allocator) : Allocator(allocator) {}
-
+ SpecificBumpPtrAllocator(SpecificBumpPtrAllocator &&Old)
+ : Allocator(std::move(Old.Allocator)) {}
~SpecificBumpPtrAllocator() { DestroyAll(); }
+ SpecificBumpPtrAllocator &operator=(SpecificBumpPtrAllocator &&RHS) {
+ Allocator = std::move(RHS.Allocator);
+ return *this;
+ }
+
/// Call the destructor of each allocated object and deallocate all but the
/// current slab and reset the current pointer to the beginning of it, freeing
/// all memory allocated so far.
void DestroyAll() {
- MemSlab *Slab = Allocator.CurSlab;
- while (Slab) {
- char *End = Slab == Allocator.CurSlab ? Allocator.CurPtr
- : (char *)Slab + Slab->Size;
- for (char *Ptr = (char *)(Slab + 1); Ptr < End; Ptr += sizeof(T)) {
- Ptr = alignPtr(Ptr, alignOf<T>());
- if (Ptr + sizeof(T) <= End)
- reinterpret_cast<T *>(Ptr)->~T();
- }
- Slab = Slab->NextPtr;
+ auto DestroyElements = [](char *Begin, char *End) {
+ assert(Begin == alignPtr(Begin, alignOf<T>()));
+ for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T))
+ reinterpret_cast<T *>(Ptr)->~T();
+ };
+
+ for (auto I = Allocator.Slabs.begin(), E = Allocator.Slabs.end(); I != E;
+ ++I) {
+ size_t AllocatedSlabSize = BumpPtrAllocator::computeSlabSize(
+ std::distance(Allocator.Slabs.begin(), I));
+ char *Begin = alignPtr((char *)*I, alignOf<T>());
+ char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr
+ : (char *)*I + AllocatedSlabSize;
+
+ DestroyElements(Begin, End);
+ }
+
+ for (auto &PtrAndSize : Allocator.CustomSizedSlabs) {
+ void *Ptr = PtrAndSize.first;
+ size_t Size = PtrAndSize.second;
+ DestroyElements(alignPtr((char *)Ptr, alignOf<T>()), (char *)Ptr + Size);
}
+
Allocator.Reset();
}
@@ -325,10 +404,10 @@ public:
} // end namespace llvm
-template <size_t SlabSize, size_t SizeThreshold>
-void *
-operator new(size_t Size,
- llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &Allocator) {
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
+void *operator new(size_t Size,
+ llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize,
+ SizeThreshold> &Allocator) {
struct S {
char c;
union {
@@ -342,8 +421,9 @@ operator new(size_t Size,
Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
}
-template <size_t SlabSize, size_t SizeThreshold>
-void operator delete(void *,
- llvm::BumpPtrAllocatorImpl<SlabSize, SizeThreshold> &) {}
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
+void operator delete(
+ void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold> &) {
+}
#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
index e974332..36f644a 100644
--- a/include/llvm/Support/ArrayRecycler.h
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -44,10 +44,10 @@ class ArrayRecycler {
// Return NULL if no entries are available.
T *pop(unsigned Idx) {
if (Idx >= Bucket.size())
- return 0;
+ return nullptr;
FreeList *Entry = Bucket[Idx];
if (!Entry)
- return 0;
+ return nullptr;
Bucket[Idx] = Entry->Next;
return reinterpret_cast<T*>(Entry);
}
diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h
index dae520b..4304a25 100644
--- a/include/llvm/Support/BlockFrequency.h
+++ b/include/llvm/Support/BlockFrequency.h
@@ -23,14 +23,8 @@ class BranchProbability;
// This class represents Block Frequency as a 64-bit value.
class BlockFrequency {
-
uint64_t Frequency;
- /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
- /// the division by D. Upon overflow, the routine will saturate and
- /// additionally will return the remainder set to D.
- uint32_t scale(uint32_t N, uint32_t D);
-
public:
BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { }
@@ -58,10 +52,6 @@ public:
/// \brief Shift block frequency to the right by count digits saturating to 1.
BlockFrequency &operator>>=(const unsigned count);
- /// \brief Scale the given BlockFrequency by N/D. Return the remainder from
- /// the division by D. Upon overflow, the routine will saturate.
- uint32_t scale(const BranchProbability &Prob);
-
bool operator<(const BlockFrequency &RHS) const {
return Frequency < RHS.Frequency;
}
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index eedf692..9aab6ac 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -46,10 +46,26 @@ public:
return BranchProbability(D - N, D);
}
- void print(raw_ostream &OS) const;
+ raw_ostream &print(raw_ostream &OS) const;
void dump() const;
+ /// \brief Scale a large integer.
+ ///
+ /// Scales \c Num. Guarantees full precision. Returns the floor of the
+ /// result.
+ ///
+ /// \return \c Num times \c this.
+ uint64_t scale(uint64_t Num) const;
+
+ /// \brief Scale a large integer by the inverse.
+ ///
+ /// Scales \c Num by the inverse of \c this. Guarantees full precision.
+ /// Returns the floor of the result.
+ ///
+ /// \return \c Num divided by \c this.
+ uint64_t scaleByInverse(uint64_t Num) const;
+
bool operator==(BranchProbability RHS) const {
return (uint64_t)N * RHS.D == (uint64_t)D * RHS.N;
}
@@ -59,18 +75,14 @@ public:
bool operator<(BranchProbability RHS) const {
return (uint64_t)N * RHS.D < (uint64_t)D * RHS.N;
}
- bool operator>(BranchProbability RHS) const {
- return RHS < *this;
- }
- bool operator<=(BranchProbability RHS) const {
- return (uint64_t)N * RHS.D <= (uint64_t)D * RHS.N;
- }
- bool operator>=(BranchProbability RHS) const {
- return RHS <= *this;
- }
+ bool operator>(BranchProbability RHS) const { return RHS < *this; }
+ bool operator<=(BranchProbability RHS) const { return !(RHS < *this); }
+ bool operator>=(BranchProbability RHS) const { return !(*this < RHS); }
};
-raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob);
+inline raw_ostream &operator<<(raw_ostream &OS, const BranchProbability &Prob) {
+ return Prob.print(OS);
+}
}
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index dca7fc6..f0e5c7d 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -275,7 +275,7 @@ namespace COFF {
uint16_t Type;
};
- enum RelocationTypeX86 {
+ enum RelocationTypeI386 {
IMAGE_REL_I386_ABSOLUTE = 0x0000,
IMAGE_REL_I386_DIR16 = 0x0001,
IMAGE_REL_I386_REL16 = 0x0002,
@@ -286,8 +286,10 @@ namespace COFF {
IMAGE_REL_I386_SECREL = 0x000B,
IMAGE_REL_I386_TOKEN = 0x000C,
IMAGE_REL_I386_SECREL7 = 0x000D,
- IMAGE_REL_I386_REL32 = 0x0014,
+ IMAGE_REL_I386_REL32 = 0x0014
+ };
+ enum RelocationTypeAMD64 {
IMAGE_REL_AMD64_ABSOLUTE = 0x0000,
IMAGE_REL_AMD64_ADDR64 = 0x0001,
IMAGE_REL_AMD64_ADDR32 = 0x0002,
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 689f590..beed31a 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -245,7 +245,7 @@ inline typename cast_retty<X, Y *>::ret_type cast(Y *Val) {
template <class X, class Y>
LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
cast_or_null(Y *Val) {
- if (Val == 0) return 0;
+ if (!Val) return nullptr;
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
return cast<X>(Val);
}
@@ -263,19 +263,19 @@ template <class X, class Y>
LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if<
!is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>::type
dyn_cast(const Y &Val) {
- return isa<X>(Val) ? cast<X>(Val) : 0;
+ return isa<X>(Val) ? cast<X>(Val) : nullptr;
}
template <class X, class Y>
LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y>::ret_type
dyn_cast(Y &Val) {
- return isa<X>(Val) ? cast<X>(Val) : 0;
+ return isa<X>(Val) ? cast<X>(Val) : nullptr;
}
template <class X, class Y>
LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
dyn_cast(Y *Val) {
- return isa<X>(Val) ? cast<X>(Val) : 0;
+ return isa<X>(Val) ? cast<X>(Val) : nullptr;
}
// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
@@ -284,7 +284,7 @@ dyn_cast(Y *Val) {
template <class X, class Y>
LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty<X, Y *>::ret_type
dyn_cast_or_null(Y *Val) {
- return (Val && isa<X>(Val)) ? cast<X>(Val) : 0;
+ return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
}
} // End llvm namespace
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index e49a97e..5cb5501 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -41,14 +41,14 @@ namespace cl {
// ParseCommandLineOptions - Command line option processing entry point.
//
void ParseCommandLineOptions(int argc, const char * const *argv,
- const char *Overview = 0);
+ const char *Overview = nullptr);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
// entry point.
//
void ParseEnvironmentOptions(const char *progName, const char *envvar,
- const char *Overview = 0);
+ const char *Overview = nullptr);
///===---------------------------------------------------------------------===//
/// SetVersionPrinter - Override the default (LLVM specific) version printer
@@ -146,7 +146,7 @@ private:
const char *const Description;
void registerCategory();
public:
- OptionCategory(const char *const Name, const char *const Description = 0)
+ OptionCategory(const char *const Name, const char *const Description = nullptr)
: Name(Name), Description(Description) { registerCategory(); }
const char *getName() const { return Name; }
const char *getDescription() const { return Description; }
@@ -238,7 +238,7 @@ protected:
enum OptionHidden Hidden)
: NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
- Position(0), AdditionalVals(0), NextRegistered(0),
+ Position(0), AdditionalVals(0), NextRegistered(nullptr),
ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) {
}
@@ -763,7 +763,7 @@ public:
}
// getValueName - Do not print =<value> at all.
- const char *getValueName() const override { return 0; }
+ const char *getValueName() const override { return nullptr; }
void printOptionDiff(const Option &O, bool V, OptVal Default,
size_t GlobalWidth) const;
@@ -787,7 +787,7 @@ public:
}
// getValueName - Do not print =<value> at all.
- const char *getValueName() const override { return 0; }
+ const char *getValueName() const override { return nullptr; }
void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
size_t GlobalWidth) const;
@@ -1063,12 +1063,12 @@ class opt_storage {
OptionValue<DataType> Default;
void check_location() const {
- assert(Location != 0 && "cl::location(...) not specified for a command "
+ assert(Location && "cl::location(...) not specified for a command "
"line option with external storage, "
"or cl::init specified before cl::location()!!");
}
public:
- opt_storage() : Location(0) {}
+ opt_storage() : Location(nullptr) {}
bool setLocation(Option &O, DataType &L) {
if (Location)
@@ -1469,7 +1469,7 @@ class bits_storage {
}
public:
- bits_storage() : Location(0) {}
+ bits_storage() : Location(nullptr) {}
bool setLocation(Option &O, unsigned &L) {
if (Location)
@@ -1664,7 +1664,7 @@ class alias : public Option {
void done() {
if (!hasArgStr())
error("cl::alias must have argument name specified!");
- if (AliasFor == 0)
+ if (!AliasFor)
error("cl::alias must have an cl::aliasopt(option) specified!");
addArgument();
}
@@ -1677,27 +1677,28 @@ public:
// One option...
template<class M0t>
- explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(0) {
+ explicit alias(const M0t &M0) : Option(Optional, Hidden), AliasFor(nullptr) {
apply(M0, this);
done();
}
// Two options...
template<class M0t, class M1t>
- alias(const M0t &M0, const M1t &M1) : Option(Optional, Hidden), AliasFor(0) {
+ alias(const M0t &M0, const M1t &M1)
+ : Option(Optional, Hidden), AliasFor(nullptr) {
apply(M0, this); apply(M1, this);
done();
}
// Three options...
template<class M0t, class M1t, class M2t>
alias(const M0t &M0, const M1t &M1, const M2t &M2)
- : Option(Optional, Hidden), AliasFor(0) {
+ : Option(Optional, Hidden), AliasFor(nullptr) {
apply(M0, this); apply(M1, this); apply(M2, this);
done();
}
// Four options...
template<class M0t, class M1t, class M2t, class M3t>
alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
- : Option(Optional, Hidden), AliasFor(0) {
+ : Option(Optional, Hidden), AliasFor(nullptr) {
apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
done();
}
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index 80eff5c..8152b60 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -16,10 +16,10 @@
#include "llvm/Support/DataTypes.h"
#include <memory>
+#include "llvm/ADT/SmallVector.h"
namespace llvm {
-class MemoryBuffer;
class StringRef;
namespace zlib {
@@ -42,12 +42,11 @@ enum Status {
bool isAvailable();
-Status compress(StringRef InputBuffer,
- std::unique_ptr<MemoryBuffer> &CompressedBuffer,
+Status compress(StringRef InputBuffer, SmallVectorImpl<char> &CompressedBuffer,
CompressionLevel Level = DefaultCompression);
Status uncompress(StringRef InputBuffer,
- std::unique_ptr<MemoryBuffer> &UncompressedBuffer,
+ SmallVectorImpl<char> &UncompressedBuffer,
size_t UncompressedSize);
uint32_t crc32(StringRef Buffer);
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 4500efe..c132373 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -12,11 +12,13 @@
#include <string>
+#include "llvm/ADT/STLExtras.h"
+
namespace llvm {
class StringRef;
class CrashRecoveryContextCleanup;
-
+
/// \brief Crash recovery helper object.
///
/// This class implements support for running operations in a safe context so
@@ -46,21 +48,10 @@ class CrashRecoveryContext {
void *Impl;
CrashRecoveryContextCleanup *head;
- /// An adaptor to convert an arbitrary functor into a void(void*), void* pair.
- template<typename T> struct FunctorAdaptor {
- T Fn;
- static void invoke(void *Data) {
- return static_cast<FunctorAdaptor<T>*>(Data)->Fn();
- }
- typedef void Callback(void*);
- Callback *fn() { return &invoke; }
- void *arg() { return this; }
- };
-
public:
- CrashRecoveryContext() : Impl(0), head(0) {}
+ CrashRecoveryContext() : Impl(nullptr), head(nullptr) {}
~CrashRecoveryContext();
-
+
void registerCleanup(CrashRecoveryContextCleanup *cleanup);
void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
@@ -86,11 +77,9 @@ public:
/// make as little assumptions as possible about the program state when
/// RunSafely has returned false. Clients can use getBacktrace() to retrieve
/// the backtrace of the crash on failures.
- bool RunSafely(void (*Fn)(void*), void *UserData);
- template<typename Functor>
- bool RunSafely(Functor Fn) {
- FunctorAdaptor<Functor> Adaptor = { Fn };
- return RunSafely(Adaptor.fn(), Adaptor.arg());
+ bool RunSafely(function_ref<void()> Fn);
+ bool RunSafely(void (*Fn)(void*), void *UserData) {
+ return RunSafely([&]() { Fn(UserData); });
}
/// \brief Execute the provide callback function (with the given arguments) in
@@ -98,12 +87,10 @@ public:
/// requested stack size).
///
/// See RunSafely() and llvm_execute_on_thread().
+ bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0);
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
- unsigned RequestedStackSize = 0);
- template<typename Functor>
- bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
- FunctorAdaptor<Functor> Adaptor = { Fn };
- return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize);
+ unsigned RequestedStackSize = 0) {
+ return RunSafelyOnThread([&]() { Fn(UserData); }, RequestedStackSize);
}
/// \brief Explicitly trigger a crash recovery in the current process, and
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index 2702408..e93e6ca 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -13,10 +13,12 @@
//
// In particular, just wrap your code with the DEBUG() macro, and it will be
// enabled automatically if you specify '-debug' on the command-line.
-// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
-// that your debug code belongs to class "foo". Then, on the command line, you
-// can specify '-debug-only=foo' to enable JUST the debug information for the
-// foo class.
+// Alternatively, you can also define the DEBUG_TYPE macro to "foo" specify
+// that your debug code belongs to class "foo". Be careful that you only do
+// this after including Debug.h and not around any #include of headers. Headers
+// should define and undef the macro acround the code that needs to use the
+// DEBUG() macro. Then, on the command line, you can specify '-debug-only=foo'
+// to enable JUST the debug information for the foo class.
//
// When compiling without assertions, the -debug-* options and all code in
// DEBUG() statements disappears, so it does not affect the runtime of the code.
@@ -30,12 +32,6 @@
namespace llvm {
-/// DEBUG_TYPE macro - Files can specify a DEBUG_TYPE as a string, which causes
-/// all of their DEBUG statements to be activatable with -debug-only=thatstring.
-#ifndef DEBUG_TYPE
-#define DEBUG_TYPE ""
-#endif
-
#ifndef NDEBUG
/// DebugFlag - This boolean is set to true if the '-debug' command line option
/// is specified. This should probably not be referenced directly, instead, use
diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
index 1e2d16c..de47be6 100644
--- a/include/llvm/Support/DynamicLibrary.h
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -65,7 +65,7 @@ namespace sys {
/// It is safe to call this function multiple times for the same library.
/// @brief Open a dynamic library permanently.
static DynamicLibrary getPermanentLibrary(const char *filename,
- std::string *errMsg = 0);
+ std::string *errMsg = nullptr);
/// This function permanently loads the dynamic library at the given path.
/// Use this instead of getPermanentLibrary() when you won't need to get
@@ -73,7 +73,7 @@ namespace sys {
///
/// It is safe to call this function multiple times for the same library.
static bool LoadLibraryPermanently(const char *Filename,
- std::string *ErrMsg = 0) {
+ std::string *ErrMsg = nullptr) {
return !getPermanentLibrary(Filename, ErrMsg).isValid();
}
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index 7b10ebd..0b3e55b 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -807,6 +807,7 @@ enum : unsigned {
EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
EF_MIPS_ABI2 = 0x00000020,
EF_MIPS_32BITMODE = 0x00000100,
+ EF_MIPS_NAN2008 = 0x00000400, // Uses IEE 754-2008 NaN encoding
EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
//ARCH_ASE
@@ -823,11 +824,12 @@ enum : unsigned {
EF_MIPS_ARCH_64 = 0x60000000, // MIPS64 instruction set per linux not elf.h
EF_MIPS_ARCH_32R2 = 0x70000000, // mips32r2
EF_MIPS_ARCH_64R2 = 0x80000000, // mips64r2
+ EF_MIPS_ARCH_32R6 = 0x90000000, // mips32r6
+ EF_MIPS_ARCH_64R6 = 0xa0000000, // mips64r6
EF_MIPS_ARCH = 0xf0000000 // Mask for applying EF_MIPS_ARCH_ variant
};
// ELF Relocation types for Mips
-// .
enum {
R_MIPS_NONE = 0,
R_MIPS_16 = 1,
@@ -880,6 +882,12 @@ enum {
R_MIPS_TLS_TPREL_HI16 = 49,
R_MIPS_TLS_TPREL_LO16 = 50,
R_MIPS_GLOB_DAT = 51,
+ R_MIPS_PC21_S2 = 60,
+ R_MIPS_PC26_S2 = 61,
+ R_MIPS_PC18_S3 = 62,
+ R_MIPS_PC19_S2 = 63,
+ R_MIPS_PCHI16 = 64,
+ R_MIPS_PCLO16 = 65,
R_MIPS16_GOT16 = 102,
R_MIPS16_HI16 = 104,
R_MIPS16_LO16 = 105,
@@ -906,7 +914,11 @@ enum {
// Special values for the st_other field in the symbol table entry for MIPS.
enum {
- STO_MIPS_MICROMIPS = 0x80 // MIPS Specific ISA for MicroMips
+ STO_MIPS_OPTIONAL = 0x04, // Symbol whose definition is optional
+ STO_MIPS_PLT = 0x08, // PLT entry related dynamic table record
+ STO_MIPS_PIC = 0x20, // PIC func in an object mixes PIC/non-PIC
+ STO_MIPS_MICROMIPS = 0x80, // MIPS Specific ISA for MicroMips
+ STO_MIPS_MIPS16 = 0xf0 // MIPS Specific ISA for Mips16
};
// Hexagon Specific e_flags
@@ -1661,6 +1673,7 @@ enum {
DT_LOPROC = 0x70000000, // Start of processor specific tags.
DT_HIPROC = 0x7FFFFFFF, // End of processor specific tags.
+ DT_GNU_HASH = 0x6FFFFEF5, // Reference to the GNU hash table.
DT_RELACOUNT = 0x6FFFFFF9, // ELF32_Rela count.
DT_RELCOUNT = 0x6FFFFFFA, // ELF32_Rel count.
diff --git a/include/llvm/Support/ErrorHandling.h b/include/llvm/Support/ErrorHandling.h
index b948d97..ac3a4d8 100644
--- a/include/llvm/Support/ErrorHandling.h
+++ b/include/llvm/Support/ErrorHandling.h
@@ -47,7 +47,7 @@ namespace llvm {
/// \param user_data - An argument which will be passed to the install error
/// handler.
void install_fatal_error_handler(fatal_error_handler_t handler,
- void *user_data = 0);
+ void *user_data = nullptr);
/// Restores default error handling behaviour.
/// This must not be called between llvm_start_multithreaded() and
@@ -59,7 +59,7 @@ namespace llvm {
/// remove_fatal_error_handler in its destructor.
struct ScopedFatalErrorHandler {
explicit ScopedFatalErrorHandler(fatal_error_handler_t handler,
- void *user_data = 0) {
+ void *user_data = nullptr) {
install_fatal_error_handler(handler, user_data);
}
@@ -86,9 +86,9 @@ namespace llvm {
/// This function calls abort(), and prints the optional message to stderr.
/// Use the llvm_unreachable macro (that adds location info), instead of
/// calling this function directly.
- LLVM_ATTRIBUTE_NORETURN void llvm_unreachable_internal(const char *msg=0,
- const char *file=0,
- unsigned line=0);
+ LLVM_ATTRIBUTE_NORETURN void
+ llvm_unreachable_internal(const char *msg=nullptr, const char *file=nullptr,
+ unsigned line=0);
}
/// Marks that the current location is not supposed to be reachable.
diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h
index 1884a24..a8a48fa 100644
--- a/include/llvm/Support/FileOutputBuffer.h
+++ b/include/llvm/Support/FileOutputBuffer.h
@@ -14,7 +14,6 @@
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
@@ -41,9 +40,6 @@ public:
/// buffer of the specified size. When committed, the buffer will be written
/// to the file at the specified path.
static error_code create(StringRef FilePath, size_t Size,
- OwningPtr<FileOutputBuffer> &Result,
- unsigned Flags = 0);
- static error_code create(StringRef FilePath, size_t Size,
std::unique_ptr<FileOutputBuffer> &Result,
unsigned Flags = 0);
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index b511a8e..806a3e3 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -165,15 +165,30 @@ class file_status
file_type Type;
perms Perms;
public:
- file_status() : Type(file_type::status_error) {}
- file_status(file_type Type) : Type(Type) {}
-
#if defined(LLVM_ON_UNIX)
+ file_status() : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+ fs_st_uid(0), fs_st_gid(0), fs_st_size(0),
+ Type(file_type::status_error), Perms(perms_not_known) {}
+
+ file_status(file_type Type) : fs_st_dev(0), fs_st_ino(0), fs_st_mtime(0),
+ fs_st_uid(0), fs_st_gid(0), fs_st_size(0), Type(Type),
+ Perms(perms_not_known) {}
+
file_status(file_type Type, perms Perms, dev_t Dev, ino_t Ino, time_t MTime,
uid_t UID, gid_t GID, off_t Size)
: fs_st_dev(Dev), fs_st_ino(Ino), fs_st_mtime(MTime), fs_st_uid(UID),
fs_st_gid(GID), fs_st_size(Size), Type(Type), Perms(Perms) {}
#elif defined(LLVM_ON_WIN32)
+ file_status() : LastWriteTimeHigh(0), LastWriteTimeLow(0),
+ VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
+ FileIndexHigh(0), FileIndexLow(0), Type(file_type::status_error),
+ Perms(perms_not_known) {}
+
+ file_status(file_type Type) : LastWriteTimeHigh(0), LastWriteTimeLow(0),
+ VolumeSerialNumber(0), FileSizeHigh(0), FileSizeLow(0),
+ FileIndexHigh(0), FileIndexLow(0), Type(Type),
+ Perms(perms_not_known) {}
+
file_status(file_type Type, uint32_t LastWriteTimeHigh,
uint32_t LastWriteTimeLow, uint32_t VolumeSerialNumber,
uint32_t FileSizeHigh, uint32_t FileSizeLow,
@@ -562,7 +577,7 @@ error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
error_code createUniqueDirectory(const Twine &Prefix,
SmallVectorImpl<char> &ResultPath);
-enum OpenFlags {
+enum OpenFlags : unsigned {
F_None = 0,
/// F_Excl - When opening a file, this flag makes raw_fd_ostream
@@ -814,7 +829,7 @@ public:
}
/// Construct end iterator.
- directory_iterator() : State(0) {}
+ directory_iterator() : State(nullptr) {}
// No operator++ because we need error_code.
directory_iterator &increment(error_code &ec) {
@@ -828,9 +843,9 @@ public:
bool operator==(const directory_iterator &RHS) const {
if (State == RHS.State)
return true;
- if (RHS.State == 0)
+ if (!RHS.State)
return State->CurrentEntry == directory_entry();
- if (State == 0)
+ if (!State)
return RHS.State->CurrentEntry == directory_entry();
return State->CurrentEntry == RHS.State->CurrentEntry;
}
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 873b8df..3f2f176 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -30,7 +30,7 @@ namespace llvm {
int DiffFilesWithTolerance(StringRef FileA,
StringRef FileB,
double AbsTol, double RelTol,
- std::string *Error = 0);
+ std::string *Error = nullptr);
/// FileRemover - This class is a simple object meant to be stack allocated.
diff --git a/include/llvm/Support/FormattedStream.h b/include/llvm/Support/FormattedStream.h
index 78c4809..8137daa 100644
--- a/include/llvm/Support/FormattedStream.h
+++ b/include/llvm/Support/FormattedStream.h
@@ -85,12 +85,12 @@ public:
/// underneath it.
///
formatted_raw_ostream(raw_ostream &Stream, bool Delete = false)
- : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
+ : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
setStream(Stream, Delete);
}
explicit formatted_raw_ostream()
- : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
- Scanned = 0;
+ : raw_ostream(), TheStream(nullptr), DeleteStream(false), Position(0, 0) {
+ Scanned = nullptr;
}
~formatted_raw_ostream() {
@@ -114,7 +114,7 @@ public:
SetUnbuffered();
TheStream->SetUnbuffered();
- Scanned = 0;
+ Scanned = nullptr;
}
/// PadToColumn - Align the output to some column number. If the current
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index 902f2db..0cb6cfd 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -37,9 +37,9 @@ namespace GCOV {
/// GCOVOptions - A struct for passing gcov options between functions.
struct GCOVOptions {
- GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U)
+ GCOVOptions(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N)
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
- PreservePaths(P), UncondBranch(U) {}
+ PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N) {}
bool AllBlocks;
bool BranchInfo;
@@ -47,6 +47,8 @@ struct GCOVOptions {
bool FuncCoverage;
bool PreservePaths;
bool UncondBranch;
+ bool LongFileNames;
+ bool NoOutput;
};
/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific
@@ -232,7 +234,6 @@ class GCOVFile {
public:
GCOVFile() : GCNOInitialized(false), Checksum(0), Functions(), RunCount(0),
ProgramCount(0) {}
- ~GCOVFile();
bool readGCNO(GCOVBuffer &Buffer);
bool readGCDA(GCOVBuffer &Buffer);
uint32_t getChecksum() const { return Checksum; }
@@ -242,27 +243,27 @@ private:
bool GCNOInitialized;
GCOV::GCOVVersion Version;
uint32_t Checksum;
- SmallVector<GCOVFunction *, 16> Functions;
+ SmallVector<std::unique_ptr<GCOVFunction>, 16> Functions;
uint32_t RunCount;
uint32_t ProgramCount;
};
/// GCOVEdge - Collects edge information.
struct GCOVEdge {
- GCOVEdge(GCOVBlock *S, GCOVBlock *D): Src(S), Dst(D), Count(0) {}
+ GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D), Count(0) {}
- GCOVBlock *Src;
- GCOVBlock *Dst;
+ GCOVBlock &Src;
+ GCOVBlock &Dst;
uint64_t Count;
};
/// GCOVFunction - Collects function information.
class GCOVFunction {
public:
- typedef SmallVectorImpl<GCOVBlock *>::const_iterator BlockIterator;
+ typedef SmallVectorImpl<std::unique_ptr<GCOVBlock>>::const_iterator
+ BlockIterator;
GCOVFunction(GCOVFile &P) : Parent(P), Ident(0), LineNumber(0) {}
- ~GCOVFunction();
bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
StringRef getName() const { return Name; }
@@ -283,8 +284,8 @@ private:
uint32_t LineNumber;
StringRef Name;
StringRef Filename;
- SmallVector<GCOVBlock *, 16> Blocks;
- SmallVector<GCOVEdge *, 16> Edges;
+ SmallVector<std::unique_ptr<GCOVBlock>, 16> Blocks;
+ SmallVector<std::unique_ptr<GCOVEdge>, 16> Edges;
};
/// GCOVBlock - Collects block information.
@@ -298,7 +299,7 @@ class GCOVBlock {
struct SortDstEdgesFunctor {
bool operator()(const GCOVEdge *E1, const GCOVEdge *E2) {
- return E1->Dst->Number < E2->Dst->Number;
+ return E1->Dst.Number < E2->Dst.Number;
}
};
public:
@@ -314,13 +315,13 @@ public:
uint64_t getCount() const { return Counter; }
void addSrcEdge(GCOVEdge *Edge) {
- assert(Edge->Dst == this); // up to caller to ensure edge is valid
+ assert(&Edge->Dst == this); // up to caller to ensure edge is valid
SrcEdges.push_back(Edge);
}
void addDstEdge(GCOVEdge *Edge) {
- assert(Edge->Src == this); // up to caller to ensure edge is valid
+ assert(&Edge->Src == this); // up to caller to ensure edge is valid
// Check if adding this edge causes list to become unsorted.
- if (DstEdges.size() && DstEdges.back()->Dst->Number > Edge->Dst->Number)
+ if (DstEdges.size() && DstEdges.back()->Dst.Number > Edge->Dst.Number)
DstEdgesAreSorted = false;
DstEdges.push_back(Edge);
}
@@ -355,8 +356,10 @@ class FileInfo {
typedef DenseMap<uint32_t, BlockVector> BlockLines;
struct LineData {
+ LineData() : LastLine(0) {}
BlockLines Blocks;
FunctionLines Functions;
+ uint32_t LastLine;
};
struct GCOVCoverage {
@@ -378,23 +381,30 @@ public:
Options(Options), LineInfo(), RunCount(0), ProgramCount(0) {}
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
+ if (Line > LineInfo[Filename].LastLine)
+ LineInfo[Filename].LastLine = Line;
LineInfo[Filename].Blocks[Line-1].push_back(Block);
}
void addFunctionLine(StringRef Filename, uint32_t Line,
const GCOVFunction *Function) {
+ if (Line > LineInfo[Filename].LastLine)
+ LineInfo[Filename].LastLine = Line;
LineInfo[Filename].Functions[Line-1].push_back(Function);
}
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
- void print(StringRef GCNOFile, StringRef GCDAFile);
+ void print(StringRef MainFilename, StringRef GCNOFile, StringRef GCDAFile);
+
private:
- void printFunctionSummary(raw_fd_ostream &OS,
+ std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
+ std::unique_ptr<raw_ostream> openCoveragePath(StringRef CoveragePath);
+ void printFunctionSummary(raw_ostream &OS,
const FunctionVector &Funcs) const;
- void printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ void printBlockInfo(raw_ostream &OS, const GCOVBlock &Block,
uint32_t LineIndex, uint32_t &BlockNo) const;
- void printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
+ void printBranchInfo(raw_ostream &OS, const GCOVBlock &Block,
GCOVCoverage &Coverage, uint32_t &EdgeNo);
- void printUncondBranchInfo(raw_fd_ostream &OS, uint32_t &EdgeNo,
+ void printUncondBranchInfo(raw_ostream &OS, uint32_t &EdgeNo,
uint64_t Count) const;
void printCoverage(const GCOVCoverage &Coverage) const;
diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h
index 6878844..e344220 100644
--- a/include/llvm/Support/GenericDomTree.h
+++ b/include/llvm/Support/GenericDomTree.h
@@ -186,9 +186,9 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
assert(isReachableFromEntry(A));
const DomTreeNodeBase<NodeT> *IDom;
- while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
+ while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
B = IDom; // Walk up the tree
- return IDom != 0;
+ return IDom != nullptr;
}
protected:
@@ -205,7 +205,7 @@ protected:
unsigned Semi;
NodeT *Label;
- InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(0) {}
+ InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {}
};
DenseMap<NodeT*, NodeT*> IDoms;
@@ -224,7 +224,7 @@ protected:
IDoms.clear();
this->Roots.clear();
Vertex.clear();
- RootNode = 0;
+ RootNode = nullptr;
}
// NewBB is split and now it has one successor. Update dominator tree to
@@ -260,7 +260,7 @@ protected:
// Find NewBB's immediate dominator and create new dominator tree node for
// NewBB.
- NodeT *NewBBIDom = 0;
+ NodeT *NewBBIDom = nullptr;
unsigned i = 0;
for (i = 0; i < PredBlocks.size(); ++i)
if (DT.isReachableFromEntry(PredBlocks[i])) {
@@ -344,7 +344,7 @@ public:
void getDescendants(NodeT *R, SmallVectorImpl<NodeT *> &Result) const {
Result.clear();
const DomTreeNodeBase<NodeT> *RN = getNode(R);
- if (RN == NULL)
+ if (!RN)
return; // If R is unreachable, it will not be present in the DOM tree.
SmallVector<const DomTreeNodeBase<NodeT> *, 8> WL;
WL.push_back(RN);
@@ -361,7 +361,7 @@ public:
///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const {
- if (A == 0 || B == 0)
+ if (!A || !B)
return false;
if (A == B)
return false;
@@ -453,6 +453,21 @@ public:
DomTreeNodeBase<NodeT> *NodeA = getNode(A);
DomTreeNodeBase<NodeT> *NodeB = getNode(B);
+ // If we have DFS info, then we can avoid all allocations by just querying
+ // it from each IDom. Note that because we call 'dominates' twice above, we
+ // expect to call through this code at most 16 times in a row without
+ // building valid DFS information. This is important as below is a *very*
+ // slow tree walk.
+ if (DFSInfoValid) {
+ DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
+ while (IDomA) {
+ if (NodeB->DominatedBy(IDomA))
+ return IDomA->getBlock();
+ IDomA = IDomA->getIDom();
+ }
+ return nullptr;
+ }
+
// Collect NodeA dominators set.
SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms;
NodeADoms.insert(NodeA);
@@ -471,7 +486,7 @@ public:
IDomB = IDomB->getIDom();
}
- return NULL;
+ return nullptr;
}
const NodeT *findNearestCommonDominator(const NodeT *A, const NodeT *B) {
@@ -489,7 +504,7 @@ public:
/// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
DomTreeNodeBase<NodeT> *addNewBlock(NodeT *BB, NodeT *DomBB) {
- assert(getNode(BB) == 0 && "Block already in dominator tree!");
+ assert(getNode(BB) == nullptr && "Block already in dominator tree!");
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
@@ -636,7 +651,7 @@ protected:
// immediate dominator.
NodeT *IDom = getIDom(BB);
- assert(IDom || this->DomTreeNodes[NULL]);
+ assert(IDom || this->DomTreeNodes[nullptr]);
DomTreeNodeBase<NodeT> *IDomNode = getNodeForBlock(IDom);
// Add a new tree node for this NodeT, and link it as a child of
@@ -659,14 +674,14 @@ public:
void recalculate(FT& F) {
typedef GraphTraits<FT*> TraitsTy;
reset();
- this->Vertex.push_back(0);
+ this->Vertex.push_back(nullptr);
if (!this->IsPostDominators) {
// Initialize root
NodeT *entry = TraitsTy::getEntryNode(&F);
this->Roots.push_back(entry);
- this->IDoms[entry] = 0;
- this->DomTreeNodes[entry] = 0;
+ this->IDoms[entry] = nullptr;
+ this->DomTreeNodes[entry] = nullptr;
Calculate<FT, NodeT*>(*this, F);
} else {
@@ -677,8 +692,8 @@ public:
addRoot(I);
// Prepopulate maps so that we don't get iterator invalidation issues later.
- this->IDoms[I] = 0;
- this->DomTreeNodes[I] = 0;
+ this->IDoms[I] = nullptr;
+ this->DomTreeNodes[I] = nullptr;
}
Calculate<FT, Inverse<NodeT*> >(*this, F);
diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h
index f6bb8f4..bcba5e0 100644
--- a/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/include/llvm/Support/GenericDomTreeConstruction.h
@@ -156,11 +156,11 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
bool MultipleRoots = (DT.Roots.size() > 1);
if (MultipleRoots) {
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
- DT.Info[NULL];
+ DT.Info[nullptr];
BBInfo.DFSNum = BBInfo.Semi = ++N;
- BBInfo.Label = NULL;
+ BBInfo.Label = nullptr;
- DT.Vertex.push_back(NULL); // Vertex[n] = V;
+ DT.Vertex.push_back(nullptr); // Vertex[n] = V;
}
// Step #1: Number blocks in depth-first order and initialize variables used
@@ -249,10 +249,10 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
// one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
// which postdominates all real exits if there are multiple exit blocks, or
// an infinite loop.
- typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;
+ typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr;
DT.DomTreeNodes[Root] = DT.RootNode =
- new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0);
+ new DomTreeNodeBase<typename GraphT::NodeType>(Root, nullptr);
// Loop over all of the reachable blocks in the function...
for (unsigned i = 2; i <= N; ++i) {
@@ -263,7 +263,7 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
typename GraphT::NodeType* ImmDom = DT.getIDom(W);
- assert(ImmDom || DT.DomTreeNodes[NULL]);
+ assert(ImmDom || DT.DomTreeNodes[nullptr]);
// Get or calculate the node for the immediate dominator
DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 62547dd..539673a 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -259,8 +259,8 @@ public:
/// emitSimpleNode - Outputs a simple (non-record) node
void emitSimpleNode(const void *ID, const std::string &Attr,
- const std::string &Label, unsigned NumEdgeSources = 0,
- const std::vector<std::string> *EdgeSourceLabels = 0) {
+ const std::string &Label, unsigned NumEdgeSources = 0,
+ const std::vector<std::string> *EdgeSourceLabels = nullptr) {
O << "\tNode" << ID << "[ ";
if (!Attr.empty())
O << Attr << ",";
@@ -325,7 +325,10 @@ template <typename GraphType>
std::string WriteGraph(const GraphType &G, const Twine &Name,
bool ShortNames = false, const Twine &Title = "") {
int FD;
- std::string Filename = createGraphFilename(Name, FD);
+ // Windows can't always handle long paths, so limit the length of the name.
+ std::string N = Name.str();
+ N = N.substr(0, std::min<std::size_t>(N.size(), 140));
+ std::string Filename = createGraphFilename(N, FD);
raw_fd_ostream O(FD, /*shouldClose=*/ true);
if (FD == -1) {
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index 9ef5fe6..ea76c9b 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -77,7 +77,7 @@ inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
/// Utility function to decode a ULEB128 value.
-inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = 0) {
+inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) {
const uint8_t *orig_p = p;
uint64_t Value = 0;
unsigned Shift = 0;
diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h
index 7077656..2a58262 100644
--- a/include/llvm/Support/LineIterator.h
+++ b/include/llvm/Support/LineIterator.h
@@ -11,6 +11,7 @@
#define LLVM_SUPPORT_LINEITERATOR_H__
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
#include <iterator>
namespace llvm {
@@ -28,7 +29,7 @@ class MemoryBuffer;
///
/// Note that this iterator requires the buffer to be nul terminated.
class line_iterator
- : public std::iterator<std::forward_iterator_tag, StringRef, ptrdiff_t> {
+ : public std::iterator<std::forward_iterator_tag, StringRef> {
const MemoryBuffer *Buffer;
char CommentMarker;
@@ -37,7 +38,7 @@ class line_iterator
public:
/// \brief Default construct an "end" iterator.
- line_iterator() : Buffer(0) {}
+ line_iterator() : Buffer(nullptr) {}
/// \brief Construct a new iterator around some memory buffer.
explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0');
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 9df8675..523a781 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -40,6 +40,16 @@ public:
LFS_Error
};
+ /// \brief Describes the result of waiting for the owner to release the lock.
+ enum WaitForUnlockResult {
+ /// \brief The lock was released successfully.
+ Res_Success,
+ /// \brief Owner died while holding the lock.
+ Res_OwnerDied,
+ /// \brief Reached timeout while waiting for the owner to release the lock.
+ Res_Timeout
+ };
+
private:
SmallString<128> FileName;
SmallString<128> LockFileName;
@@ -67,7 +77,7 @@ public:
operator LockFileState() const { return getState(); }
/// \brief For a shared lock, wait until the owner releases the lock.
- void waitForUnlock();
+ WaitForUnlockResult waitForUnlock();
};
} // end namespace llvm
diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h
index ef06a41..2a0fc7b 100644
--- a/include/llvm/Support/MachO.h
+++ b/include/llvm/Support/MachO.h
@@ -153,27 +153,59 @@ namespace llvm {
enum SectionType : uint32_t {
// Constant masks for the "flags[7:0]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_TYPE)
+
+ /// S_REGULAR - Regular section.
S_REGULAR = 0x00u,
+ /// S_ZEROFILL - Zero fill on demand section.
S_ZEROFILL = 0x01u,
+ /// S_CSTRING_LITERALS - Section with literal C strings.
S_CSTRING_LITERALS = 0x02u,
+ /// S_4BYTE_LITERALS - Section with 4 byte literals.
S_4BYTE_LITERALS = 0x03u,
+ /// S_8BYTE_LITERALS - Section with 8 byte literals.
S_8BYTE_LITERALS = 0x04u,
+ /// S_LITERAL_POINTERS - Section with pointers to literals.
S_LITERAL_POINTERS = 0x05u,
+ /// S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
S_NON_LAZY_SYMBOL_POINTERS = 0x06u,
+ /// S_LAZY_SYMBOL_POINTERS - Section with lazy symbol pointers.
S_LAZY_SYMBOL_POINTERS = 0x07u,
+ /// S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in
+ /// the Reserved2 field.
S_SYMBOL_STUBS = 0x08u,
+ /// S_MOD_INIT_FUNC_POINTERS - Section with only function pointers for
+ /// initialization.
S_MOD_INIT_FUNC_POINTERS = 0x09u,
+ /// S_MOD_TERM_FUNC_POINTERS - Section with only function pointers for
+ /// termination.
S_MOD_TERM_FUNC_POINTERS = 0x0au,
+ /// S_COALESCED - Section contains symbols that are to be coalesced.
S_COALESCED = 0x0bu,
+ /// S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4
+ /// gigabytes).
S_GB_ZEROFILL = 0x0cu,
+ /// S_INTERPOSING - Section with only pairs of function pointers for
+ /// interposing.
S_INTERPOSING = 0x0du,
+ /// S_16BYTE_LITERALS - Section with only 16 byte literals.
S_16BYTE_LITERALS = 0x0eu,
+ /// S_DTRACE_DOF - Section contains DTrace Object Format.
S_DTRACE_DOF = 0x0fu,
+ /// S_LAZY_DYLIB_SYMBOL_POINTERS - Section with lazy symbol pointers to
+ /// lazy loaded dylibs.
S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10u,
+ /// S_THREAD_LOCAL_REGULAR - Thread local data section.
S_THREAD_LOCAL_REGULAR = 0x11u,
+ /// S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
S_THREAD_LOCAL_ZEROFILL = 0x12u,
+ /// S_THREAD_LOCAL_VARIABLES - Section with thread local variable
+ /// structure data.
S_THREAD_LOCAL_VARIABLES = 0x13u,
+ /// S_THREAD_LOCAL_VARIABLE_POINTERS - Section with pointers to thread
+ /// local structures.
S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14u,
+ /// S_THREAD_LOCAL_INIT_FUNCTION_POINTERS - Section with thread local
+ /// variable initialization pointers to functions.
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u,
LAST_KNOWN_SECTION_TYPE = S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
@@ -182,18 +214,34 @@ namespace llvm {
enum : uint32_t {
// Constant masks for the "flags[31:24]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
+
+ /// S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine
+ /// instructions.
S_ATTR_PURE_INSTRUCTIONS = 0x80000000u,
+ /// S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be
+ /// in a ranlib table of contents.
S_ATTR_NO_TOC = 0x40000000u,
+ /// S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section
+ /// in files with the MY_DYLDLINK flag.
S_ATTR_STRIP_STATIC_SYMS = 0x20000000u,
+ /// S_ATTR_NO_DEAD_STRIP - No dead stripping.
S_ATTR_NO_DEAD_STRIP = 0x10000000u,
+ /// S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
S_ATTR_LIVE_SUPPORT = 0x08000000u,
+ /// S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by
+ /// dyld.
S_ATTR_SELF_MODIFYING_CODE = 0x04000000u,
+ /// S_ATTR_DEBUG - A debug section.
S_ATTR_DEBUG = 0x02000000u,
// Constant masks for the "flags[23:8]" field in llvm::MachO::section and
// llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_SYS)
+
+ /// S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
S_ATTR_SOME_INSTRUCTIONS = 0x00000400u,
+ /// S_ATTR_EXT_RELOC - Section has external relocation entries.
S_ATTR_EXT_RELOC = 0x00000200u,
+ /// S_ATTR_LOC_RELOC - Section has local relocation entries.
S_ATTR_LOC_RELOC = 0x00000100u,
// Constant masks for the value of an indirect symbol in an indirect
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
index 5587618..1bb8cea 100644
--- a/include/llvm/Support/ManagedStatic.h
+++ b/include/llvm/Support/ManagedStatic.h
@@ -47,7 +47,7 @@ protected:
void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
public:
/// isConstructed - Return true if this object has not been created yet.
- bool isConstructed() const { return Ptr != 0; }
+ bool isConstructed() const { return Ptr != nullptr; }
void destroy() const;
};
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 8251fcd..0996adb 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -28,7 +28,7 @@ namespace sys {
/// @brief Memory block abstraction.
class MemoryBlock {
public:
- MemoryBlock() : Address(0), Size(0) { }
+ MemoryBlock() : Address(nullptr), Size(0) { }
MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { }
void *base() const { return Address; }
size_t size() const { return Size; }
@@ -120,7 +120,7 @@ namespace sys {
/// @brief Allocate Read/Write/Execute memory.
static MemoryBlock AllocateRWX(size_t NumBytes,
const MemoryBlock *NearBlock,
- std::string *ErrMsg = 0);
+ std::string *ErrMsg = nullptr);
/// This method releases a block of Read/Write/Execute memory that was
/// allocated with the AllocateRWX method. It should not be used to
@@ -129,7 +129,7 @@ namespace sys {
/// On success, this returns false, otherwise it returns true and fills
/// in *ErrMsg.
/// @brief Release Read/Write/Execute memory.
- static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = nullptr);
/// InvalidateInstructionCache - Before the JIT can run a block of code
@@ -140,12 +140,12 @@ namespace sys {
/// setExecutable - Before the JIT can run a block of code, it has to be
/// given read and executable privilege. Return true if it is already r-x
/// or the system is able to change its previlege.
- static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = 0);
+ static bool setExecutable(MemoryBlock &M, std::string *ErrMsg = nullptr);
/// setWritable - When adding to a block of code, the JIT may need
/// to mark a block of code as RW since the protections are on page
/// boundaries, and the JIT internal allocations are not page aligned.
- static bool setWritable(MemoryBlock &M, std::string *ErrMsg = 0);
+ static bool setWritable(MemoryBlock &M, std::string *ErrMsg = nullptr);
/// setRangeExecutable - Mark the page containing a range of addresses
/// as executable.
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index 578c7e8..5810c47 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -24,7 +24,6 @@
namespace llvm {
class error_code;
-template<class T> class OwningPtr;
/// MemoryBuffer - This interface provides simple read-only access to a block
/// of memory, and provides simple methods for reading files and standard input
@@ -67,34 +66,39 @@ public:
/// MemoryBuffer if successful, otherwise returning null. If FileSize is
/// specified, this means that the client knows that the file exists and that
/// it has the specified size.
- static error_code getFile(Twine Filename, OwningPtr<MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true);
+ ///
+ /// \param IsVolatileSize Set to true to indicate that the file size may be
+ /// changing, e.g. when libclang tries to parse while the user is
+ /// editing/updating the file.
static error_code getFile(Twine Filename,
std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1,
- bool RequiresNullTerminator = true);
+ bool RequiresNullTerminator = true,
+ bool IsVolatileSize = false);
/// Given an already-open file descriptor, map some slice of it into a
/// MemoryBuffer. The slice is specified by an \p Offset and \p MapSize.
/// Since this is in the middle of a file, the buffer is not null terminated.
- static error_code getOpenFileSlice(int FD, const char *Filename,
- OwningPtr<MemoryBuffer> &Result,
- uint64_t MapSize, int64_t Offset);
+ ///
+ /// \param IsVolatileSize Set to true to indicate that the file size may be
+ /// changing, e.g. when libclang tries to parse while the user is
+ /// editing/updating the file.
static error_code getOpenFileSlice(int FD, const char *Filename,
std::unique_ptr<MemoryBuffer> &Result,
- uint64_t MapSize, int64_t Offset);
+ uint64_t MapSize, int64_t Offset,
+ bool IsVolatileSize = false);
/// Given an already-open file descriptor, read the file and return a
/// MemoryBuffer.
- static error_code getOpenFile(int FD, const char *Filename,
- OwningPtr<MemoryBuffer> &Result,
- uint64_t FileSize,
- bool RequiresNullTerminator = true);
+ ///
+ /// \param IsVolatileSize Set to true to indicate that the file size may be
+ /// changing, e.g. when libclang tries to parse while the user is
+ /// editing/updating the file.
static error_code getOpenFile(int FD, const char *Filename,
std::unique_ptr<MemoryBuffer> &Result,
uint64_t FileSize,
- bool RequiresNullTerminator = true);
+ bool RequiresNullTerminator = true,
+ bool IsVolatileSize = false);
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that InputData must be null terminated if RequiresNullTerminator is true.
@@ -123,7 +127,6 @@ public:
/// getSTDIN - Read all of stdin into a file buffer, and return it.
/// If an error occurs, this returns null and sets ec.
- static error_code getSTDIN(OwningPtr<MemoryBuffer> &Result);
static error_code getSTDIN(std::unique_ptr<MemoryBuffer> &Result);
@@ -131,9 +134,6 @@ public:
/// if the Filename is "-". If an error occurs, this returns null and sets
/// ec.
static error_code getFileOrSTDIN(StringRef Filename,
- OwningPtr<MemoryBuffer> &Result,
- int64_t FileSize = -1);
- static error_code getFileOrSTDIN(StringRef Filename,
std::unique_ptr<MemoryBuffer> &Result,
int64_t FileSize = -1);
diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h
new file mode 100644
index 0000000..f6d43a4
--- /dev/null
+++ b/include/llvm/Support/OnDiskHashTable.h
@@ -0,0 +1,571 @@
+//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines facilities for reading and writing on-disk hash tables.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
+#define LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
+
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdlib>
+
+namespace llvm {
+
+/// \brief Generates an on disk hash table.
+///
+/// This needs an \c Info that handles storing values into the hash table's
+/// payload and computes the hash for a given key. This should provide the
+/// following interface:
+///
+/// \code
+/// class ExampleInfo {
+/// public:
+/// typedef ExampleKey key_type; // Must be copy constructible
+/// typedef ExampleKey &key_type_ref;
+/// typedef ExampleData data_type; // Must be copy constructible
+/// typedef ExampleData &data_type_ref;
+/// typedef uint32_t hash_value_type; // The type the hash function returns.
+/// typedef uint32_t offset_type; // The type for offsets into the table.
+///
+/// /// Calculate the hash for Key
+/// static hash_value_type ComputeHash(key_type_ref Key);
+/// /// Return the lengths, in bytes, of the given Key/Data pair.
+/// static std::pair<offset_type, offset_type>
+/// EmitKeyDataLength(raw_ostream &Out, key_type_ref Key, data_type_ref Data);
+/// /// Write Key to Out. KeyLen is the length from EmitKeyDataLength.
+/// static void EmitKey(raw_ostream &Out, key_type_ref Key,
+/// offset_type KeyLen);
+/// /// Write Data to Out. DataLen is the length from EmitKeyDataLength.
+/// static void EmitData(raw_ostream &Out, key_type_ref Key,
+/// data_type_ref Data, offset_type DataLen);
+/// };
+/// \endcode
+template <typename Info> class OnDiskChainedHashTableGenerator {
+ /// \brief A single item in the hash table.
+ class Item {
+ public:
+ typename Info::key_type Key;
+ typename Info::data_type Data;
+ Item *Next;
+ const typename Info::hash_value_type Hash;
+
+ Item(typename Info::key_type_ref Key, typename Info::data_type_ref Data,
+ Info &InfoObj)
+ : Key(Key), Data(Data), Next(nullptr), Hash(InfoObj.ComputeHash(Key)) {}
+ };
+
+ typedef typename Info::offset_type offset_type;
+ offset_type NumBuckets;
+ offset_type NumEntries;
+ llvm::SpecificBumpPtrAllocator<Item> BA;
+
+ /// \brief A linked list of values in a particular hash bucket.
+ class Bucket {
+ public:
+ offset_type Off;
+ Item *Head;
+ unsigned Length;
+
+ Bucket() {}
+ };
+
+ Bucket *Buckets;
+
+private:
+ /// \brief Insert an item into the appropriate hash bucket.
+ void insert(Bucket *Buckets, size_t Size, Item *E) {
+ Bucket &B = Buckets[E->Hash & (Size - 1)];
+ E->Next = B.Head;
+ ++B.Length;
+ B.Head = E;
+ }
+
+ /// \brief Resize the hash table, moving the old entries into the new buckets.
+ void resize(size_t NewSize) {
+ Bucket *NewBuckets = (Bucket *)std::calloc(NewSize, sizeof(Bucket));
+ // Populate NewBuckets with the old entries.
+ for (size_t I = 0; I < NumBuckets; ++I)
+ for (Item *E = Buckets[I].Head; E;) {
+ Item *N = E->Next;
+ E->Next = nullptr;
+ insert(NewBuckets, NewSize, E);
+ E = N;
+ }
+
+ free(Buckets);
+ NumBuckets = NewSize;
+ Buckets = NewBuckets;
+ }
+
+public:
+ /// \brief Insert an entry into the table.
+ void insert(typename Info::key_type_ref Key,
+ typename Info::data_type_ref Data) {
+ Info InfoObj;
+ insert(Key, Data, InfoObj);
+ }
+
+ /// \brief Insert an entry into the table.
+ ///
+ /// Uses the provided Info instead of a stack allocated one.
+ void insert(typename Info::key_type_ref Key,
+ typename Info::data_type_ref Data, Info &InfoObj) {
+
+ ++NumEntries;
+ if (4 * NumEntries >= 3 * NumBuckets)
+ resize(NumBuckets * 2);
+ insert(Buckets, NumBuckets, new (BA.Allocate()) Item(Key, Data, InfoObj));
+ }
+
+ /// \brief Emit the table to Out, which must not be at offset 0.
+ offset_type Emit(raw_ostream &Out) {
+ Info InfoObj;
+ return Emit(Out, InfoObj);
+ }
+
+ /// \brief Emit the table to Out, which must not be at offset 0.
+ ///
+ /// Uses the provided Info instead of a stack allocated one.
+ offset_type Emit(raw_ostream &Out, Info &InfoObj) {
+ using namespace llvm::support;
+ endian::Writer<little> LE(Out);
+
+ // Emit the payload of the table.
+ for (offset_type I = 0; I < NumBuckets; ++I) {
+ Bucket &B = Buckets[I];
+ if (!B.Head)
+ continue;
+
+ // Store the offset for the data of this bucket.
+ B.Off = Out.tell();
+ assert(B.Off && "Cannot write a bucket at offset 0. Please add padding.");
+
+ // Write out the number of items in the bucket.
+ LE.write<uint16_t>(B.Length);
+ assert(B.Length != 0 && "Bucket has a head but zero length?");
+
+ // Write out the entries in the bucket.
+ for (Item *I = B.Head; I; I = I->Next) {
+ LE.write<typename Info::hash_value_type>(I->Hash);
+ const std::pair<offset_type, offset_type> &Len =
+ InfoObj.EmitKeyDataLength(Out, I->Key, I->Data);
+ InfoObj.EmitKey(Out, I->Key, Len.first);
+ InfoObj.EmitData(Out, I->Key, I->Data, Len.second);
+ }
+ }
+
+ // Pad with zeros so that we can start the hashtable at an aligned address.
+ offset_type TableOff = Out.tell();
+ uint64_t N = llvm::OffsetToAlignment(TableOff, alignOf<offset_type>());
+ TableOff += N;
+ while (N--)
+ LE.write<uint8_t>(0);
+
+ // Emit the hashtable itself.
+ LE.write<offset_type>(NumBuckets);
+ LE.write<offset_type>(NumEntries);
+ for (offset_type I = 0; I < NumBuckets; ++I)
+ LE.write<offset_type>(Buckets[I].Off);
+
+ return TableOff;
+ }
+
+ OnDiskChainedHashTableGenerator() {
+ NumEntries = 0;
+ NumBuckets = 64;
+ // Note that we do not need to run the constructors of the individual
+ // Bucket objects since 'calloc' returns bytes that are all 0.
+ Buckets = (Bucket *)std::calloc(NumBuckets, sizeof(Bucket));
+ }
+
+ ~OnDiskChainedHashTableGenerator() { std::free(Buckets); }
+};
+
+/// \brief Provides lookup on an on disk hash table.
+///
+/// This needs an \c Info that handles reading values from the hash table's
+/// payload and computes the hash for a given key. This should provide the
+/// following interface:
+///
+/// \code
+/// class ExampleLookupInfo {
+/// public:
+/// typedef ExampleData data_type;
+/// typedef ExampleInternalKey internal_key_type; // The stored key type.
+/// typedef ExampleKey external_key_type; // The type to pass to find().
+/// typedef uint32_t hash_value_type; // The type the hash function returns.
+/// typedef uint32_t offset_type; // The type for offsets into the table.
+///
+/// /// Compare two keys for equality.
+/// static bool EqualKey(internal_key_type &Key1, internal_key_type &Key2);
+/// /// Calculate the hash for the given key.
+/// static hash_value_type ComputeHash(internal_key_type &IKey);
+/// /// Translate from the semantic type of a key in the hash table to the
+/// /// type that is actually stored and used for hashing and comparisons.
+/// /// The internal and external types are often the same, in which case this
+/// /// can simply return the passed in value.
+/// static const internal_key_type &GetInternalKey(external_key_type &EKey);
+/// /// Read the key and data length from Buffer, leaving it pointing at the
+/// /// following byte.
+/// static std::pair<offset_type, offset_type>
+/// ReadKeyDataLength(const unsigned char *&Buffer);
+/// /// Read the key from Buffer, given the KeyLen as reported from
+/// /// ReadKeyDataLength.
+/// const internal_key_type &ReadKey(const unsigned char *Buffer,
+/// offset_type KeyLen);
+/// /// Read the data for Key from Buffer, given the DataLen as reported from
+/// /// ReadKeyDataLength.
+/// data_type ReadData(StringRef Key, const unsigned char *Buffer,
+/// offset_type DataLen);
+/// };
+/// \endcode
+template <typename Info> class OnDiskChainedHashTable {
+ const typename Info::offset_type NumBuckets;
+ const typename Info::offset_type NumEntries;
+ const unsigned char *const Buckets;
+ const unsigned char *const Base;
+ Info InfoObj;
+
+public:
+ typedef typename Info::internal_key_type internal_key_type;
+ typedef typename Info::external_key_type external_key_type;
+ typedef typename Info::data_type data_type;
+ typedef typename Info::hash_value_type hash_value_type;
+ typedef typename Info::offset_type offset_type;
+
+ OnDiskChainedHashTable(offset_type NumBuckets, offset_type NumEntries,
+ const unsigned char *Buckets,
+ const unsigned char *Base,
+ const Info &InfoObj = Info())
+ : NumBuckets(NumBuckets), NumEntries(NumEntries), Buckets(Buckets),
+ Base(Base), InfoObj(InfoObj) {
+ assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+ "'buckets' must have a 4-byte alignment");
+ }
+
+ offset_type getNumBuckets() const { return NumBuckets; }
+ offset_type getNumEntries() const { return NumEntries; }
+ const unsigned char *getBase() const { return Base; }
+ const unsigned char *getBuckets() const { return Buckets; }
+
+ bool isEmpty() const { return NumEntries == 0; }
+
+ class iterator {
+ internal_key_type Key;
+ const unsigned char *const Data;
+ const offset_type Len;
+ Info *InfoObj;
+
+ public:
+ iterator() : Data(nullptr), Len(0) {}
+ iterator(const internal_key_type K, const unsigned char *D, offset_type L,
+ Info *InfoObj)
+ : Key(K), Data(D), Len(L), InfoObj(InfoObj) {}
+
+ data_type operator*() const { return InfoObj->ReadData(Key, Data, Len); }
+ bool operator==(const iterator &X) const { return X.Data == Data; }
+ bool operator!=(const iterator &X) const { return X.Data != Data; }
+ };
+
+ /// \brief Look up the stored data for a particular key.
+ iterator find(const external_key_type &EKey, Info *InfoPtr = 0) {
+ if (!InfoPtr)
+ InfoPtr = &InfoObj;
+
+ using namespace llvm::support;
+ const internal_key_type &IKey = InfoObj.GetInternalKey(EKey);
+ hash_value_type KeyHash = InfoObj.ComputeHash(IKey);
+
+ // Each bucket is just an offset into the hash table file.
+ offset_type Idx = KeyHash & (NumBuckets - 1);
+ const unsigned char *Bucket = Buckets + sizeof(offset_type) * Idx;
+
+ offset_type Offset = endian::readNext<offset_type, little, aligned>(Bucket);
+ if (Offset == 0)
+ return iterator(); // Empty bucket.
+ const unsigned char *Items = Base + Offset;
+
+ // 'Items' starts with a 16-bit unsigned integer representing the
+ // number of items in this bucket.
+ unsigned Len = endian::readNext<uint16_t, little, unaligned>(Items);
+
+ for (unsigned i = 0; i < Len; ++i) {
+ // Read the hash.
+ hash_value_type ItemHash =
+ endian::readNext<hash_value_type, little, unaligned>(Items);
+
+ // Determine the length of the key and the data.
+ const std::pair<offset_type, offset_type> &L =
+ Info::ReadKeyDataLength(Items);
+ offset_type ItemLen = L.first + L.second;
+
+ // Compare the hashes. If they are not the same, skip the entry entirely.
+ if (ItemHash != KeyHash) {
+ Items += ItemLen;
+ continue;
+ }
+
+ // Read the key.
+ const internal_key_type &X =
+ InfoPtr->ReadKey((const unsigned char *const)Items, L.first);
+
+ // If the key doesn't match just skip reading the value.
+ if (!InfoPtr->EqualKey(X, IKey)) {
+ Items += ItemLen;
+ continue;
+ }
+
+ // The key matches!
+ return iterator(X, Items + L.first, L.second, InfoPtr);
+ }
+
+ return iterator();
+ }
+
+ iterator end() const { return iterator(); }
+
+ Info &getInfoObj() { return InfoObj; }
+
+ /// \brief Create the hash table.
+ ///
+ /// \param Buckets is the beginning of the hash table itself, which follows
+ /// the payload of entire structure. This is the value returned by
+ /// OnDiskHashTableGenerator::Emit.
+ ///
+ /// \param Base is the point from which all offsets into the structure are
+ /// based. This is offset 0 in the stream that was used when Emitting the
+ /// table.
+ static OnDiskChainedHashTable *Create(const unsigned char *Buckets,
+ const unsigned char *const Base,
+ const Info &InfoObj = Info()) {
+ using namespace llvm::support;
+ assert(Buckets > Base);
+ assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+ "buckets should be 4-byte aligned.");
+
+ offset_type NumBuckets =
+ endian::readNext<offset_type, little, aligned>(Buckets);
+ offset_type NumEntries =
+ endian::readNext<offset_type, little, aligned>(Buckets);
+ return new OnDiskChainedHashTable<Info>(NumBuckets, NumEntries, Buckets,
+ Base, InfoObj);
+ }
+};
+
+/// \brief Provides lookup and iteration over an on disk hash table.
+///
+/// \copydetails llvm::OnDiskChainedHashTable
+template <typename Info>
+class OnDiskIterableChainedHashTable : public OnDiskChainedHashTable<Info> {
+ const unsigned char *Payload;
+
+public:
+ typedef OnDiskChainedHashTable<Info> base_type;
+ typedef typename base_type::internal_key_type internal_key_type;
+ typedef typename base_type::external_key_type external_key_type;
+ typedef typename base_type::data_type data_type;
+ typedef typename base_type::hash_value_type hash_value_type;
+ typedef typename base_type::offset_type offset_type;
+
+ OnDiskIterableChainedHashTable(offset_type NumBuckets, offset_type NumEntries,
+ const unsigned char *Buckets,
+ const unsigned char *Payload,
+ const unsigned char *Base,
+ const Info &InfoObj = Info())
+ : base_type(NumBuckets, NumEntries, Buckets, Base, InfoObj),
+ Payload(Payload) {}
+
+ /// \brief Iterates over all of the keys in the table.
+ class key_iterator {
+ const unsigned char *Ptr;
+ offset_type NumItemsInBucketLeft;
+ offset_type NumEntriesLeft;
+ Info *InfoObj;
+
+ public:
+ typedef external_key_type value_type;
+
+ key_iterator(const unsigned char *const Ptr, offset_type NumEntries,
+ Info *InfoObj)
+ : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
+ InfoObj(InfoObj) {}
+ key_iterator()
+ : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0),
+ InfoObj(0) {}
+
+ friend bool operator==(const key_iterator &X, const key_iterator &Y) {
+ return X.NumEntriesLeft == Y.NumEntriesLeft;
+ }
+ friend bool operator!=(const key_iterator &X, const key_iterator &Y) {
+ return X.NumEntriesLeft != Y.NumEntriesLeft;
+ }
+
+ key_iterator &operator++() { // Preincrement
+ using namespace llvm::support;
+ if (!NumItemsInBucketLeft) {
+ // 'Items' starts with a 16-bit unsigned integer representing the
+ // number of items in this bucket.
+ NumItemsInBucketLeft =
+ endian::readNext<uint16_t, little, unaligned>(Ptr);
+ }
+ Ptr += sizeof(hash_value_type); // Skip the hash.
+ // Determine the length of the key and the data.
+ const std::pair<offset_type, offset_type> &L =
+ Info::ReadKeyDataLength(Ptr);
+ Ptr += L.first + L.second;
+ assert(NumItemsInBucketLeft);
+ --NumItemsInBucketLeft;
+ assert(NumEntriesLeft);
+ --NumEntriesLeft;
+ return *this;
+ }
+ key_iterator operator++(int) { // Postincrement
+ key_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ value_type operator*() const {
+ const unsigned char *LocalPtr = Ptr;
+ if (!NumItemsInBucketLeft)
+ LocalPtr += 2; // number of items in bucket
+ LocalPtr += sizeof(hash_value_type); // Skip the hash.
+
+ // Determine the length of the key and the data.
+ const std::pair<offset_type, offset_type> &L =
+ Info::ReadKeyDataLength(LocalPtr);
+
+ // Read the key.
+ const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first);
+ return InfoObj->GetExternalKey(Key);
+ }
+ };
+
+ key_iterator key_begin() {
+ return key_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
+ }
+ key_iterator key_end() { return key_iterator(); }
+
+ iterator_range<key_iterator> keys() {
+ return make_range(key_begin(), key_end());
+ }
+
+ /// \brief Iterates over all the entries in the table, returning the data.
+ class data_iterator {
+ const unsigned char *Ptr;
+ offset_type NumItemsInBucketLeft;
+ offset_type NumEntriesLeft;
+ Info *InfoObj;
+
+ public:
+ typedef data_type value_type;
+
+ data_iterator(const unsigned char *const Ptr, offset_type NumEntries,
+ Info *InfoObj)
+ : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
+ InfoObj(InfoObj) {}
+ data_iterator()
+ : Ptr(nullptr), NumItemsInBucketLeft(0), NumEntriesLeft(0),
+ InfoObj(nullptr) {}
+
+ bool operator==(const data_iterator &X) const {
+ return X.NumEntriesLeft == NumEntriesLeft;
+ }
+ bool operator!=(const data_iterator &X) const {
+ return X.NumEntriesLeft != NumEntriesLeft;
+ }
+
+ data_iterator &operator++() { // Preincrement
+ using namespace llvm::support;
+ if (!NumItemsInBucketLeft) {
+ // 'Items' starts with a 16-bit unsigned integer representing the
+ // number of items in this bucket.
+ NumItemsInBucketLeft =
+ endian::readNext<uint16_t, little, unaligned>(Ptr);
+ }
+ Ptr += sizeof(hash_value_type); // Skip the hash.
+ // Determine the length of the key and the data.
+ const std::pair<offset_type, offset_type> &L =
+ Info::ReadKeyDataLength(Ptr);
+ Ptr += L.first + L.second;
+ assert(NumItemsInBucketLeft);
+ --NumItemsInBucketLeft;
+ assert(NumEntriesLeft);
+ --NumEntriesLeft;
+ return *this;
+ }
+ data_iterator operator++(int) { // Postincrement
+ data_iterator tmp = *this; ++*this; return tmp;
+ }
+
+ value_type operator*() const {
+ const unsigned char *LocalPtr = Ptr;
+ if (!NumItemsInBucketLeft)
+ LocalPtr += 2; // number of items in bucket
+ LocalPtr += sizeof(hash_value_type); // Skip the hash.
+
+ // Determine the length of the key and the data.
+ const std::pair<offset_type, offset_type> &L =
+ Info::ReadKeyDataLength(LocalPtr);
+
+ // Read the key.
+ const internal_key_type &Key = InfoObj->ReadKey(LocalPtr, L.first);
+ return InfoObj->ReadData(Key, LocalPtr + L.first, L.second);
+ }
+ };
+
+ data_iterator data_begin() {
+ return data_iterator(Payload, this->getNumEntries(), &this->getInfoObj());
+ }
+ data_iterator data_end() { return data_iterator(); }
+
+ iterator_range<data_iterator> data() {
+ return make_range(data_begin(), data_end());
+ }
+
+ /// \brief Create the hash table.
+ ///
+ /// \param Buckets is the beginning of the hash table itself, which follows
+ /// the payload of entire structure. This is the value returned by
+ /// OnDiskHashTableGenerator::Emit.
+ ///
+ /// \param Payload is the beginning of the data contained in the table. This
+ /// is Base plus any padding or header data that was stored, ie, the offset
+ /// that the stream was at when calling Emit.
+ ///
+ /// \param Base is the point from which all offsets into the structure are
+ /// based. This is offset 0 in the stream that was used when Emitting the
+ /// table.
+ static OnDiskIterableChainedHashTable *
+ Create(const unsigned char *Buckets, const unsigned char *const Payload,
+ const unsigned char *const Base, const Info &InfoObj = Info()) {
+ using namespace llvm::support;
+ assert(Buckets > Base);
+ assert((reinterpret_cast<uintptr_t>(Buckets) & 0x3) == 0 &&
+ "buckets should be 4-byte aligned.");
+
+ offset_type NumBuckets =
+ endian::readNext<offset_type, little, aligned>(Buckets);
+ offset_type NumEntries =
+ endian::readNext<offset_type, little, aligned>(Buckets);
+ return new OnDiskIterableChainedHashTable<Info>(
+ NumBuckets, NumEntries, Buckets, Payload, Base, InfoObj);
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_ON_DISK_HASH_TABLE_H
diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h
index ba18529..cf821f0 100644
--- a/include/llvm/Support/Path.h
+++ b/include/llvm/Support/Path.h
@@ -295,6 +295,11 @@ const StringRef extension(StringRef path);
/// @result true if \a value is a path separator character on the host OS
bool is_separator(char value);
+/// @brief Return the preferred separator for this platform.
+///
+/// @result StringRef of the preferred separator, null-terminated.
+const StringRef get_separator();
+
/// @brief Get the typical temporary directory for the system, e.g.,
/// "/var/tmp" or "C:/TEMP"
///
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index a1067a6..9160b7d 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -87,11 +87,11 @@ struct ProcessInfo {
const char **args, ///< A vector of strings that are passed to the
///< program. The first element should be the name of the program.
///< The list *must* be terminated by a null char* entry.
- const char **env = 0, ///< An optional vector of strings to use for
+ const char **env = nullptr, ///< An optional vector of strings to use for
///< the program's environment. If not provided, the current program's
///< environment will be used.
- const StringRef **redirects = 0, ///< An optional array of pointers to
- ///< paths. If the array is null, no redirection is done. The array
+ const StringRef **redirects = nullptr, ///< An optional array of pointers
+ ///< to paths. If the array is null, no redirection is done. The array
///< should have a size of at least three. The inferior process's
///< stdin(0), stdout(1), and stderr(2) will be redirected to the
///< corresponding paths.
@@ -107,11 +107,11 @@ struct ProcessInfo {
///< of memory can be allocated by process. If memory usage will be
///< higher limit, the child is killed and this call returns. If zero
///< - no memory limit.
- std::string *ErrMsg = 0, ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while invoking the
+ std::string *ErrMsg = nullptr, ///< If non-zero, provides a pointer to a
+ ///< string instance in which error messages will be returned. If the
+ ///< string is non-empty upon return an error occurred while invoking the
///< program.
- bool *ExecutionFailed = 0);
+ bool *ExecutionFailed = nullptr);
/// Similar to ExecuteAndWait, but returns immediately.
/// @returns The \see ProcessInfo of the newly launced process.
@@ -119,9 +119,9 @@ struct ProcessInfo {
/// Wait until the process finished execution or win32 CloseHandle() API on
/// ProcessInfo.ProcessHandle to avoid memory leaks.
ProcessInfo
- ExecuteNoWait(StringRef Program, const char **args, const char **env = 0,
- const StringRef **redirects = 0, unsigned memoryLimit = 0,
- std::string *ErrMsg = 0, bool *ExecutionFailed = 0);
+ ExecuteNoWait(StringRef Program, const char **args, const char **env = nullptr,
+ const StringRef **redirects = nullptr, unsigned memoryLimit = 0,
+ std::string *ErrMsg = nullptr, bool *ExecutionFailed = nullptr);
/// Return true if the given arguments fit within system-specific
/// argument length limits.
@@ -142,9 +142,9 @@ struct ProcessInfo {
///< will perform a non-blocking wait on the child process.
bool WaitUntilTerminates, ///< If true, ignores \p SecondsToWait and waits
///< until child has terminated.
- std::string *ErrMsg = 0 ///< If non-zero, provides a pointer to a string
- ///< instance in which error messages will be returned. If the string
- ///< is non-empty upon return an error occurred while invoking the
+ std::string *ErrMsg = nullptr ///< If non-zero, provides a pointer to a
+ ///< string instance in which error messages will be returned. If the
+ ///< string is non-empty upon return an error occurred while invoking the
///< program.
);
}
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 2eea369..bf533ca 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -55,7 +55,7 @@ namespace llvm {
Regex(Regex &&regex) {
preg = regex.preg;
error = regex.error;
- regex.preg = NULL;
+ regex.preg = nullptr;
}
~Regex();
@@ -75,7 +75,7 @@ namespace llvm {
/// the first group is always the entire pattern.
///
/// This returns true on a successful match.
- bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = 0);
+ bool match(StringRef String, SmallVectorImpl<StringRef> *Matches = nullptr);
/// sub - Return the result of replacing the first match of the regex in
/// \p String with the \p Repl string. Backreferences like "\0" in the
@@ -87,7 +87,8 @@ namespace llvm {
/// \param Error If non-null, any errors in the substitution (invalid
/// backreferences, trailing backslashes) will be recorded as a non-empty
/// string.
- std::string sub(StringRef Repl, StringRef String, std::string *Error = 0);
+ std::string sub(StringRef Repl, StringRef String,
+ std::string *Error = nullptr);
/// \brief If this function returns true, ^Str$ is an extended regular
/// expression that matches Str and only Str.
diff --git a/include/llvm/Support/Registry.h b/include/llvm/Support/Registry.h
index 073becd..b0c2e89 100644
--- a/include/llvm/Support/Registry.h
+++ b/include/llvm/Support/Registry.h
@@ -14,24 +14,27 @@
#ifndef LLVM_SUPPORT_REGISTRY_H
#define LLVM_SUPPORT_REGISTRY_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
+#include <memory>
+
namespace llvm {
/// A simple registry entry which provides only a name, description, and
/// no-argument constructor.
template <typename T>
class SimpleRegistryEntry {
const char *Name, *Desc;
- T *(*Ctor)();
+ std::unique_ptr<T> (*Ctor)();
public:
- SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
+ SimpleRegistryEntry(const char *N, const char *D, std::unique_ptr<T> (*C)())
: Name(N), Desc(D), Ctor(C)
{}
const char *getName() const { return Name; }
const char *getDesc() const { return Desc; }
- T *instantiate() const { return Ctor(); }
+ std::unique_ptr<T> instantiate() const { return Ctor(); }
};
@@ -88,7 +91,7 @@ namespace llvm {
const entry& Val;
public:
- node(const entry& V) : Next(0), Val(V) {
+ node(const entry& V) : Next(nullptr), Val(V) {
if (Tail)
Tail->Next = this;
else
@@ -116,7 +119,7 @@ namespace llvm {
};
static iterator begin() { return iterator(Head); }
- static iterator end() { return iterator(0); }
+ static iterator end() { return iterator(nullptr); }
/// Abstract base class for registry listeners, which are informed when new
@@ -195,7 +198,7 @@ namespace llvm {
entry Entry;
node Node;
- static T *CtorFn() { return new V(); }
+ static std::unique_ptr<T> CtorFn() { return make_unique<V>(); }
public:
Add(const char *Name, const char *Desc)
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index 0906471..d5b4c57 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -23,9 +23,9 @@ namespace llvm {
class SMLoc {
const char *Ptr;
public:
- SMLoc() : Ptr(0) {}
+ SMLoc() : Ptr(nullptr) {}
- bool isValid() const { return Ptr != 0; }
+ bool isValid() const { return Ptr != nullptr; }
bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; }
bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; }
diff --git a/include/llvm/Support/SaveAndRestore.h b/include/llvm/Support/SaveAndRestore.h
index 6330bec..ef154ac 100644
--- a/include/llvm/Support/SaveAndRestore.h
+++ b/include/llvm/Support/SaveAndRestore.h
@@ -6,10 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file provides utility classes that uses RAII to save and restore
-// values.
-//
+///
+/// \file
+/// This file provides utility classes that use RAII to save and restore
+/// values.
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H
@@ -17,31 +18,32 @@
namespace llvm {
-// SaveAndRestore - A utility class that uses RAII to save and restore
-// the value of a variable.
-template<typename T>
-struct SaveAndRestore {
- SaveAndRestore(T& x) : X(x), old_value(x) {}
- SaveAndRestore(T& x, const T &new_value) : X(x), old_value(x) {
- X = new_value;
+/// A utility class that uses RAII to save and restore the value of a variable.
+template <typename T> struct SaveAndRestore {
+ SaveAndRestore(T &X) : X(X), OldValue(X) {}
+ SaveAndRestore(T &X, const T &NewValue) : X(X), OldValue(X) {
+ X = NewValue;
}
- ~SaveAndRestore() { X = old_value; }
- T get() { return old_value; }
+ ~SaveAndRestore() { X = OldValue; }
+ T get() { return OldValue; }
+
private:
- T& X;
- T old_value;
+ T &X;
+ T OldValue;
};
-// SaveOr - Similar to SaveAndRestore. Operates only on bools; the old
-// value of a variable is saved, and during the dstor the old value is
-// or'ed with the new value.
+/// Similar to \c SaveAndRestore. Operates only on bools; the old value of a
+/// variable is saved, and during the dstor the old value is or'ed with the new
+/// value.
struct SaveOr {
- SaveOr(bool& x) : X(x), old_value(x) { x = false; }
- ~SaveOr() { X |= old_value; }
+ SaveOr(bool &X) : X(X), OldValue(X) { X = false; }
+ ~SaveOr() { X |= OldValue; }
+
private:
- bool& X;
- const bool old_value;
+ bool &X;
+ const bool OldValue;
};
-}
+} // namespace llvm
+
#endif
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 58ed175..6cbc1f6 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -28,7 +28,7 @@ namespace sys {
/// This function registers signal handlers to ensure that if a signal gets
/// delivered that the named file is removed.
/// @brief Remove a file if a fatal signal occurs.
- bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg = 0);
+ bool RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg = nullptr);
/// This function removes a file from the list of files to be removed on
/// signal delivery.
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index dd48974..39f896d 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -71,7 +71,8 @@ private:
SourceMgr(const SourceMgr&) LLVM_DELETED_FUNCTION;
void operator=(const SourceMgr&) LLVM_DELETED_FUNCTION;
public:
- SourceMgr() : LineNoCache(0), DiagHandler(0), DiagContext(0) {}
+ SourceMgr()
+ : LineNoCache(nullptr), DiagHandler(nullptr), DiagContext(nullptr) {}
~SourceMgr();
void setIncludeDirs(const std::vector<std::string> &Dirs) {
@@ -80,7 +81,7 @@ public:
/// setDiagHandler - Specify a diagnostic handler to be invoked every time
/// PrintMessage is called. Ctx is passed into the handler when it is invoked.
- void setDiagHandler(DiagHandlerTy DH, void *Ctx = 0) {
+ void setDiagHandler(DiagHandlerTy DH, void *Ctx = nullptr) {
DiagHandler = DH;
DiagContext = Ctx;
}
@@ -222,10 +223,10 @@ class SMDiagnostic {
public:
// Null diagnostic.
SMDiagnostic()
- : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
+ : SM(nullptr), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
- : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
+ : SM(nullptr), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
// Diagnostic with a location.
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 0259630..9c9e55c 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -116,7 +116,7 @@ public:
// the memory doesn't go away/get reallocated, but it's
// not currently necessary. Users that need the pointer don't stream.
assert(0 && "getPointer in streaming memory objects not allowed");
- return NULL;
+ return nullptr;
}
bool isValidAddress(uint64_t address) const override;
bool isObjectEnd(uint64_t address) const override;
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index 71adbc5..7e1394c 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -48,7 +48,7 @@ namespace llvm {
unsigned Refcount; ///< Number of referencing PooledStringPtrs.
public:
- PooledString() : Pool(0), Refcount(0) { }
+ PooledString() : Pool(nullptr), Refcount(0) { }
};
friend class PooledStringPtr;
@@ -81,7 +81,7 @@ namespace llvm {
entry_t *S;
public:
- PooledStringPtr() : S(0) {}
+ PooledStringPtr() : S(nullptr) {}
explicit PooledStringPtr(entry_t *E) : S(E) {
if (S) ++S->getValue().Refcount;
@@ -107,7 +107,7 @@ namespace llvm {
S->getValue().Pool->InternTable.remove(S);
S->Destroy();
}
- S = 0;
+ S = nullptr;
}
~PooledStringPtr() { clear(); }
@@ -128,7 +128,7 @@ namespace llvm {
}
inline const char *operator*() const { return begin(); }
- inline operator bool() const { return S != 0; }
+ inline operator bool() const { return S != nullptr; }
inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 8e7478c..fcdc604 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -45,14 +45,14 @@ namespace llvm {
class MCSymbolizer;
class MCRelocationInfo;
class MCTargetAsmParser;
+ class MCTargetOptions;
class TargetMachine;
class TargetOptions;
class raw_ostream;
class formatted_raw_ostream;
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- bool isVerboseAsm, bool useCFI,
- bool useDwarfDirectory,
+ bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
@@ -104,11 +104,14 @@ namespace llvm {
const MCRegisterInfo &MRI,
StringRef TT,
StringRef CPU);
- typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
- MCAsmParser &P,
- const MCInstrInfo &MII);
+ typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
+ MCSubtargetInfo &STI,
+ MCAsmParser &P,
+ const MCInstrInfo &MII,
+ const MCTargetOptions &Options);
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
- const MCSubtargetInfo &STI);
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx);
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
@@ -131,7 +134,6 @@ namespace llvm {
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
@@ -233,8 +235,8 @@ namespace llvm {
public:
Target()
- : AsmStreamerCtorFn(0), MCRelocationInfoCtorFn(0),
- MCSymbolizerCtorFn(0) {}
+ : AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr),
+ MCSymbolizerCtorFn(nullptr) {}
/// @name Target Information
/// @{
@@ -256,10 +258,10 @@ namespace llvm {
bool hasJIT() const { return HasJIT; }
/// hasTargetMachine - Check if this target supports code generation.
- bool hasTargetMachine() const { return TargetMachineCtorFn != 0; }
+ bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
/// hasMCAsmBackend - Check if this target supports .o generation.
- bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; }
+ bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
/// @}
/// @name Feature Constructors
@@ -275,7 +277,7 @@ namespace llvm {
MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
StringRef Triple) const {
if (!MCAsmInfoCtorFn)
- return 0;
+ return nullptr;
return MCAsmInfoCtorFn(MRI, Triple);
}
@@ -285,7 +287,7 @@ namespace llvm {
CodeModel::Model CM,
CodeGenOpt::Level OL) const {
if (!MCCodeGenInfoCtorFn)
- return 0;
+ return nullptr;
return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
}
@@ -293,7 +295,7 @@ namespace llvm {
///
MCInstrInfo *createMCInstrInfo() const {
if (!MCInstrInfoCtorFn)
- return 0;
+ return nullptr;
return MCInstrInfoCtorFn();
}
@@ -301,7 +303,7 @@ namespace llvm {
///
MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
if (!MCInstrAnalysisCtorFn)
- return 0;
+ return nullptr;
return MCInstrAnalysisCtorFn(Info);
}
@@ -309,7 +311,7 @@ namespace llvm {
///
MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
if (!MCRegInfoCtorFn)
- return 0;
+ return nullptr;
return MCRegInfoCtorFn(Triple);
}
@@ -325,7 +327,7 @@ namespace llvm {
MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
StringRef Features) const {
if (!MCSubtargetInfoCtorFn)
- return 0;
+ return nullptr;
return MCSubtargetInfoCtorFn(Triple, CPU, Features);
}
@@ -342,7 +344,7 @@ namespace llvm {
CodeModel::Model CM = CodeModel::Default,
CodeGenOpt::Level OL = CodeGenOpt::Default) const {
if (!TargetMachineCtorFn)
- return 0;
+ return nullptr;
return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
RM, CM, OL);
}
@@ -353,7 +355,7 @@ namespace llvm {
MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
StringRef Triple, StringRef CPU) const {
if (!MCAsmBackendCtorFn)
- return 0;
+ return nullptr;
return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
}
@@ -361,26 +363,29 @@ namespace llvm {
///
/// \param Parser The target independent parser implementation to use for
/// parsing and lexing.
- MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI,
- MCAsmParser &Parser,
- const MCInstrInfo &MII) const {
+ MCTargetAsmParser *createMCAsmParser(
+ MCSubtargetInfo &STI,
+ MCAsmParser &Parser,
+ const MCInstrInfo &MII,
+ const MCTargetOptions &Options) const {
if (!MCAsmParserCtorFn)
- return 0;
- return MCAsmParserCtorFn(STI, Parser, MII);
+ return nullptr;
+ return MCAsmParserCtorFn(STI, Parser, MII, Options);
}
/// createAsmPrinter - Create a target specific assembly printer pass. This
/// takes ownership of the MCStreamer object.
AsmPrinter *createAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) const{
if (!AsmPrinterCtorFn)
- return 0;
+ return nullptr;
return AsmPrinterCtorFn(TM, Streamer);
}
- MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const {
+ MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
+ MCContext &Ctx) const {
if (!MCDisassemblerCtorFn)
- return 0;
- return MCDisassemblerCtorFn(*this, STI);
+ return nullptr;
+ return MCDisassemblerCtorFn(*this, STI, Ctx);
}
MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
@@ -389,7 +394,7 @@ namespace llvm {
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI) const {
if (!MCInstPrinterCtorFn)
- return 0;
+ return nullptr;
return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
}
@@ -400,7 +405,7 @@ namespace llvm {
const MCSubtargetInfo &STI,
MCContext &Ctx) const {
if (!MCCodeEmitterCtorFn)
- return 0;
+ return nullptr;
return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
}
@@ -421,7 +426,7 @@ namespace llvm {
bool RelaxAll,
bool NoExecStack) const {
if (!MCObjectStreamerCtorFn)
- return 0;
+ return nullptr;
return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
RelaxAll, NoExecStack);
}
@@ -430,19 +435,16 @@ namespace llvm {
MCStreamer *createAsmStreamer(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
- bool useCFI,
bool useDwarfDirectory,
MCInstPrinter *InstPrint,
MCCodeEmitter *CE,
MCAsmBackend *TAB,
bool ShowInst) const {
if (AsmStreamerCtorFn)
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useCFI,
- useDwarfDirectory, InstPrint, CE, TAB,
- ShowInst);
- return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useCFI,
- useDwarfDirectory, InstPrint, CE, TAB,
- ShowInst);
+ return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
+ InstPrint, CE, TAB, ShowInst);
+ return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
+ InstPrint, CE, TAB, ShowInst);
}
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
@@ -486,7 +488,7 @@ namespace llvm {
explicit iterator(Target *T) : Current(T) {}
friend struct TargetRegistry;
public:
- iterator() : Current(0) {}
+ iterator() : Current(nullptr) {}
bool operator==(const iterator &x) const {
return Current == x.Current;
@@ -1097,8 +1099,9 @@ namespace llvm {
private:
static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
- const MCInstrInfo &MII) {
- return new MCAsmParserImpl(STI, P, MII);
+ const MCInstrInfo &MII,
+ const MCTargetOptions &Options) {
+ return new MCAsmParserImpl(STI, P, MII, Options);
}
};
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index d009d7f..45c1828 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -85,24 +85,24 @@ class Timer {
Timer **Prev, *Next; // Doubly linked list of timers in the group.
public:
- explicit Timer(StringRef N) : TG(0) { init(N); }
- Timer(StringRef N, TimerGroup &tg) : TG(0) { init(N, tg); }
- Timer(const Timer &RHS) : TG(0) {
- assert(RHS.TG == 0 && "Can only copy uninitialized timers");
+ explicit Timer(StringRef N) : TG(nullptr) { init(N); }
+ Timer(StringRef N, TimerGroup &tg) : TG(nullptr) { init(N, tg); }
+ Timer(const Timer &RHS) : TG(nullptr) {
+ assert(!RHS.TG && "Can only copy uninitialized timers");
}
const Timer &operator=(const Timer &T) {
- assert(TG == 0 && T.TG == 0 && "Can only assign uninit timers");
+ assert(!TG && !T.TG && "Can only assign uninit timers");
return *this;
}
~Timer();
// Create an uninitialized timer, client must use 'init'.
- explicit Timer() : TG(0) {}
+ explicit Timer() : TG(nullptr) {}
void init(StringRef N);
void init(StringRef N, TimerGroup &tg);
const std::string &getName() const { return Name; }
- bool isInitialized() const { return TG != 0; }
+ bool isInitialized() const { return TG != nullptr; }
/// startTimer - Start the timer running. Time between calls to
/// startTimer/stopTimer is counted by the Timer class. Note that these calls
diff --git a/include/llvm/Support/Unicode.h b/include/llvm/Support/Unicode.h
index e6a52c4..f668a5b 100644
--- a/include/llvm/Support/Unicode.h
+++ b/include/llvm/Support/Unicode.h
@@ -12,6 +12,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_UNICODE_H
+#define LLVM_SUPPORT_UNICODE_H
+
#include "llvm/ADT/StringRef.h"
namespace llvm {
@@ -60,3 +63,5 @@ int columnWidthUTF8(StringRef Text);
} // namespace unicode
} // namespace sys
} // namespace llvm
+
+#endif
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 734d323..79137bf 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -21,6 +21,8 @@
namespace llvm {
namespace sys {
+#define DEBUG_TYPE "unicode"
+
/// \brief Represents a closed range of Unicode code points [Lower, Upper].
struct UnicodeCharRange {
uint32_t Lower;
@@ -88,6 +90,8 @@ private:
const CharRanges Ranges;
};
+#undef DEBUG_TYPE // "unicode"
+
} // namespace sys
} // namespace llvm
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 5194b52..c39874c 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -60,26 +60,26 @@ class Node;
class Scanner;
struct Token;
-/// @brief Dump all the tokens in this stream to OS.
-/// @returns true if there was an error, false otherwise.
+/// \brief Dump all the tokens in this stream to OS.
+/// \returns true if there was an error, false otherwise.
bool dumpTokens(StringRef Input, raw_ostream &);
-/// @brief Scans all tokens in input without outputting anything. This is used
+/// \brief Scans all tokens in input without outputting anything. This is used
/// for benchmarking the tokenizer.
-/// @returns true if there was an error, false otherwise.
+/// \returns true if there was an error, false otherwise.
bool scanTokens(StringRef Input);
-/// @brief Escape \a Input for a double quoted scalar.
+/// \brief Escape \a Input for a double quoted scalar.
std::string escape(StringRef Input);
-/// @brief This class represents a YAML stream potentially containing multiple
+/// \brief This class represents a YAML stream potentially containing multiple
/// documents.
class Stream {
public:
- /// @brief This keeps a reference to the string referenced by \p Input.
+ /// \brief This keeps a reference to the string referenced by \p Input.
Stream(StringRef Input, SourceMgr &);
- /// @brief This takes ownership of \p InputBuffer.
+ /// \brief This takes ownership of \p InputBuffer.
Stream(MemoryBuffer *InputBuffer, SourceMgr &);
~Stream();
@@ -101,9 +101,10 @@ private:
friend class Document;
};
-/// @brief Abstract base class for all Nodes.
+/// \brief Abstract base class for all Nodes.
class Node {
- virtual void anchor();
+ virtual void anchor();
+
public:
enum NodeKind {
NK_Null,
@@ -117,7 +118,7 @@ public:
Node(unsigned int Type, std::unique_ptr<Document> &, StringRef Anchor,
StringRef Tag);
- /// @brief Get the value of the anchor attached to this node. If it does not
+ /// \brief Get the value of the anchor attached to this node. If it does not
/// have one, getAnchor().size() will be 0.
StringRef getAnchor() const { return Anchor; }
@@ -144,14 +145,13 @@ public:
unsigned int getType() const { return TypeID; }
- void *operator new ( size_t Size
- , BumpPtrAllocator &Alloc
- , size_t Alignment = 16) throw() {
+ void *operator new(size_t Size, BumpPtrAllocator &Alloc,
+ size_t Alignment = 16) throw() {
return Alloc.Allocate(Size, Alignment);
}
- void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t) throw() {
- Alloc.Deallocate(Ptr);
+ void operator delete(void *Ptr, BumpPtrAllocator &Alloc, size_t Size) throw() {
+ Alloc.Deallocate(Ptr, Size);
}
protected:
@@ -169,28 +169,28 @@ private:
StringRef Tag;
};
-/// @brief A null value.
+/// \brief A null value.
///
/// Example:
/// !!null null
class NullNode : public Node {
void anchor() override;
+
public:
NullNode(std::unique_ptr<Document> &D)
: Node(NK_Null, D, StringRef(), StringRef()) {}
- static inline bool classof(const Node *N) {
- return N->getType() == NK_Null;
- }
+ static inline bool classof(const Node *N) { return N->getType() == NK_Null; }
};
-/// @brief A scalar node is an opaque datum that can be presented as a
+/// \brief A scalar node is an opaque datum that can be presented as a
/// series of zero or more Unicode scalar values.
///
/// Example:
/// Adena
class ScalarNode : public Node {
void anchor() override;
+
public:
ScalarNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
StringRef Val)
@@ -205,9 +205,9 @@ public:
// utf8).
StringRef getRawValue() const { return Value; }
- /// @brief Gets the value of this node as a StringRef.
+ /// \brief Gets the value of this node as a StringRef.
///
- /// @param Storage is used to store the content of the returned StringRef iff
+ /// \param Storage is used to store the content of the returned StringRef iff
/// it requires any modification from how it appeared in the source.
/// This happens with escaped characters and multi-line literals.
StringRef getValue(SmallVectorImpl<char> &Storage) const;
@@ -219,12 +219,12 @@ public:
private:
StringRef Value;
- StringRef unescapeDoubleQuoted( StringRef UnquotedValue
- , StringRef::size_type Start
- , SmallVectorImpl<char> &Storage) const;
+ StringRef unescapeDoubleQuoted(StringRef UnquotedValue,
+ StringRef::size_type Start,
+ SmallVectorImpl<char> &Storage) const;
};
-/// @brief A key and value pair. While not technically a Node under the YAML
+/// \brief A key and value pair. While not technically a Node under the YAML
/// representation graph, it is easier to treat them this way.
///
/// TODO: Consider making this not a child of Node.
@@ -233,22 +233,24 @@ private:
/// Section: .text
class KeyValueNode : public Node {
void anchor() override;
+
public:
KeyValueNode(std::unique_ptr<Document> &D)
- : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(0), Value(0) {}
+ : Node(NK_KeyValue, D, StringRef(), StringRef()), Key(nullptr),
+ Value(nullptr) {}
- /// @brief Parse and return the key.
+ /// \brief Parse and return the key.
///
/// This may be called multiple times.
///
- /// @returns The key, or nullptr if failed() == true.
+ /// \returns The key, or nullptr if failed() == true.
Node *getKey();
- /// @brief Parse and return the value.
+ /// \brief Parse and return the value.
///
/// This may be called multiple times.
///
- /// @returns The value, or nullptr if failed() == true.
+ /// \returns The value, or nullptr if failed() == true.
Node *getValue();
void skip() override {
@@ -265,47 +267,47 @@ private:
Node *Value;
};
-/// @brief This is an iterator abstraction over YAML collections shared by both
+/// \brief This is an iterator abstraction over YAML collections shared by both
/// sequences and maps.
///
/// BaseT must have a ValueT* member named CurrentEntry and a member function
/// increment() which must set CurrentEntry to 0 to create an end iterator.
template <class BaseT, class ValueT>
class basic_collection_iterator
- : public std::iterator<std::forward_iterator_tag, ValueT> {
+ : public std::iterator<std::forward_iterator_tag, ValueT> {
public:
- basic_collection_iterator() : Base(0) {}
+ basic_collection_iterator() : Base(nullptr) {}
basic_collection_iterator(BaseT *B) : Base(B) {}
- ValueT *operator ->() const {
+ ValueT *operator->() const {
assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
return Base->CurrentEntry;
}
- ValueT &operator *() const {
+ ValueT &operator*() const {
assert(Base && Base->CurrentEntry &&
"Attempted to dereference end iterator!");
return *Base->CurrentEntry;
}
- operator ValueT*() const {
+ operator ValueT *() const {
assert(Base && Base->CurrentEntry && "Attempted to access end iterator!");
return Base->CurrentEntry;
}
- bool operator !=(const basic_collection_iterator &Other) const {
- if(Base != Other.Base)
+ bool operator!=(const basic_collection_iterator &Other) const {
+ if (Base != Other.Base)
return true;
- return (Base && Other.Base) && Base->CurrentEntry
- != Other.Base->CurrentEntry;
+ return (Base && Other.Base) &&
+ Base->CurrentEntry != Other.Base->CurrentEntry;
}
basic_collection_iterator &operator++() {
assert(Base && "Attempted to advance iterator past end!");
Base->increment();
// Create an end iterator.
- if (Base->CurrentEntry == 0)
- Base = 0;
+ if (!Base->CurrentEntry)
+ Base = nullptr;
return *this;
}
@@ -323,17 +325,16 @@ typename CollectionType::iterator begin(CollectionType &C) {
return ret;
}
-template <class CollectionType>
-void skip(CollectionType &C) {
+template <class CollectionType> void skip(CollectionType &C) {
// TODO: support skipping from the middle of a parsed collection ;/
assert((C.IsAtBeginning || C.IsAtEnd) && "Cannot skip mid parse!");
if (C.IsAtBeginning)
- for (typename CollectionType::iterator i = begin(C), e = C.end();
- i != e; ++i)
+ for (typename CollectionType::iterator i = begin(C), e = C.end(); i != e;
+ ++i)
i->skip();
}
-/// @brief Represents a YAML map created from either a block map for a flow map.
+/// \brief Represents a YAML map created from either a block map for a flow map.
///
/// This parses the YAML stream as increment() is called.
///
@@ -342,6 +343,7 @@ void skip(CollectionType &C) {
/// Scope: Global
class MappingNode : public Node {
void anchor() override;
+
public:
enum MappingType {
MT_Block,
@@ -352,22 +354,18 @@ public:
MappingNode(std::unique_ptr<Document> &D, StringRef Anchor, StringRef Tag,
MappingType MT)
: Node(NK_Mapping, D, Anchor, Tag), Type(MT), IsAtBeginning(true),
- IsAtEnd(false), CurrentEntry(0) {}
+ IsAtEnd(false), CurrentEntry(nullptr) {}
friend class basic_collection_iterator<MappingNode, KeyValueNode>;
typedef basic_collection_iterator<MappingNode, KeyValueNode> iterator;
template <class T> friend typename T::iterator yaml::begin(T &);
template <class T> friend void yaml::skip(T &);
- iterator begin() {
- return yaml::begin(*this);
- }
+ iterator begin() { return yaml::begin(*this); }
iterator end() { return iterator(); }
- void skip() override {
- yaml::skip(*this);
- }
+ void skip() override { yaml::skip(*this); }
static inline bool classof(const Node *N) {
return N->getType() == NK_Mapping;
@@ -382,7 +380,7 @@ private:
void increment();
};
-/// @brief Represents a YAML sequence created from either a block sequence for a
+/// \brief Represents a YAML sequence created from either a block sequence for a
/// flow sequence.
///
/// This parses the YAML stream as increment() is called.
@@ -392,6 +390,7 @@ private:
/// - World
class SequenceNode : public Node {
void anchor() override;
+
public:
enum SequenceType {
ST_Block,
@@ -411,7 +410,7 @@ public:
: Node(NK_Sequence, D, Anchor, Tag), SeqType(ST), IsAtBeginning(true),
IsAtEnd(false),
WasPreviousTokenFlowEntry(true), // Start with an imaginary ','.
- CurrentEntry(0) {}
+ CurrentEntry(nullptr) {}
friend class basic_collection_iterator<SequenceNode, Node>;
typedef basic_collection_iterator<SequenceNode, Node> iterator;
@@ -420,15 +419,11 @@ public:
void increment();
- iterator begin() {
- return yaml::begin(*this);
- }
+ iterator begin() { return yaml::begin(*this); }
iterator end() { return iterator(); }
- void skip() override {
- yaml::skip(*this);
- }
+ void skip() override { yaml::skip(*this); }
static inline bool classof(const Node *N) {
return N->getType() == NK_Sequence;
@@ -442,12 +437,13 @@ private:
Node *CurrentEntry;
};
-/// @brief Represents an alias to a Node with an anchor.
+/// \brief Represents an alias to a Node with an anchor.
///
/// Example:
/// *AnchorName
class AliasNode : public Node {
void anchor() override;
+
public:
AliasNode(std::unique_ptr<Document> &D, StringRef Val)
: Node(NK_Alias, D, StringRef(), StringRef()), Name(Val) {}
@@ -455,50 +451,46 @@ public:
StringRef getName() const { return Name; }
Node *getTarget();
- static inline bool classof(const Node *N) {
- return N->getType() == NK_Alias;
- }
+ static inline bool classof(const Node *N) { return N->getType() == NK_Alias; }
private:
StringRef Name;
};
-/// @brief A YAML Stream is a sequence of Documents. A document contains a root
+/// \brief A YAML Stream is a sequence of Documents. A document contains a root
/// node.
class Document {
public:
- /// @brief Root for parsing a node. Returns a single node.
+ /// \brief Root for parsing a node. Returns a single node.
Node *parseBlockNode();
Document(Stream &ParentStream);
- /// @brief Finish parsing the current document and return true if there are
+ /// \brief Finish parsing the current document and return true if there are
/// more. Return false otherwise.
bool skip();
- /// @brief Parse and return the root level node.
+ /// \brief Parse and return the root level node.
Node *getRoot() {
if (Root)
return Root;
return Root = parseBlockNode();
}
- const std::map<StringRef, StringRef> &getTagMap() const {
- return TagMap;
- }
+ const std::map<StringRef, StringRef> &getTagMap() const { return TagMap; }
private:
friend class Node;
friend class document_iterator;
- /// @brief Stream to read tokens from.
+ /// \brief Stream to read tokens from.
Stream &stream;
- /// @brief Used to allocate nodes to. All are destroyed without calling their
+ /// \brief Used to allocate nodes to. All are destroyed without calling their
/// destructor when the document is destroyed.
BumpPtrAllocator NodeAllocator;
- /// @brief The root node. Used to support skipping a partially parsed
+ /// \brief The root node. Used to support skipping a partially parsed
/// document.
Node *Root;
@@ -510,7 +502,7 @@ private:
void setError(const Twine &Message, Token &Location) const;
bool failed() const;
- /// @brief Parse %BLAH directives and return true if any were encountered.
+ /// \brief Parse %BLAH directives and return true if any were encountered.
bool parseDirectives();
/// \brief Parse %YAML
@@ -519,30 +511,28 @@ private:
/// \brief Parse %TAG
void parseTAGDirective();
- /// @brief Consume the next token and error if it is not \a TK.
+ /// \brief Consume the next token and error if it is not \a TK.
bool expectToken(int TK);
};
-/// @brief Iterator abstraction for Documents over a Stream.
+/// \brief Iterator abstraction for Documents over a Stream.
class document_iterator {
public:
- document_iterator() : Doc(0) {}
+ document_iterator() : Doc(nullptr) {}
document_iterator(std::unique_ptr<Document> &D) : Doc(&D) {}
- bool operator ==(const document_iterator &Other) {
+ bool operator==(const document_iterator &Other) {
if (isAtEnd() || Other.isAtEnd())
return isAtEnd() && Other.isAtEnd();
return Doc == Other.Doc;
}
- bool operator !=(const document_iterator &Other) {
- return !(*this == Other);
- }
+ bool operator!=(const document_iterator &Other) { return !(*this == Other); }
- document_iterator operator ++() {
- assert(Doc != 0 && "incrementing iterator past the end.");
+ document_iterator operator++() {
+ assert(Doc && "incrementing iterator past the end.");
if (!(*Doc)->skip()) {
- Doc->reset(0);
+ Doc->reset(nullptr);
} else {
Stream &S = (*Doc)->stream;
Doc->reset(new Document(S));
@@ -550,21 +540,18 @@ public:
return *this;
}
- Document &operator *() {
- return *Doc->get();
- }
+ Document &operator*() { return *Doc->get(); }
std::unique_ptr<Document> &operator->() { return *Doc; }
private:
- bool isAtEnd() const {
- return !Doc || !*Doc;
- }
+ bool isAtEnd() const { return !Doc || !*Doc; }
std::unique_ptr<Document> *Doc;
};
-}
-}
+} // End namespace yaml.
+
+} // End namespace llvm.
#endif
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index ea217c3..4ee05ed 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Regex.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
@@ -32,7 +33,7 @@ namespace yaml {
/// This class should be specialized by any type that needs to be converted
/// to/from a YAML mapping. For example:
///
-/// struct ScalarBitSetTraits<MyStruct> {
+/// struct MappingTraits<MyStruct> {
/// static void mapping(IO &io, MyStruct &s) {
/// io.mapRequired("name", s.name);
/// io.mapRequired("size", s.size);
@@ -98,6 +99,7 @@ struct ScalarBitSetTraits {
/// // return empty string on success, or error string
/// return StringRef();
/// }
+/// static bool mustQuote(StringRef) { return true; }
/// };
template<typename T>
struct ScalarTraits {
@@ -109,6 +111,9 @@ struct ScalarTraits {
// Function to convert a string to a value. Returns the empty
// StringRef on success or an error string if string is malformed:
//static StringRef input(StringRef scalar, void *ctxt, T &value);
+ //
+ // Function to determine if the value should be quoted.
+ //static bool mustQuote(StringRef);
};
@@ -171,7 +176,8 @@ struct has_ScalarEnumerationTraits
static double test(...);
public:
- static bool const value = (sizeof(test<ScalarEnumerationTraits<T> >(0)) == 1);
+ static bool const value =
+ (sizeof(test<ScalarEnumerationTraits<T> >(nullptr)) == 1);
};
@@ -188,7 +194,7 @@ struct has_ScalarBitSetTraits
static double test(...);
public:
- static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(0)) == 1);
+ static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(nullptr)) == 1);
};
@@ -198,16 +204,19 @@ struct has_ScalarTraits
{
typedef StringRef (*Signature_input)(StringRef, void*, T&);
typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
+ typedef bool (*Signature_mustQuote)(StringRef);
template <typename U>
- static char test(SameType<Signature_input, &U::input>*,
- SameType<Signature_output, &U::output>*);
+ static char test(SameType<Signature_input, &U::input> *,
+ SameType<Signature_output, &U::output> *,
+ SameType<Signature_mustQuote, &U::mustQuote> *);
template <typename U>
static double test(...);
public:
- static bool const value = (sizeof(test<ScalarTraits<T> >(0,0)) == 1);
+ static bool const value =
+ (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
};
@@ -224,7 +233,7 @@ struct has_MappingTraits
static double test(...);
public:
- static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
+ static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
};
// Test if MappingTraits<T>::validate() is defined on type T.
@@ -240,7 +249,7 @@ struct has_MappingValidateTraits
static double test(...);
public:
- static bool const value = (sizeof(test<MappingTraits<T> >(0)) == 1);
+ static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
};
@@ -258,7 +267,7 @@ struct has_SequenceMethodTraits
static double test(...);
public:
- static bool const value = (sizeof(test<SequenceTraits<T> >(0)) == 1);
+ static bool const value = (sizeof(test<SequenceTraits<T> >(nullptr)) == 1);
};
@@ -288,7 +297,7 @@ struct has_FlowTraits<T, true>
static char (&f(...))[2];
public:
- static bool const value = sizeof(f<Derived>(0)) == 2;
+ static bool const value = sizeof(f<Derived>(nullptr)) == 2;
};
@@ -312,10 +321,84 @@ struct has_DocumentListTraits
static double test(...);
public:
- static bool const value = (sizeof(test<DocumentListTraits<T> >(0)) == 1);
+ static bool const value = (sizeof(test<DocumentListTraits<T> >(nullptr))==1);
};
+inline bool isNumber(StringRef S) {
+ static const char OctalChars[] = "01234567";
+ if (S.startswith("0") &&
+ S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
+ return true;
+
+ if (S.startswith("0o") &&
+ S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
+ return true;
+
+ static const char HexChars[] = "0123456789abcdefABCDEF";
+ if (S.startswith("0x") &&
+ S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
+ return true;
+
+ static const char DecChars[] = "0123456789";
+ if (S.find_first_not_of(DecChars) == StringRef::npos)
+ return true;
+
+ if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
+ return true;
+
+ Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
+ if (FloatMatcher.match(S))
+ return true;
+
+ return false;
+}
+
+inline bool isNumeric(StringRef S) {
+ if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
+ return true;
+
+ if (isNumber(S))
+ return true;
+
+ if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
+ return true;
+
+ return false;
+}
+
+inline bool isNull(StringRef S) {
+ return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
+ S.equals("~");
+}
+inline bool isBool(StringRef S) {
+ return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
+ S.equals("false") || S.equals("False") || S.equals("FALSE");
+}
+
+inline bool needsQuotes(StringRef S) {
+ if (S.empty())
+ return true;
+ if (isspace(S.front()) || isspace(S.back()))
+ return true;
+ if (S.front() == ',')
+ return true;
+
+ static const char ScalarSafeChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
+ if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
+ return true;
+
+ if (isNull(S))
+ return true;
+ if (isBool(S))
+ return true;
+ if (isNumeric(S))
+ return true;
+
+ return false;
+}
template<typename T>
@@ -340,7 +423,7 @@ struct unvalidatedMappingTraits : public std::integral_constant<bool,
class IO {
public:
- IO(void *Ctxt=NULL);
+ IO(void *Ctxt=nullptr);
virtual ~IO();
virtual bool outputting() = 0;
@@ -370,7 +453,7 @@ public:
virtual bool bitSetMatch(const char*, bool) = 0;
virtual void endBitSetScalar() = 0;
- virtual void scalarString(StringRef &) = 0;
+ virtual void scalarString(StringRef &, bool) = 0;
virtual void setError(const Twine &) = 0;
@@ -404,6 +487,19 @@ public:
}
}
+ template <typename T>
+ void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
+ if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+ Val = Val | ConstVal;
+ }
+
+ template <typename T>
+ void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
+ uint32_t Mask) {
+ if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
+ Val = Val | ConstVal;
+ }
+
void *getContext();
void setContext(void *);
@@ -520,11 +616,11 @@ yamlize(IO &io, T &Val, bool) {
llvm::raw_string_ostream Buffer(Storage);
ScalarTraits<T>::output(Val, io.getContext(), Buffer);
StringRef Str = Buffer.str();
- io.scalarString(Str);
+ io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
}
else {
StringRef Str;
- io.scalarString(Str);
+ io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
if ( !Result.empty() ) {
io.setError(llvm::Twine(Result));
@@ -601,78 +697,91 @@ template<>
struct ScalarTraits<bool> {
static void output(const bool &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, bool &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<StringRef> {
static void output(const StringRef &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, StringRef &);
+ static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<std::string> {
static void output(const std::string &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, std::string &);
+ static bool mustQuote(StringRef S) { return needsQuotes(S); }
};
template<>
struct ScalarTraits<uint8_t> {
static void output(const uint8_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, uint8_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint16_t> {
static void output(const uint16_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, uint16_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint32_t> {
static void output(const uint32_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, uint32_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<uint64_t> {
static void output(const uint64_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, uint64_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int8_t> {
static void output(const int8_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, int8_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int16_t> {
static void output(const int16_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, int16_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int32_t> {
static void output(const int32_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, int32_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<int64_t> {
static void output(const int64_t &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, int64_t &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<float> {
static void output(const float &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, float &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<double> {
static void output(const double &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, double &);
+ static bool mustQuote(StringRef) { return false; }
};
@@ -682,7 +791,7 @@ struct ScalarTraits<double> {
template <typename TNorm, typename TFinal>
struct MappingNormalization {
MappingNormalization(IO &i_o, TFinal &Obj)
- : io(i_o), BufPtr(NULL), Result(Obj) {
+ : io(i_o), BufPtr(nullptr), Result(Obj) {
if ( io.outputting() ) {
BufPtr = new (&Buffer) TNorm(io, Obj);
}
@@ -765,9 +874,9 @@ public:
// user-data. The DiagHandler can be specified to provide
// alternative error reporting.
Input(StringRef InputContent,
- void *Ctxt = NULL,
- SourceMgr::DiagHandlerTy DiagHandler = NULL,
- void *DiagHandlerCtxt = NULL);
+ void *Ctxt = nullptr,
+ SourceMgr::DiagHandlerTy DiagHandler = nullptr,
+ void *DiagHandlerCtxt = nullptr);
~Input();
// Check if there was an syntax or semantic error during parsing.
@@ -794,7 +903,7 @@ private:
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
- void scalarString(StringRef &) override;
+ void scalarString(StringRef &, bool) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
@@ -896,7 +1005,7 @@ private:
///
class Output : public IO {
public:
- Output(llvm::raw_ostream &, void *Ctxt=NULL);
+ Output(llvm::raw_ostream &, void *Ctxt=nullptr);
virtual ~Output();
bool outputting() override;
@@ -919,7 +1028,7 @@ public:
bool beginBitSetScalar(bool &) override;
bool bitSetMatch(const char *, bool ) override;
void endBitSetScalar() override;
- void scalarString(StringRef &) override;
+ void scalarString(StringRef &, bool) override;
void setError(const Twine &message) override;
bool canElideEmptySequence() override;
public:
@@ -990,24 +1099,28 @@ template<>
struct ScalarTraits<Hex8> {
static void output(const Hex8 &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, Hex8 &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex16> {
static void output(const Hex16 &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, Hex16 &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex32> {
static void output(const Hex32 &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, Hex32 &);
+ static bool mustQuote(StringRef) { return false; }
};
template<>
struct ScalarTraits<Hex64> {
static void output(const Hex64 &, void*, llvm::raw_ostream &);
static StringRef input(StringRef, void*, Hex64 &);
+ static bool mustQuote(StringRef) { return false; }
};
diff --git a/include/llvm/Support/circular_raw_ostream.h b/include/llvm/Support/circular_raw_ostream.h
index 3114199..ee7b89f 100644
--- a/include/llvm/Support/circular_raw_ostream.h
+++ b/include/llvm/Support/circular_raw_ostream.h
@@ -109,10 +109,10 @@ namespace llvm
circular_raw_ostream(raw_ostream &Stream, const char *Header,
size_t BuffSize = 0, bool Owns = REFERENCE_ONLY)
: raw_ostream(/*unbuffered*/true),
- TheStream(0),
+ TheStream(nullptr),
OwnsStream(Owns),
BufferSize(BuffSize),
- BufferArray(0),
+ BufferArray(nullptr),
Filled(false),
Banner(Header) {
if (BufferSize != 0)
@@ -122,9 +122,9 @@ namespace llvm
}
explicit circular_raw_ostream()
: raw_ostream(/*unbuffered*/true),
- TheStream(0),
+ TheStream(nullptr),
OwnsStream(REFERENCE_ONLY),
- BufferArray(0),
+ BufferArray(nullptr),
Filled(false),
Banner("") {
Cur = BufferArray;
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 0240035..34fbe08 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -17,13 +17,18 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/FileSystem.h"
namespace llvm {
class format_object_base;
template <typename T>
class SmallVectorImpl;
+ namespace sys {
+ namespace fs {
+ enum OpenFlags : unsigned;
+ }
+ }
+
/// raw_ostream - This class implements an extremely fast bulk output stream
/// that can *only* output to a stream. It does not support seeking, reopening,
/// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
@@ -76,7 +81,7 @@ public:
explicit raw_ostream(bool unbuffered=false)
: BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
// Start out ready to flush.
- OutBufStart = OutBufEnd = OutBufCur = 0;
+ OutBufStart = OutBufEnd = OutBufCur = nullptr;
}
virtual ~raw_ostream();
@@ -102,7 +107,7 @@ public:
size_t GetBufferSize() const {
// If we're supposed to be buffered but haven't actually gotten around
// to allocating the buffer yet, return the value that would be used.
- if (BufferMode != Unbuffered && OutBufStart == 0)
+ if (BufferMode != Unbuffered && OutBufStart == nullptr)
return preferred_buffer_size();
// Otherwise just return the size of the allocated buffer.
@@ -115,7 +120,7 @@ public:
/// set to unbuffered.
void SetUnbuffered() {
flush();
- SetBufferAndMode(0, 0, Unbuffered);
+ SetBufferAndMode(nullptr, 0, Unbuffered);
}
size_t GetNumBytesInBuffer() const {
@@ -157,7 +162,7 @@ public:
size_t Size = Str.size();
// Make sure we can use the fast path.
- if (OutBufCur+Size > OutBufEnd)
+ if (Size > (size_t)(OutBufEnd - OutBufCur))
return write(Str.data(), Size);
memcpy(OutBufCur, Str.data(), Size);
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 4ca4b06..aa5e9f7 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -706,7 +706,7 @@ public:
static void unspecified_bool_true() {}
operator unspecified_bool_type() const { // true if error
- return _val_ == 0 ? 0 : unspecified_bool_true;
+ return _val_ == 0 ? nullptr : unspecified_bool_true;
}
};
@@ -771,7 +771,7 @@ public:
static void unspecified_bool_true() {}
operator unspecified_bool_type() const { // true if error
- return _val_ == 0 ? 0 : unspecified_bool_true;
+ return _val_ == 0 ? nullptr : unspecified_bool_true;
}
};