From dce4a407a24b04eebc6a376f8e62b41aaa7b071f Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Thu, 29 May 2014 02:49:00 -0700 Subject: Update LLVM for 3.5 rebase (r209712). Change-Id: I149556c940fb7dc92d075273c87ff584f400941f --- include/llvm/Support/ARMBuildAttributes.h | 13 + include/llvm/Support/Allocator.h | 410 +++++++++------- include/llvm/Support/ArrayRecycler.h | 4 +- include/llvm/Support/BlockFrequency.h | 10 - include/llvm/Support/BranchProbability.h | 34 +- include/llvm/Support/COFF.h | 6 +- include/llvm/Support/Casting.h | 10 +- include/llvm/Support/CommandLine.h | 29 +- include/llvm/Support/Compression.h | 7 +- include/llvm/Support/CrashRecoveryContext.h | 35 +- include/llvm/Support/Debug.h | 16 +- include/llvm/Support/DynamicLibrary.h | 4 +- include/llvm/Support/ELF.h | 17 +- include/llvm/Support/ErrorHandling.h | 10 +- include/llvm/Support/FileOutputBuffer.h | 4 - include/llvm/Support/FileSystem.h | 29 +- include/llvm/Support/FileUtilities.h | 2 +- include/llvm/Support/FormattedStream.h | 8 +- include/llvm/Support/GCOV.h | 50 +- include/llvm/Support/GenericDomTree.h | 45 +- include/llvm/Support/GenericDomTreeConstruction.h | 12 +- include/llvm/Support/GraphWriter.h | 9 +- include/llvm/Support/LEB128.h | 2 +- include/llvm/Support/LineIterator.h | 5 +- include/llvm/Support/LockFileManager.h | 12 +- include/llvm/Support/MachO.h | 48 ++ include/llvm/Support/ManagedStatic.h | 2 +- include/llvm/Support/Memory.h | 10 +- include/llvm/Support/MemoryBuffer.h | 36 +- include/llvm/Support/OnDiskHashTable.h | 571 ++++++++++++++++++++++ include/llvm/Support/Path.h | 5 + include/llvm/Support/Program.h | 26 +- include/llvm/Support/Regex.h | 7 +- include/llvm/Support/Registry.h | 15 +- include/llvm/Support/SMLoc.h | 4 +- include/llvm/Support/SaveAndRestore.h | 48 +- include/llvm/Support/Signals.h | 2 +- include/llvm/Support/SourceMgr.h | 9 +- include/llvm/Support/StreamableMemoryObject.h | 2 +- include/llvm/Support/StringPool.h | 8 +- include/llvm/Support/TargetRegistry.h | 85 ++-- include/llvm/Support/Timer.h | 14 +- include/llvm/Support/Unicode.h | 5 + include/llvm/Support/UnicodeCharRanges.h | 4 + include/llvm/Support/YAMLParser.h | 181 ++++--- include/llvm/Support/YAMLTraits.h | 157 +++++- include/llvm/Support/circular_raw_ostream.h | 8 +- include/llvm/Support/raw_ostream.h | 15 +- include/llvm/Support/system_error.h | 4 +- 49 files changed, 1470 insertions(+), 579 deletions(-) create mode 100644 include/llvm/Support/OnDiskHashTable.h (limited to 'include/llvm/Support') 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 namespace llvm { -template struct ReferenceAdder { - typedef T &result; -}; -template struct ReferenceAdder { - 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 class AllocatorBase { public: - MallocAllocator() {} - ~MallocAllocator() {} - - void Reset() {} - - void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } - - template T *Allocate() { - return static_cast(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( + &AllocatorBase::Allocate) != + static_cast( + &DerivedT::Allocate), + "Class derives from AllocatorBase without implementing the " + "core Allocate(size_t, size_t) overload!"); +#endif + return static_cast(this)->Allocate(Size, Alignment); } - template T *Allocate(size_t Num) { - return static_cast(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( + &AllocatorBase::Deallocate) != + static_cast( + &DerivedT::Deallocate), + "Class derives from AllocatorBase without implementing the " + "core Deallocate(void *) overload!"); +#endif + return static_cast(this)->Deallocate(Ptr, Size); } - void Deallocate(const void *Ptr) { free(const_cast(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 T *Allocate(size_t Num = 1) { + return static_cast(Allocate(Num * sizeof(T), AlignOf::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 std::enable_if< + !std::is_same::type, void>::value, void>::type + Deallocate(T *Ptr, size_t Num = 1) { + Deallocate(static_cast(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 { 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::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(Ptr)); + } - /// \brief Returns the total physical memory allocated by this allocator. - size_t getTotalMemory() const; + // Pull in base class overloads. + using AllocatorBase::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 -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 +class BumpPtrAllocatorImpl + : public AllocatorBase< + BumpPtrAllocatorImpl> { 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 + BumpPtrAllocatorImpl(T &&Allocator) + : CurPtr(nullptr), End(nullptr), BytesAllocated(0), + Allocator(std::forward(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 T *Allocate() { - return static_cast(Allocate(sizeof(T), AlignOf::Alignment)); - } + // Pull in base class overloads. + using AllocatorBase::Allocate; - /// \brief Allocate space for an array of objects without constructing them. - template T *Allocate(size_t Num) { - return static_cast(Allocate(Num * sizeof(T), AlignOf::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 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(Allocate(Num * EltSize, Alignment)); - } + // Pull in base class overloads. + using AllocatorBase::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 Slabs; + + /// \brief Custom-sized slabs allocated for too-large allocation requests. + SmallVector, 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(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(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::iterator I, + SmallVectorImpl::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 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()); - if (Ptr + sizeof(T) <= End) - reinterpret_cast(Ptr)->~T(); - } - Slab = Slab->NextPtr; + auto DestroyElements = [](char *Begin, char *End) { + assert(Begin == alignPtr(Begin, alignOf())); + for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T)) + reinterpret_cast(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()); + 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()), (char *)Ptr + Size); } + Allocator.Reset(); } @@ -325,10 +404,10 @@ public: } // end namespace llvm -template -void * -operator new(size_t Size, - llvm::BumpPtrAllocatorImpl &Allocator) { +template +void *operator new(size_t Size, + llvm::BumpPtrAllocatorImpl &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 -void operator delete(void *, - llvm::BumpPtrAllocatorImpl &) {} +template +void operator delete( + void *, llvm::BumpPtrAllocatorImpl &) { +} #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(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::ret_type cast(Y *Val) { template LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type cast_or_null(Y *Val) { - if (Val == 0) return 0; + if (!Val) return nullptr; assert(isa(Val) && "cast_or_null() argument of incompatible type!"); return cast(Val); } @@ -263,19 +263,19 @@ template LLVM_ATTRIBUTE_UNUSED_RESULT inline typename std::enable_if< !is_simple_type::value, typename cast_retty::ret_type>::type dyn_cast(const Y &Val) { - return isa(Val) ? cast(Val) : 0; + return isa(Val) ? cast(Val) : nullptr; } template LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type dyn_cast(Y &Val) { - return isa(Val) ? cast(Val) : 0; + return isa(Val) ? cast(Val) : nullptr; } template LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type dyn_cast(Y *Val) { - return isa(Val) ? cast(Val) : 0; + return isa(Val) ? cast(Val) : nullptr; } // dyn_cast_or_null - Functionally identical to dyn_cast, except that a null @@ -284,7 +284,7 @@ dyn_cast(Y *Val) { template LLVM_ATTRIBUTE_UNUSED_RESULT inline typename cast_retty::ret_type dyn_cast_or_null(Y *Val) { - return (Val && isa(Val)) ? cast(Val) : 0; + return (Val && isa(Val)) ? cast(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 = 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 = 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 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 - 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 - 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 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 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 +#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 &CompressedBuffer, +Status compress(StringRef InputBuffer, SmallVectorImpl &CompressedBuffer, CompressionLevel Level = DefaultCompression); Status uncompress(StringRef InputBuffer, - std::unique_ptr &UncompressedBuffer, + SmallVectorImpl &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 +#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 struct FunctorAdaptor { - T Fn; - static void invoke(void *Data) { - return static_cast*>(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 - bool RunSafely(Functor Fn) { - FunctorAdaptor Adaptor = { Fn }; - return RunSafely(Adaptor.fn(), Adaptor.arg()); + bool RunSafely(function_ref 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, unsigned RequestedStackSize = 0); bool RunSafelyOnThread(void (*Fn)(void*), void *UserData, - unsigned RequestedStackSize = 0); - template - bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) { - FunctorAdaptor 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 &Result, - unsigned Flags = 0); - static error_code create(StringRef FilePath, size_t Size, std::unique_ptr &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 &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 Functions; + SmallVector, 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::const_iterator BlockIterator; + typedef SmallVectorImpl>::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 Blocks; - SmallVector Edges; + SmallVector, 16> Blocks; + SmallVector, 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 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 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 { assert(isReachableFromEntry(A)); const DomTreeNodeBase *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 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 &Result) const { Result.clear(); const DomTreeNodeBase *RN = getNode(R); - if (RN == NULL) + if (!RN) return; // If R is unreachable, it will not be present in the DOM tree. SmallVector *, 8> WL; WL.push_back(RN); @@ -361,7 +361,7 @@ public: /// bool properlyDominates(const DomTreeNodeBase *A, const DomTreeNodeBase *B) const { - if (A == 0 || B == 0) + if (!A || !B) return false; if (A == B) return false; @@ -453,6 +453,21 @@ public: DomTreeNodeBase *NodeA = getNode(A); DomTreeNodeBase *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 *IDomA = NodeA->getIDom(); + while (IDomA) { + if (NodeB->DominatedBy(IDomA)) + return IDomA->getBlock(); + IDomA = IDomA->getIDom(); + } + return nullptr; + } + // Collect NodeA dominators set. SmallPtrSet*, 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 *addNewBlock(NodeT *BB, NodeT *DomBB) { - assert(getNode(BB) == 0 && "Block already in dominator tree!"); + assert(getNode(BB) == nullptr && "Block already in dominator tree!"); DomTreeNodeBase *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 *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 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(*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 >(*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::NodeType>& DT, bool MultipleRoots = (DT.Roots.size() > 1); if (MultipleRoots) { typename DominatorTreeBase::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::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(Root, 0); + new DomTreeNodeBase(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::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 *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 *EdgeSourceLabels = 0) { + const std::string &Label, unsigned NumEdgeSources = 0, + const std::vector *EdgeSourceLabels = nullptr) { O << "\tNode" << ID << "[ "; if (!Attr.empty()) O << Attr << ","; @@ -325,7 +325,10 @@ template 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(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 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 { + : public std::iterator { 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 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 &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 &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 &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 &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 &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 &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 &Result); static error_code getSTDIN(std::unique_ptr &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 &Result, - int64_t FileSize = -1); - static error_code getFileOrSTDIN(StringRef Filename, std::unique_ptr &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 +#include + +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 +/// 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 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 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 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(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(I->Hash); + const std::pair &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()); + TableOff += N; + while (N--) + LE.write(0); + + // Emit the hashtable itself. + LE.write(NumBuckets); + LE.write(NumEntries); + for (offset_type I = 0; I < NumBuckets; ++I) + LE.write(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 +/// 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 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(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(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(Items); + + for (unsigned i = 0; i < Len; ++i) { + // Read the hash. + hash_value_type ItemHash = + endian::readNext(Items); + + // Determine the length of the key and the data. + const std::pair &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(Buckets) & 0x3) == 0 && + "buckets should be 4-byte aligned."); + + offset_type NumBuckets = + endian::readNext(Buckets); + offset_type NumEntries = + endian::readNext(Buckets); + return new OnDiskChainedHashTable(NumBuckets, NumEntries, Buckets, + Base, InfoObj); + } +}; + +/// \brief Provides lookup and iteration over an on disk hash table. +/// +/// \copydetails llvm::OnDiskChainedHashTable +template +class OnDiskIterableChainedHashTable : public OnDiskChainedHashTable { + const unsigned char *Payload; + +public: + typedef OnDiskChainedHashTable 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(Ptr); + } + Ptr += sizeof(hash_value_type); // Skip the hash. + // Determine the length of the key and the data. + const std::pair &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 &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 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(Ptr); + } + Ptr += sizeof(hash_value_type); // Skip the hash. + // Determine the length of the key and the data. + const std::pair &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 &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() { + 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(Buckets) & 0x3) == 0 && + "buckets should be 4-byte aligned."); + + offset_type NumBuckets = + endian::readNext(Buckets); + offset_type NumEntries = + endian::readNext(Buckets); + return new OnDiskIterableChainedHashTable( + 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 &®ex) { 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 *Matches = 0); + bool match(StringRef String, SmallVectorImpl *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 + namespace llvm { /// A simple registry entry which provides only a name, description, and /// no-argument constructor. template class SimpleRegistryEntry { const char *Name, *Desc; - T *(*Ctor)(); + std::unique_ptr (*Ctor)(); public: - SimpleRegistryEntry(const char *N, const char *D, T *(*C)()) + SimpleRegistryEntry(const char *N, const char *D, std::unique_ptr (*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 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 CtorFn() { return make_unique(); } 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 -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 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 &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 &, 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 &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 &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 &Storage) const; @@ -219,12 +219,12 @@ public: private: StringRef Value; - StringRef unescapeDoubleQuoted( StringRef UnquotedValue - , StringRef::size_type Start - , SmallVectorImpl &Storage) const; + StringRef unescapeDoubleQuoted(StringRef UnquotedValue, + StringRef::size_type Start, + SmallVectorImpl &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 &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 basic_collection_iterator - : public std::iterator { + : public std::iterator { 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 -void skip(CollectionType &C) { +template 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 &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; typedef basic_collection_iterator iterator; template friend typename T::iterator yaml::begin(T &); template 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; typedef basic_collection_iterator 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 &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 &getTagMap() const { - return TagMap; - } + const std::map &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 &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 &operator->() { return *Doc; } private: - bool isAtEnd() const { - return !Doc || !*Doc; - } + bool isAtEnd() const { return !Doc || !*Doc; } std::unique_ptr *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 { +/// struct MappingTraits { /// 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 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 >(0)) == 1); + static bool const value = + (sizeof(test >(nullptr)) == 1); }; @@ -188,7 +194,7 @@ struct has_ScalarBitSetTraits static double test(...); public: - static bool const value = (sizeof(test >(0)) == 1); + static bool const value = (sizeof(test >(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 - static char test(SameType*, - SameType*); + static char test(SameType *, + SameType *, + SameType *); template static double test(...); public: - static bool const value = (sizeof(test >(0,0)) == 1); + static bool const value = + (sizeof(test>(nullptr, nullptr, nullptr)) == 1); }; @@ -224,7 +233,7 @@ struct has_MappingTraits static double test(...); public: - static bool const value = (sizeof(test >(0)) == 1); + static bool const value = (sizeof(test >(nullptr)) == 1); }; // Test if MappingTraits::validate() is defined on type T. @@ -240,7 +249,7 @@ struct has_MappingValidateTraits static double test(...); public: - static bool const value = (sizeof(test >(0)) == 1); + static bool const value = (sizeof(test >(nullptr)) == 1); }; @@ -258,7 +267,7 @@ struct has_SequenceMethodTraits static double test(...); public: - static bool const value = (sizeof(test >(0)) == 1); + static bool const value = (sizeof(test >(nullptr)) == 1); }; @@ -288,7 +297,7 @@ struct has_FlowTraits static char (&f(...))[2]; public: - static bool const value = sizeof(f(0)) == 2; + static bool const value = sizeof(f(nullptr)) == 2; }; @@ -312,10 +321,84 @@ struct has_DocumentListTraits static double test(...); public: - static bool const value = (sizeof(test >(0)) == 1); + static bool const value = (sizeof(test >(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 @@ -340,7 +423,7 @@ struct unvalidatedMappingTraits : public std::integral_constant + void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) { + if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal)) + Val = Val | ConstVal; + } + + template + 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::output(Val, io.getContext(), Buffer); StringRef Str = Buffer.str(); - io.scalarString(Str); + io.scalarString(Str, ScalarTraits::mustQuote(Str)); } else { StringRef Str; - io.scalarString(Str); + io.scalarString(Str, ScalarTraits::mustQuote(Str)); StringRef Result = ScalarTraits::input(Str, io.getContext(), Val); if ( !Result.empty() ) { io.setError(llvm::Twine(Result)); @@ -601,78 +697,91 @@ template<> struct ScalarTraits { static void output(const bool &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, bool &); + static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { static void output(const float &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, float &); + static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits { 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 { template 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 { static void output(const Hex8 &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, Hex8 &); + static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits { static void output(const Hex16 &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, Hex16 &); + static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits { static void output(const Hex32 &, void*, llvm::raw_ostream &); static StringRef input(StringRef, void*, Hex32 &); + static bool mustQuote(StringRef) { return false; } }; template<> struct ScalarTraits { 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 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; } }; -- cgit v1.1