diff options
Diffstat (limited to 'include/llvm/Support')
58 files changed, 1360 insertions, 892 deletions
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h index f63e0a6..07340de 100644 --- a/include/llvm/Support/ARMBuildAttributes.h +++ b/include/llvm/Support/ARMBuildAttributes.h @@ -16,8 +16,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H -#define LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H +#ifndef LLVM_SUPPORT_ARMBUILDATTRIBUTES_H +#define LLVM_SUPPORT_ARMBUILDATTRIBUTES_H namespace llvm { class StringRef; @@ -146,6 +146,12 @@ enum { AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations) AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted + // Tag_ABI_PCS_R9_use, (=14), uleb128 + R9IsGPR = 0, // R9 used as v6 (just another callee-saved register) + R9IsSB = 1, // R9 used as a global static base rgister + R9IsTLSPointer = 2, // R9 used as a thread local storage pointer + R9Reserved = 3, // R9 not used by code associated with attributed entity + // Tag_ABI_PCS_RW_data, (=15), uleb128 AddressRWPCRel = 1, // Address RW static data PC-relative AddressRWSBRel = 2, // Address RW static data SB-relative @@ -214,4 +220,4 @@ enum { } // namespace ARMBuildAttrs } // namespace llvm -#endif // LLVM_SUPPORT_ARM_BUILD_ATTRIBUTES_H +#endif diff --git a/include/llvm/Support/ARMEHABI.h b/include/llvm/Support/ARMEHABI.h index c7ac54a..9b052df 100644 --- a/include/llvm/Support/ARMEHABI.h +++ b/include/llvm/Support/ARMEHABI.h @@ -19,8 +19,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_ARM_EHABI_H -#define LLVM_SUPPORT_ARM_EHABI_H +#ifndef LLVM_SUPPORT_ARMEHABI_H +#define LLVM_SUPPORT_ARMEHABI_H namespace llvm { namespace ARM { @@ -131,4 +131,4 @@ namespace EHABI { } } -#endif // ARM_UNWIND_OP_H +#endif diff --git a/include/llvm/Support/ARMWinEH.h b/include/llvm/Support/ARMWinEH.h index 78deb8d..1463629 100644 --- a/include/llvm/Support/ARMWinEH.h +++ b/include/llvm/Support/ARMWinEH.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_WINARMEH_H -#define LLVM_SUPPORT_WINARMEH_H +#ifndef LLVM_SUPPORT_ARMWINEH_H +#define LLVM_SUPPORT_ARMWINEH_H #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Endian.h" @@ -350,16 +350,15 @@ struct ExceptionDataRecord { ArrayRef<support::ulittle32_t> EpilogueScopes() const { assert(E() == 0 && "epilogue scopes are only present when the E bit is 0"); size_t Offset = HeaderWords(*this); - return ArrayRef<support::ulittle32_t>(&Data[Offset], EpilogueCount()); + return makeArrayRef(&Data[Offset], EpilogueCount()); } - ArrayRef<support::ulittle8_t> UnwindByteCode() const { + ArrayRef<uint8_t> UnwindByteCode() const { const size_t Offset = HeaderWords(*this) + (E() ? 0 : EpilogueCount()); - const support::ulittle8_t *ByteCode = - reinterpret_cast<const support::ulittle8_t *>(&Data[Offset]); - return ArrayRef<support::ulittle8_t>(ByteCode, - CodeWords() * sizeof(uint32_t)); + const uint8_t *ByteCode = + reinterpret_cast<const uint8_t *>(&Data[Offset]); + return makeArrayRef(ByteCode, CodeWords() * sizeof(uint32_t)); } uint32_t ExceptionHandlerRVA() const { @@ -381,4 +380,3 @@ inline size_t HeaderWords(const ExceptionDataRecord &XR) { } #endif - diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index 7a7e4c0..de31771 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -90,7 +90,10 @@ class MallocAllocator : public AllocatorBase<MallocAllocator> { public: void Reset() {} - void *Allocate(size_t Size, size_t /*Alignment*/) { return malloc(Size); } + LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, + size_t /*Alignment*/) { + return malloc(Size); + } // Pull in base class overloads. using AllocatorBase<MallocAllocator>::Allocate; @@ -116,8 +119,8 @@ void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated, /// \brief Allocate memory in an ever growing pool, as if by bump-pointer. /// /// This isn't strictly a bump-pointer allocator as it uses backing slabs of -/// memory rather than relying on boundless contiguous heap. However, it has -/// bump-pointer semantics in that is a monotonically growing pool of memory +/// memory rather than relying on a boundless contiguous heap. However, it has +/// bump-pointer semantics in that it is a monotonically growing pool of memory /// where every allocation is found by merely allocating the next N bytes in /// the slab, or the next N bytes in the next slab. /// @@ -200,28 +203,24 @@ public: } /// \brief Allocate space at the specified alignment. - void *Allocate(size_t Size, size_t Alignment) { - if (!CurPtr) // Start a new slab if we haven't allocated one already. - StartNewSlab(); + LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) { + assert(Alignment > 0 && "0-byte alignnment is not allowed. Use 1 instead."); // Keep track of how many bytes we've allocated. BytesAllocated += Size; - // 0-byte alignment means 1-byte alignment. - if (Alignment == 0) - Alignment = 1; - - // Allocate the aligned space, going forwards from CurPtr. - char *Ptr = alignPtr(CurPtr, Alignment); + size_t Adjustment = alignmentAdjustment(CurPtr, Alignment); + assert(Adjustment + Size >= Size && "Adjustment + Size must not overflow"); - // Check if we can hold it. - if (Ptr + Size <= End) { - CurPtr = Ptr + Size; + // Check if we have enough space. + if (Adjustment + Size <= size_t(End - CurPtr)) { + char *AlignedPtr = CurPtr + Adjustment; + CurPtr = AlignedPtr + Size; // Update the allocation point of this memory block in MemorySanitizer. // Without this, MemorySanitizer messages for values originated from here // will point to the allocation of the entire slab. - __msan_allocated_memory(Ptr, Size); - return Ptr; + __msan_allocated_memory(AlignedPtr, Size); + return AlignedPtr; } // If Size is really big, allocate a separate slab for it. @@ -230,19 +229,22 @@ public: void *NewSlab = Allocator.Allocate(PaddedSize, 0); CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize)); - Ptr = alignPtr((char *)NewSlab, Alignment); - assert((uintptr_t)Ptr + Size <= (uintptr_t)NewSlab + PaddedSize); - __msan_allocated_memory(Ptr, Size); - return Ptr; + uintptr_t AlignedAddr = alignAddr(NewSlab, Alignment); + assert(AlignedAddr + Size <= (uintptr_t)NewSlab + PaddedSize); + char *AlignedPtr = (char*)AlignedAddr; + __msan_allocated_memory(AlignedPtr, Size); + return AlignedPtr; } // Otherwise, start a new slab and try again. StartNewSlab(); - Ptr = alignPtr(CurPtr, Alignment); - CurPtr = Ptr + Size; - assert(CurPtr <= End && "Unable to allocate memory!"); - __msan_allocated_memory(Ptr, Size); - return Ptr; + uintptr_t AlignedAddr = alignAddr(CurPtr, Alignment); + assert(AlignedAddr + Size <= (uintptr_t)End && + "Unable to allocate memory!"); + char *AlignedPtr = (char*)AlignedAddr; + CurPtr = AlignedPtr + Size; + __msan_allocated_memory(AlignedPtr, Size); + return AlignedPtr; } // Pull in base class overloads. @@ -320,8 +322,10 @@ private: #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(*I, AllocatedSlabSize); - memset(*I, 0xCD, AllocatedSlabSize); + if (AllocatedSlabSize != 0) { + sys::Memory::setRangeWritable(*I, AllocatedSlabSize); + memset(*I, 0xCD, AllocatedSlabSize); + } #endif Allocator.Deallocate(*I, AllocatedSlabSize); } @@ -373,7 +377,7 @@ public: /// all memory allocated so far. void DestroyAll() { auto DestroyElements = [](char *Begin, char *End) { - assert(Begin == alignPtr(Begin, alignOf<T>())); + assert(Begin == (char*)alignAddr(Begin, alignOf<T>())); for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T)) reinterpret_cast<T *>(Ptr)->~T(); }; @@ -382,7 +386,7 @@ public: ++I) { size_t AllocatedSlabSize = BumpPtrAllocator::computeSlabSize( std::distance(Allocator.Slabs.begin(), I)); - char *Begin = alignPtr((char *)*I, alignOf<T>()); + char *Begin = (char*)alignAddr(*I, alignOf<T>()); char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr : (char *)*I + AllocatedSlabSize; @@ -392,7 +396,7 @@ public: for (auto &PtrAndSize : Allocator.CustomSizedSlabs) { void *Ptr = PtrAndSize.first; size_t Size = PtrAndSize.second; - DestroyElements(alignPtr((char *)Ptr, alignOf<T>()), (char *)Ptr + Size); + DestroyElements((char*)alignAddr(Ptr, alignOf<T>()), (char *)Ptr + Size); } Allocator.Reset(); diff --git a/include/llvm/Support/CBindingWrapping.h b/include/llvm/Support/CBindingWrapping.h index 51097b8..786ba18 100644 --- a/include/llvm/Support/CBindingWrapping.h +++ b/include/llvm/Support/CBindingWrapping.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_C_BINDING_WRAPPING_H -#define LLVM_C_BINDING_WRAPPING_H +#ifndef LLVM_SUPPORT_CBINDINGWRAPPING_H +#define LLVM_SUPPORT_CBINDINGWRAPPING_H #include "llvm/Support/Casting.h" diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index e09ef07..150bce5 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -31,23 +31,30 @@ namespace llvm { namespace COFF { // The maximum number of sections that a COFF object can have (inclusive). - const int MaxNumberOfSections = 65299; + const int32_t MaxNumberOfSections16 = 65279; // The PE signature bytes that follows the DOS stub header. static const char PEMagic[] = { 'P', 'E', '\0', '\0' }; + static const char BigObjMagic[] = { + '\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b', + '\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8', + }; + // Sizes in bytes of various things in the COFF format. enum { - HeaderSize = 20, + Header16Size = 20, + Header32Size = 56, NameSize = 8, - SymbolSize = 18, + Symbol16Size = 18, + Symbol32Size = 20, SectionSize = 40, RelocationSize = 10 }; struct header { uint16_t Machine; - uint16_t NumberOfSections; + int32_t NumberOfSections; uint32_t TimeDateStamp; uint32_t PointerToSymbolTable; uint32_t NumberOfSymbols; @@ -55,6 +62,24 @@ namespace COFF { uint16_t Characteristics; }; + struct BigObjHeader { + enum : uint16_t { MinBigObjectVersion = 2 }; + + uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0). + uint16_t Sig2; ///< Must be 0xFFFF. + uint16_t Version; + uint16_t Machine; + uint32_t TimeDateStamp; + uint8_t UUID[16]; + uint32_t unused1; + uint32_t unused2; + uint32_t unused3; + uint32_t unused4; + uint32_t NumberOfSections; + uint32_t PointerToSymbolTable; + uint32_t NumberOfSymbols; + }; + enum MachineTypes { MT_Invalid = 0xffff, @@ -124,7 +149,7 @@ namespace COFF { struct symbol { char Name[NameSize]; uint32_t Value; - uint16_t SectionNumber; + int32_t SectionNumber; uint16_t Type; uint8_t StorageClass; uint8_t NumberOfAuxSymbols; @@ -140,9 +165,9 @@ namespace COFF { SF_WeakExternal = 0x01000000 }; - enum SymbolSectionNumber { - IMAGE_SYM_DEBUG = 0xFFFE, - IMAGE_SYM_ABSOLUTE = 0xFFFF, + enum SymbolSectionNumber : int32_t { + IMAGE_SYM_DEBUG = -2, + IMAGE_SYM_ABSOLUTE = -1, IMAGE_SYM_UNDEFINED = 0 }; @@ -367,18 +392,14 @@ namespace COFF { IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3 }; - struct AuxiliaryFile { - uint8_t FileName[18]; - }; - struct AuxiliarySectionDefinition { uint32_t Length; uint16_t NumberOfRelocations; uint16_t NumberOfLinenumbers; uint32_t CheckSum; - uint16_t Number; + uint32_t Number; uint8_t Selection; - char unused[3]; + char unused; }; struct AuxiliaryCLRToken { @@ -392,7 +413,6 @@ namespace COFF { AuxiliaryFunctionDefinition FunctionDefinition; AuxiliarybfAndefSymbol bfAndefSymbol; AuxiliaryWeakExternal WeakExternal; - AuxiliaryFile File; AuxiliarySectionDefinition SectionDefinition; }; @@ -495,12 +515,14 @@ namespace COFF { uint32_t SizeOfHeaders; uint32_t CheckSum; uint16_t Subsystem; + // FIXME: This should be DllCharacteristics to match the COFF spec. uint16_t DLLCharacteristics; uint32_t SizeOfStackReserve; uint32_t SizeOfStackCommit; uint32_t SizeOfHeapReserve; uint32_t SizeOfHeapCommit; uint32_t LoaderFlags; + // FIXME: This should be NumberOfRvaAndSizes to match the COFF spec. uint32_t NumberOfRvaAndSize; }; @@ -524,7 +546,9 @@ namespace COFF { BOUND_IMPORT, IAT, DELAY_IMPORT_DESCRIPTOR, - CLR_RUNTIME_HEADER + CLR_RUNTIME_HEADER, + + NUM_DATA_DIRECTORIES }; enum WindowsSubsystem { @@ -642,13 +666,18 @@ namespace COFF { enum CodeViewLineTableIdentifiers { DEBUG_SECTION_MAGIC = 0x4, + DEBUG_SYMBOL_SUBSECTION = 0xF1, DEBUG_LINE_TABLE_SUBSECTION = 0xF2, DEBUG_STRING_TABLE_SUBSECTION = 0xF3, - DEBUG_INDEX_SUBSECTION = 0xF4 + DEBUG_INDEX_SUBSECTION = 0xF4, + + // Symbol subsections are split into records of different types. + DEBUG_SYMBOL_TYPE_PROC_START = 0x1147, + DEBUG_SYMBOL_TYPE_PROC_END = 0x114F }; - inline bool isReservedSectionNumber(int N) { - return N == IMAGE_SYM_UNDEFINED || N > MaxNumberOfSections; + inline bool isReservedSectionNumber(int32_t SectionNumber) { + return SectionNumber <= 0; } } // End namespace COFF. diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h index 240eba6..243f2dd 100644 --- a/include/llvm/Support/CodeGen.h +++ b/include/llvm/Support/CodeGen.h @@ -30,6 +30,10 @@ namespace llvm { enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; } + namespace PICLevel { + enum Level { Default=0, Small=1, Large=2 }; + } + // TLS models. namespace TLSModel { enum Model { diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index 5cb5501..2b5c9c5 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -270,8 +270,8 @@ public: // addOccurrence - Wrapper around handleOccurrence that enforces Flags. // - bool addOccurrence(unsigned pos, StringRef ArgName, - StringRef Value, bool MultiArg = false); + virtual bool addOccurrence(unsigned pos, StringRef ArgName, + StringRef Value, bool MultiArg = false); // Prints option name followed by message. Always returns true. bool error(const Twine &Message, StringRef ArgName = StringRef()); @@ -513,9 +513,9 @@ public: } }; -template<class DataType> -ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val, - const char *Desc, ...) { +template <class DataType> +ValuesClass<DataType> LLVM_END_WITH_NULL +values(const char *Arg, DataType Val, const char *Desc, ...) { va_list ValueArgs; va_start(ValueArgs, Desc); ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs); @@ -1649,6 +1649,10 @@ class alias : public Option { StringRef Arg) override { return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg); } + bool addOccurrence(unsigned pos, StringRef /*ArgName*/, + StringRef Value, bool MultiArg = false) override { + return AliasFor->addOccurrence(pos, AliasFor->ArgStr, Value, MultiArg); + } // Handle printing stuff... size_t getOptionWidth() const override; void printOptionInfo(size_t GlobalWidth) const override; @@ -1786,9 +1790,12 @@ public: /// /// \param [in] Source The string to be split on whitespace with quotes. /// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [in] MarkEOLs true if tokenizing a response file and you want end of +/// lines and end of the response file to be marked with a nullptr string. /// \param [out] NewArgv All parsed strings are appended to NewArgv. void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, - SmallVectorImpl<const char *> &NewArgv); + SmallVectorImpl<const char *> &NewArgv, + bool MarkEOLs = false); /// \brief Tokenizes a Windows command line which may contain quotes and escaped /// quotes. @@ -1798,25 +1805,36 @@ void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver, /// /// \param [in] Source The string to be split on whitespace with quotes. /// \param [in] Saver Delegates back to the caller for saving parsed strings. +/// \param [in] MarkEOLs true if tokenizing a response file and you want end of +/// lines and end of the response file to be marked with a nullptr string. /// \param [out] NewArgv All parsed strings are appended to NewArgv. void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver, - SmallVectorImpl<const char *> &NewArgv); + SmallVectorImpl<const char *> &NewArgv, + bool MarkEOLs = false); /// \brief String tokenization function type. Should be compatible with either /// Windows or Unix command line tokenizers. typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver, - SmallVectorImpl<const char *> &NewArgv); + SmallVectorImpl<const char *> &NewArgv, + bool MarkEOLs); /// \brief Expand response files on a command line recursively using the given /// StringSaver and tokenization strategy. Argv should contain the command line -/// before expansion and will be modified in place. +/// before expansion and will be modified in place. If requested, Argv will +/// also be populated with nullptrs indicating where each response file line +/// ends, which is useful for the "/link" argument that needs to consume all +/// remaining arguments only until the next end of line, when in a response +/// file. /// /// \param [in] Saver Delegates back to the caller for saving parsed strings. /// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows. /// \param [in,out] Argv Command line into which to expand response files. +/// \param [in] MarkEOLs Mark end of lines and the end of the response file +/// with nullptrs in the Argv vector. /// \return true if all @files were expanded successfully or there were none. bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, - SmallVectorImpl<const char *> &Argv); + SmallVectorImpl<const char *> &Argv, + bool MarkEOLs = false); } // End namespace cl diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h index 25bf32a..d008fec 100644 --- a/include/llvm/Support/Compiler.h +++ b/include/llvm/Support/Compiler.h @@ -33,14 +33,19 @@ # define __has_builtin(x) 0 #endif -/// \macro __GNUC_PREREQ -/// \brief Defines __GNUC_PREREQ if glibc's features.h isn't available. -#ifndef __GNUC_PREREQ -# if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define __GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +/// \macro LLVM_GNUC_PREREQ +/// \brief Extend the default __GNUC_PREREQ even if glibc's features.h isn't +/// available. +#ifndef LLVM_GNUC_PREREQ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) + __GNUC_PATCHLEVEL__ >= \ + ((maj) << 20) + ((min) << 10) + (patch)) +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) +# define LLVM_GNUC_PREREQ(maj, min, patch) \ + ((__GNUC__ << 20) + (__GNUC_MINOR__ << 10) >= ((maj) << 20) + ((min) << 10)) # else -# define __GNUC_PREREQ(maj, min) 0 +# define LLVM_GNUC_PREREQ(maj, min, patch) 0 # endif #endif @@ -61,7 +66,7 @@ #define LLVM_MSC_PREREQ(version) 0 #endif -#ifndef _MSC_VER +#if !defined(_MSC_VER) || defined(__clang__) || LLVM_MSC_PREREQ(1900) #define LLVM_NOEXCEPT noexcept #else #define LLVM_NOEXCEPT @@ -70,10 +75,8 @@ /// \brief Does the compiler support r-value reference *this? /// /// Sadly, this is separate from just r-value reference support because GCC -/// implemented everything but this thus far. No release of GCC yet has support -/// for this feature so it is enabled with Clang only. -/// FIXME: This should change to a version check when GCC grows support for it. -#if __has_feature(cxx_rvalue_references) +/// implemented this later than everything else. +#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1) #define LLVM_HAS_RVALUE_REFERENCE_THIS 1 #else #define LLVM_HAS_RVALUE_REFERENCE_THIS 0 @@ -128,20 +131,26 @@ /// not accessible from outside it. Can also be used to mark variables and /// functions, making them private to any shared library they are linked into. /// On PE/COFF targets, library visibility is the default, so this isn't needed. -#if (__has_attribute(visibility) || __GNUC_PREREQ(4, 0)) && \ +#if (__has_attribute(visibility) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32) #define LLVM_LIBRARY_VISIBILITY __attribute__ ((visibility("hidden"))) #else #define LLVM_LIBRARY_VISIBILITY #endif -#if __has_attribute(used) || __GNUC_PREREQ(3, 1) +#if __has_attribute(sentinel) || LLVM_GNUC_PREREQ(3, 0, 0) +#define LLVM_END_WITH_NULL __attribute__((sentinel)) +#else +#define LLVM_END_WITH_NULL +#endif + +#if __has_attribute(used) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_USED __attribute__((__used__)) #else #define LLVM_ATTRIBUTE_USED #endif -#if __has_attribute(warn_unused_result) || __GNUC_PREREQ(3, 4) +#if __has_attribute(warn_unused_result) || LLVM_GNUC_PREREQ(3, 4, 0) #define LLVM_ATTRIBUTE_UNUSED_RESULT __attribute__((__warn_unused_result__)) #else #define LLVM_ATTRIBUTE_UNUSED_RESULT @@ -155,14 +164,14 @@ // more portable solution: // (void)unused_var_name; // Prefer cast-to-void wherever it is sufficient. -#if __has_attribute(unused) || __GNUC_PREREQ(3, 1) +#if __has_attribute(unused) || LLVM_GNUC_PREREQ(3, 1, 0) #define LLVM_ATTRIBUTE_UNUSED __attribute__((__unused__)) #else #define LLVM_ATTRIBUTE_UNUSED #endif // FIXME: Provide this for PE/COFF targets. -#if (__has_attribute(weak) || __GNUC_PREREQ(4, 0)) && \ +#if (__has_attribute(weak) || LLVM_GNUC_PREREQ(4, 0, 0)) && \ (!defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(LLVM_ON_WIN32)) #define LLVM_ATTRIBUTE_WEAK __attribute__((__weak__)) #else @@ -185,7 +194,7 @@ #define LLVM_READONLY #endif -#if __has_builtin(__builtin_expect) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_expect) || LLVM_GNUC_PREREQ(4, 0, 0) #define LLVM_LIKELY(EXPR) __builtin_expect((bool)(EXPR), true) #define LLVM_UNLIKELY(EXPR) __builtin_expect((bool)(EXPR), false) #else @@ -208,7 +217,7 @@ /// LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, /// mark a method "not for inlining". -#if __has_attribute(noinline) || __GNUC_PREREQ(3, 4) +#if __has_attribute(noinline) || LLVM_GNUC_PREREQ(3, 4, 0) #define LLVM_ATTRIBUTE_NOINLINE __attribute__((noinline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_NOINLINE __declspec(noinline) @@ -220,7 +229,7 @@ /// so, mark a method "always inline" because it is performance sensitive. GCC /// 3.4 supported this but is buggy in various cases and produces unimplemented /// errors, just use it in GCC 4.0 and later. -#if __has_attribute(always_inline) || __GNUC_PREREQ(4, 0) +#if __has_attribute(always_inline) || LLVM_GNUC_PREREQ(4, 0, 0) #define LLVM_ATTRIBUTE_ALWAYS_INLINE inline __attribute__((always_inline)) #elif defined(_MSC_VER) #define LLVM_ATTRIBUTE_ALWAYS_INLINE __forceinline @@ -236,6 +245,12 @@ #define LLVM_ATTRIBUTE_NORETURN #endif +#if __has_attribute(returns_nonnull) || LLVM_GNUC_PREREQ(4, 9, 0) +#define LLVM_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +#define LLVM_ATTRIBUTE_RETURNS_NONNULL +#endif + /// LLVM_EXTENSION - Support compilers where we have a keyword to suppress /// pedantic diagnostics. #ifdef __GNUC__ @@ -262,7 +277,7 @@ /// LLVM_BUILTIN_UNREACHABLE - On compilers which support it, expands /// to an expression which states that it is undefined behavior for the /// compiler to reach this point. Otherwise is not defined. -#if __has_builtin(__builtin_unreachable) || __GNUC_PREREQ(4, 5) +#if __has_builtin(__builtin_unreachable) || LLVM_GNUC_PREREQ(4, 5, 0) # define LLVM_BUILTIN_UNREACHABLE __builtin_unreachable() #elif defined(_MSC_VER) # define LLVM_BUILTIN_UNREACHABLE __assume(false) @@ -270,7 +285,7 @@ /// LLVM_BUILTIN_TRAP - On compilers which support it, expands to an expression /// which causes the program to exit abnormally. -#if __has_builtin(__builtin_trap) || __GNUC_PREREQ(4, 3) +#if __has_builtin(__builtin_trap) || LLVM_GNUC_PREREQ(4, 3, 0) # define LLVM_BUILTIN_TRAP __builtin_trap() #else # define LLVM_BUILTIN_TRAP *(volatile int*)0x11 = 0 @@ -278,7 +293,7 @@ /// \macro LLVM_ASSUME_ALIGNED /// \brief Returns a pointer with an assumed alignment. -#if __has_builtin(__builtin_assume_aligned) && __GNUC_PREREQ(4, 7) +#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0) # define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a) #elif defined(LLVM_BUILTIN_UNREACHABLE) // As of today, clang does not support __builtin_assume_aligned. diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 3869ebd..f1e636d 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -166,9 +166,7 @@ public: : CrashRecoveryContextCleanupBase< CrashRecoveryContextDeleteCleanup<T>, T>(context, resource) {} - virtual void recoverResources() { - delete this->resource; - } + void recoverResources() override { delete this->resource; } }; template <typename T> @@ -181,9 +179,7 @@ public: : CrashRecoveryContextCleanupBase<CrashRecoveryContextReleaseRefCleanup<T>, T>(context, resource) {} - virtual void recoverResources() { - this->resource->Release(); - } + void recoverResources() override { this->resource->Release(); } }; template <typename T, typename Cleanup = CrashRecoveryContextDeleteCleanup<T> > diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h index e8a19cd..48235d4 100644 --- a/include/llvm/Support/DataExtractor.h +++ b/include/llvm/Support/DataExtractor.h @@ -348,6 +348,17 @@ public: bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const { return offset + length >= offset && isValidOffset(offset + length - 1); } + + /// Test the availability of enough bytes of data for a pointer from + /// \a offset. The size of a pointer is \a getAddressSize(). + /// + /// @return + /// \b true if \a offset is a valid offset and there are enough + /// bytes for a pointer available at that offset, \b false + /// otherwise. + bool isValidOffsetForAddress(uint32_t offset) const { + return isValidOffsetForDataOfSize(offset, AddressSize); + } }; } // namespace llvm diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index 1f0c8eb..c90bf51 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -101,6 +101,13 @@ typedef signed int ssize_t; #define PRIu64 "I64u" #define PRIx64 "I64x" #define PRIX64 "I64X" + +#define PRId32 "d" +#define PRIi32 "i" +#define PRIo32 "o" +#define PRIu32 "u" +#define PRIx32 "x" +#define PRIX32 "X" #endif /* HAVE_INTTYPES_H */ #endif /* _MSC_VER */ @@ -116,12 +123,6 @@ typedef signed int ssize_t; # define UINT64_MAX 0xffffffffffffffffULL #endif -#if __GNUC__ > 3 -#define END_WITH_NULL __attribute__((sentinel)) -#else -#define END_WITH_NULL -#endif - #ifndef HUGE_VALF #define HUGE_VALF (float)HUGE_VAL #endif diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in index 09cfcdf..b8b2ba5 100644 --- a/include/llvm/Support/DataTypes.h.in +++ b/include/llvm/Support/DataTypes.h.in @@ -116,12 +116,6 @@ typedef signed int ssize_t; # define UINT64_MAX 0xffffffffffffffffULL #endif -#if __GNUC__ > 3 -#define END_WITH_NULL __attribute__((sentinel)) -#else -#define END_WITH_NULL -#endif - #ifndef HUGE_VALF #define HUGE_VALF (float)HUGE_VAL #endif diff --git a/include/llvm/Support/Disassembler.h b/include/llvm/Support/Disassembler.h deleted file mode 100644 index 6d1cc0f..0000000 --- a/include/llvm/Support/Disassembler.h +++ /dev/null @@ -1,35 +0,0 @@ -//===- llvm/Support/Disassembler.h ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the necessary glue to call external disassembler -// libraries. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SYSTEM_DISASSEMBLER_H -#define LLVM_SYSTEM_DISASSEMBLER_H - -#include "llvm/Support/DataTypes.h" -#include <string> - -namespace llvm { -namespace sys { - -/// This function returns true, if there is possible to use some external -/// disassembler library. False otherwise. -bool hasDisassembler(); - -/// This function provides some "glue" code to call external disassembler -/// libraries. -std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0); - -} -} - -#endif // LLVM_SYSTEM_DISASSEMBLER_H diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index cd9f756..47b00b1 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -7,9 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This file contains constants used for implementing Dwarf debug support. For -// Details on the Dwarf 3 specfication see DWARF Debugging Information Format -// V.3 reference manual http://dwarf.freestandards.org , +// \file +// \brief This file contains constants used for implementing Dwarf +// debug support. +// +// For details on the Dwarf specfication see the latest DWARF Debugging +// Information Format standard document on http://www.dwarfstd.org. This +// file often includes support for non-released standard features. // //===----------------------------------------------------------------------===// @@ -21,22 +25,6 @@ namespace llvm { -//===----------------------------------------------------------------------===// -// Debug info constants. - -enum : uint32_t { - LLVMDebugVersion = (12 << 16), // Current version of debug information. - LLVMDebugVersion11 = (11 << 16), // Constant for version 11. - LLVMDebugVersion10 = (10 << 16), // Constant for version 10. - LLVMDebugVersion9 = (9 << 16), // Constant for version 9. - LLVMDebugVersion8 = (8 << 16), // Constant for version 8. - LLVMDebugVersion7 = (7 << 16), // Constant for version 7. - LLVMDebugVersion6 = (6 << 16), // Constant for version 6. - LLVMDebugVersion5 = (5 << 16), // Constant for version 5. - LLVMDebugVersion4 = (4 << 16), // Constant for version 4. - LLVMDebugVersionMask = 0xffff0000 // Mask for version number. -}; - namespace dwarf { //===----------------------------------------------------------------------===// @@ -53,6 +41,7 @@ enum LLVMConstants : uint32_t { DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables. DW_TAG_arg_variable = 0x101, // Tag for argument variables. + DW_TAG_expression = 0x102, // Tag for complex address expressions. DW_TAG_user_base = 0x1000, // Recommended base for user tags. @@ -779,100 +768,24 @@ enum LocationListEntry : unsigned char { DW_LLE_offset_pair_entry }; +/// Contstants for the DW_APPLE_PROPERTY_attributes attribute. +/// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind. enum ApplePropertyAttributes { // Apple Objective-C Property Attributes DW_APPLE_PROPERTY_readonly = 0x01, - DW_APPLE_PROPERTY_readwrite = 0x02, + DW_APPLE_PROPERTY_getter = 0x02, DW_APPLE_PROPERTY_assign = 0x04, - DW_APPLE_PROPERTY_retain = 0x08, - DW_APPLE_PROPERTY_copy = 0x10, - DW_APPLE_PROPERTY_nonatomic = 0x20 + DW_APPLE_PROPERTY_readwrite = 0x08, + DW_APPLE_PROPERTY_retain = 0x10, + DW_APPLE_PROPERTY_copy = 0x20, + DW_APPLE_PROPERTY_nonatomic = 0x40, + DW_APPLE_PROPERTY_setter = 0x80, + DW_APPLE_PROPERTY_atomic = 0x100, + DW_APPLE_PROPERTY_weak = 0x200, + DW_APPLE_PROPERTY_strong = 0x400, + DW_APPLE_PROPERTY_unsafe_unretained = 0x800 }; -/// TagString - Return the string for the specified tag. -/// -const char *TagString(unsigned Tag); - -/// ChildrenString - Return the string for the specified children flag. -/// -const char *ChildrenString(unsigned Children); - -/// AttributeString - Return the string for the specified attribute. -/// -const char *AttributeString(unsigned Attribute); - -/// FormEncodingString - Return the string for the specified form encoding. -/// -const char *FormEncodingString(unsigned Encoding); - -/// OperationEncodingString - Return the string for the specified operation -/// encoding. -const char *OperationEncodingString(unsigned Encoding); - -/// AttributeEncodingString - Return the string for the specified attribute -/// encoding. -const char *AttributeEncodingString(unsigned Encoding); - -/// DecimalSignString - Return the string for the specified decimal sign -/// attribute. -const char *DecimalSignString(unsigned Sign); - -/// EndianityString - Return the string for the specified endianity. -/// -const char *EndianityString(unsigned Endian); - -/// AccessibilityString - Return the string for the specified accessibility. -/// -const char *AccessibilityString(unsigned Access); - -/// VisibilityString - Return the string for the specified visibility. -/// -const char *VisibilityString(unsigned Visibility); - -/// VirtualityString - Return the string for the specified virtuality. -/// -const char *VirtualityString(unsigned Virtuality); - -/// LanguageString - Return the string for the specified language. -/// -const char *LanguageString(unsigned Language); - -/// CaseString - Return the string for the specified identifier case. -/// -const char *CaseString(unsigned Case); - -/// ConventionString - Return the string for the specified calling convention. -/// -const char *ConventionString(unsigned Convention); - -/// InlineCodeString - Return the string for the specified inline code. -/// -const char *InlineCodeString(unsigned Code); - -/// ArrayOrderString - Return the string for the specified array order. -/// -const char *ArrayOrderString(unsigned Order); - -/// DiscriminantString - Return the string for the specified discriminant -/// descriptor. -const char *DiscriminantString(unsigned Discriminant); - -/// LNStandardString - Return the string for the specified line number standard. -/// -const char *LNStandardString(unsigned Standard); - -/// LNExtendedString - Return the string for the specified line number extended -/// opcode encodings. -const char *LNExtendedString(unsigned Encoding); - -/// MacinfoString - Return the string for the specified macinfo type encodings. -/// -const char *MacinfoString(unsigned Encoding); - -/// CallFrameString - Return the string for the specified call frame instruction -/// encodings. -const char *CallFrameString(unsigned Encoding); - // Constants for the DWARF5 Accelerator Table Proposal enum AcceleratorTable { // Data layout descriptors. @@ -895,9 +808,6 @@ enum AcceleratorTable { DW_hash_function_djb = 0u }; -/// AtomTypeString - Return the string for the specified Atom type. -const char *AtomTypeString(unsigned Atom); - // Constants for the GNU pubnames/pubtypes extensions supporting gdb index. enum GDBIndexEntryKind { GIEK_NONE, @@ -910,15 +820,51 @@ enum GDBIndexEntryKind { GIEK_UNUSED7 }; -const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind); - enum GDBIndexEntryLinkage { GIEL_EXTERNAL, GIEL_STATIC }; +/// \defgroup DwarfConstantsDumping Dwarf constants dumping functions +/// +/// All these functions map their argument's value back to the +/// corresponding enumerator name or return nullptr if the value isn't +/// known. +/// +/// @{ +const char *TagString(unsigned Tag); +const char *ChildrenString(unsigned Children); +const char *AttributeString(unsigned Attribute); +const char *FormEncodingString(unsigned Encoding); +const char *OperationEncodingString(unsigned Encoding); +const char *AttributeEncodingString(unsigned Encoding); +const char *DecimalSignString(unsigned Sign); +const char *EndianityString(unsigned Endian); +const char *AccessibilityString(unsigned Access); +const char *VisibilityString(unsigned Visibility); +const char *VirtualityString(unsigned Virtuality); +const char *LanguageString(unsigned Language); +const char *CaseString(unsigned Case); +const char *ConventionString(unsigned Convention); +const char *InlineCodeString(unsigned Code); +const char *ArrayOrderString(unsigned Order); +const char *DiscriminantString(unsigned Discriminant); +const char *LNStandardString(unsigned Standard); +const char *LNExtendedString(unsigned Encoding); +const char *MacinfoString(unsigned Encoding); +const char *CallFrameString(unsigned Encoding); +const char *ApplePropertyString(unsigned); +const char *AtomTypeString(unsigned Atom); +const char *GDBIndexEntryKindString(GDBIndexEntryKind Kind); const char *GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage); +/// @} +/// \brief Returns the symbolic string representing Val when used as a value +/// for attribute Attr. +const char *AttributeValueString(uint16_t Attr, unsigned Val); + +/// \brief Decsribes an entry of the various gnu_pub* debug sections. +/// /// The gnu_pub* kind looks like: /// /// 0-3 reserved @@ -950,6 +896,7 @@ private: }; }; + } // End of namespace dwarf } // End of namespace llvm diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h index de47be6..a7d2221 100644 --- a/include/llvm/Support/DynamicLibrary.h +++ b/include/llvm/Support/DynamicLibrary.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H -#define LLVM_SYSTEM_DYNAMICLIBRARY_H +#ifndef LLVM_SUPPORT_DYNAMICLIBRARY_H +#define LLVM_SUPPORT_DYNAMICLIBRARY_H #include <string> @@ -43,10 +43,11 @@ namespace sys { // Opaque data used to interface with OS-specific dynamic library handling. void *Data; - explicit DynamicLibrary(void *data = &Invalid) : Data(data) {} public: + explicit DynamicLibrary(void *data = &Invalid) : Data(data) {} + /// Returns true if the object refers to a valid library. - bool isValid() { return Data != &Invalid; } + bool isValid() const { return Data != &Invalid; } /// Searches through the library for the symbol \p symbolName. If it is /// found, the address of that symbol is returned. If not, NULL is returned. @@ -101,4 +102,4 @@ namespace sys { } // End sys namespace } // End llvm namespace -#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H +#endif diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 67cc651..5f78cc2 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -458,6 +458,9 @@ enum { R_PPC_GOT16_LO = 15, R_PPC_GOT16_HI = 16, R_PPC_GOT16_HA = 17, + R_PPC_PLTREL24 = 18, + R_PPC_JMP_SLOT = 21, + R_PPC_LOCAL24PC = 23, R_PPC_REL32 = 26, R_PPC_TLS = 67, R_PPC_DTPMOD32 = 68, @@ -495,6 +498,37 @@ enum { R_PPC_REL16_HA = 252 }; +// Specific e_flags for PPC64 +enum { + // e_flags bits specifying ABI: + // 1 for original ABI using function descriptors, + // 2 for revised ABI without function descriptors, + // 0 for unspecified or not using any features affected by the differences. + EF_PPC64_ABI = 3 +}; + +// Special values for the st_other field in the symbol table entry for PPC64. +enum { + STO_PPC64_LOCAL_BIT = 5, + STO_PPC64_LOCAL_MASK = (7 << STO_PPC64_LOCAL_BIT) +}; +static inline int64_t +decodePPC64LocalEntryOffset(unsigned Other) { + unsigned Val = (Other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT; + return ((1 << Val) >> 2) << 2; +} +static inline unsigned +encodePPC64LocalEntryOffset(int64_t Offset) { + unsigned Val = (Offset >= 4 * 4 + ? (Offset >= 8 * 4 + ? (Offset >= 16 * 4 ? 6 : 5) + : 4) + : (Offset >= 2 * 4 + ? 3 + : (Offset >= 1 * 4 ? 2 : 0))); + return Val << STO_PPC64_LOCAL_BIT; +} + // ELF Relocation types for PPC64 enum { R_PPC64_NONE = 0, @@ -515,6 +549,7 @@ enum { R_PPC64_GOT16_LO = 15, R_PPC64_GOT16_HI = 16, R_PPC64_GOT16_HA = 17, + R_PPC64_JMP_SLOT = 21, R_PPC64_REL32 = 26, R_PPC64_ADDR64 = 38, R_PPC64_ADDR16_HIGHER = 39, @@ -621,6 +656,9 @@ enum { R_AARCH64_LDST128_ABS_LO12_NC = 0x12b, + R_AARCH64_GOTREL64 = 0x133, + R_AARCH64_GOTREL32 = 0x134, + R_AARCH64_ADR_GOT_PAGE = 0x137, R_AARCH64_LD64_GOT_LO12_NC = 0x138, @@ -668,7 +706,17 @@ enum { R_AARCH64_TLSDESC_LD64_LO12_NC = 0x233, R_AARCH64_TLSDESC_ADD_LO12_NC = 0x234, - R_AARCH64_TLSDESC_CALL = 0x239 + R_AARCH64_TLSDESC_CALL = 0x239, + + R_AARCH64_COPY = 0x400, + R_AARCH64_GLOB_DAT = 0x401, + R_AARCH64_JUMP_SLOT = 0x402, + R_AARCH64_RELATIVE = 0x403, + R_AARCH64_TLS_DTPREL64 = 0x404, + R_AARCH64_TLS_DTPMOD64 = 0x405, + R_AARCH64_TLS_TPREL64 = 0x406, + R_AARCH64_TLSDESC = 0x407, + R_AARCH64_IRELATIVE = 0x408 }; // ARM Specific e_flags @@ -829,7 +877,13 @@ enum : unsigned { EF_MIPS_ABI2 = 0x00000020, EF_MIPS_32BITMODE = 0x00000100, EF_MIPS_NAN2008 = 0x00000400, // Uses IEE 754-2008 NaN encoding + + // ABI flags EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI + EF_MIPS_ABI_O64 = 0x00002000, // O32 ABI extended for 64-bit architecture. + EF_MIPS_ABI_EABI32 = 0x00003000, // EABI in 32 bit mode. + EF_MIPS_ABI_EABI64 = 0x00004000, // EABI in 64 bit mode. + EF_MIPS_ABI = 0x0000f000, // Mask for selecting EF_MIPS_ABI_ variant. //ARCH_ASE EF_MIPS_MICROMIPS = 0x02000000, // microMIPS diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h index 455d0fc..47b82fd 100644 --- a/include/llvm/Support/Endian.h +++ b/include/llvm/Support/Endian.h @@ -93,15 +93,40 @@ struct packed_endian_specific_integral { (void*)Value.buffer, newValue); } + packed_endian_specific_integral &operator+=(value_type newValue) { + *this = *this + newValue; + return *this; + } + + packed_endian_specific_integral &operator-=(value_type newValue) { + *this = *this - newValue; + return *this; + } + private: AlignedCharArray<PickAlignment<value_type, alignment>::value, sizeof(value_type)> Value; + +public: + struct ref { + explicit ref(void *Ptr) : Ptr(Ptr) {} + + operator value_type() const { + return endian::read<value_type, endian, alignment>(Ptr); + } + + void operator=(value_type NewValue) { + endian::write<value_type, endian, alignment>(Ptr, NewValue); + } + + private: + void *Ptr; + }; }; + } // end namespace detail typedef detail::packed_endian_specific_integral - <uint8_t, little, unaligned> ulittle8_t; -typedef detail::packed_endian_specific_integral <uint16_t, little, unaligned> ulittle16_t; typedef detail::packed_endian_specific_integral <uint32_t, little, unaligned> ulittle32_t; @@ -109,8 +134,6 @@ typedef detail::packed_endian_specific_integral <uint64_t, little, unaligned> ulittle64_t; typedef detail::packed_endian_specific_integral - <int8_t, little, unaligned> little8_t; -typedef detail::packed_endian_specific_integral <int16_t, little, unaligned> little16_t; typedef detail::packed_endian_specific_integral <int32_t, little, unaligned> little32_t; @@ -118,8 +141,6 @@ typedef detail::packed_endian_specific_integral <int64_t, little, unaligned> little64_t; typedef detail::packed_endian_specific_integral - <uint8_t, little, aligned> aligned_ulittle8_t; -typedef detail::packed_endian_specific_integral <uint16_t, little, aligned> aligned_ulittle16_t; typedef detail::packed_endian_specific_integral <uint32_t, little, aligned> aligned_ulittle32_t; @@ -127,8 +148,6 @@ typedef detail::packed_endian_specific_integral <uint64_t, little, aligned> aligned_ulittle64_t; typedef detail::packed_endian_specific_integral - <int8_t, little, aligned> aligned_little8_t; -typedef detail::packed_endian_specific_integral <int16_t, little, aligned> aligned_little16_t; typedef detail::packed_endian_specific_integral <int32_t, little, aligned> aligned_little32_t; @@ -136,8 +155,6 @@ typedef detail::packed_endian_specific_integral <int64_t, little, aligned> aligned_little64_t; typedef detail::packed_endian_specific_integral - <uint8_t, big, unaligned> ubig8_t; -typedef detail::packed_endian_specific_integral <uint16_t, big, unaligned> ubig16_t; typedef detail::packed_endian_specific_integral <uint32_t, big, unaligned> ubig32_t; @@ -145,8 +162,6 @@ typedef detail::packed_endian_specific_integral <uint64_t, big, unaligned> ubig64_t; typedef detail::packed_endian_specific_integral - <int8_t, big, unaligned> big8_t; -typedef detail::packed_endian_specific_integral <int16_t, big, unaligned> big16_t; typedef detail::packed_endian_specific_integral <int32_t, big, unaligned> big32_t; @@ -154,8 +169,6 @@ typedef detail::packed_endian_specific_integral <int64_t, big, unaligned> big64_t; typedef detail::packed_endian_specific_integral - <uint8_t, big, aligned> aligned_ubig8_t; -typedef detail::packed_endian_specific_integral <uint16_t, big, aligned> aligned_ubig16_t; typedef detail::packed_endian_specific_integral <uint32_t, big, aligned> aligned_ubig32_t; @@ -163,8 +176,6 @@ typedef detail::packed_endian_specific_integral <uint64_t, big, aligned> aligned_ubig64_t; typedef detail::packed_endian_specific_integral - <int8_t, big, aligned> aligned_big8_t; -typedef detail::packed_endian_specific_integral <int16_t, big, aligned> aligned_big16_t; typedef detail::packed_endian_specific_integral <int32_t, big, aligned> aligned_big32_t; diff --git a/include/llvm/Support/EndianStream.h b/include/llvm/Support/EndianStream.h index 89c66d3..94f372f 100644 --- a/include/llvm/Support/EndianStream.h +++ b/include/llvm/Support/EndianStream.h @@ -12,11 +12,11 @@ // //===----------------------------------------------------------------------===// -#ifndef _LLVM_SUPPORT_ENDIAN_STREAM_H_ -#define _LLVM_SUPPORT_ENDIAN_STREAM_H_ +#ifndef LLVM_SUPPORT_ENDIANSTREAM_H +#define LLVM_SUPPORT_ENDIANSTREAM_H -#include <llvm/Support/Endian.h> -#include <llvm/Support/raw_ostream.h> +#include "llvm/Support/Endian.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { namespace support { @@ -36,4 +36,4 @@ template <endianness endian> struct Writer { } // end namespace support } // end namespace llvm -#endif // _LLVM_SUPPORT_ENDIAN_STREAM_H_ +#endif diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index 0742a2d..84763de 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -13,8 +13,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_ERROR_OR_H -#define LLVM_SUPPORT_ERROR_OR_H +#ifndef LLVM_SUPPORT_ERROROR_H +#define LLVM_SUPPORT_ERROROR_H #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/AlignOf.h" @@ -68,9 +68,9 @@ public: /// \endcode /// /// -/// An implicit conversion to bool provides a way to check if there was an -/// error. The unary * and -> operators provide pointer like access to the -/// value. Accessing the value when there is an error has undefined behavior. +/// Implicit conversion to bool returns true if there is a usable value. The +/// unary * and -> operators provide pointer like access to the value. Accessing +/// the value when there is an error has undefined behavior. /// /// When T is a reference type the behaivor is slightly different. The reference /// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and @@ -115,19 +115,19 @@ public: } template <class OtherT> - ErrorOr(const ErrorOr<OtherT> &Other) { + ErrorOr( + const ErrorOr<OtherT> &Other, + typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = + nullptr) { copyConstruct(Other); } - ErrorOr &operator =(const ErrorOr &Other) { - copyAssign(Other); - return *this; - } - template <class OtherT> - ErrorOr &operator =(const ErrorOr<OtherT> &Other) { - copyAssign(Other); - return *this; + explicit ErrorOr( + const ErrorOr<OtherT> &Other, + typename std::enable_if< + !std::is_convertible<OtherT, const T &>::value>::type * = nullptr) { + copyConstruct(Other); } ErrorOr(ErrorOr &&Other) { @@ -135,17 +135,29 @@ public: } template <class OtherT> - ErrorOr(ErrorOr<OtherT> &&Other) { + ErrorOr( + ErrorOr<OtherT> &&Other, + typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * = + nullptr) { moveConstruct(std::move(Other)); } - ErrorOr &operator =(ErrorOr &&Other) { - moveAssign(std::move(Other)); + // This might eventually need SFINAE but it's more complex than is_convertible + // & I'm too lazy to write it right now. + template <class OtherT> + explicit ErrorOr( + ErrorOr<OtherT> &&Other, + typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * = + nullptr) { + moveConstruct(std::move(Other)); + } + + ErrorOr &operator=(const ErrorOr &Other) { + copyAssign(Other); return *this; } - template <class OtherT> - ErrorOr &operator =(ErrorOr<OtherT> &&Other) { + ErrorOr &operator=(ErrorOr &&Other) { moveAssign(std::move(Other)); return *this; } @@ -161,7 +173,7 @@ public: } reference get() { return *getStorage(); } - const_reference get() const { return const_cast<ErrorOr<T> >(this)->get(); } + const_reference get() const { return const_cast<ErrorOr<T> *>(this)->get(); } std::error_code getError() const { return HasError ? *getErrorStorage() : std::error_code(); diff --git a/include/llvm/Support/FileOutputBuffer.h b/include/llvm/Support/FileOutputBuffer.h index 0a9a979..a7cfacd 100644 --- a/include/llvm/Support/FileOutputBuffer.h +++ b/include/llvm/Support/FileOutputBuffer.h @@ -77,7 +77,7 @@ private: FileOutputBuffer(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; FileOutputBuffer &operator=(const FileOutputBuffer &) LLVM_DELETED_FUNCTION; - FileOutputBuffer(llvm::sys::fs::mapped_file_region *R, + FileOutputBuffer(std::unique_ptr<llvm::sys::fs::mapped_file_region> R, StringRef Path, StringRef TempPath); std::unique_ptr<llvm::sys::fs::mapped_file_region> Region; diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 556701c..63c9ed5 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -226,6 +226,7 @@ struct file_magic { unknown = 0, ///< Unrecognized file bitcode, ///< Bitcode file archive, ///< ar style archive file + elf, ///< ELF Unknown type elf_relocatable, ///< ELF Relocatable object file elf_executable, ///< ELF Executable image elf_shared_object, ///< ELF dynamically linked shared lib @@ -276,14 +277,6 @@ private: /// platform-specific error_code. std::error_code make_absolute(SmallVectorImpl<char> &path); -/// @brief Normalize path separators in \a Path -/// -/// If the path contains any '\' separators, they are transformed into '/'. -/// This is particularly useful when cross-compiling Windows on Linux, but is -/// safe to invoke on Windows, which accepts both characters as a path -/// separator. -std::error_code normalize_separators(SmallVectorImpl<char> &Path); - /// @brief Create all the non-existent directories in path. /// /// @param path Directories to create. @@ -360,33 +353,38 @@ std::error_code resize_file(const Twine &path, uint64_t size); /// not. bool exists(file_status status); -/// @brief Does file exist? +enum class AccessMode { Exist, Write, Execute }; + +/// @brief Can the file be accessed? /// -/// @param path Input path. -/// @param result Set to true if the file represented by status exists, false if -/// it does not. Undefined otherwise. -/// @returns errc::success if result has been successfully set, otherwise a +/// @param Path Input path. +/// @returns errc::success if the path can be accessed, otherwise a /// platform-specific error_code. -std::error_code exists(const Twine &path, bool &result); +std::error_code access(const Twine &Path, AccessMode Mode); -/// @brief Simpler version of exists for clients that don't need to -/// differentiate between an error and false. -inline bool exists(const Twine &path) { - bool result; - return !exists(path, result) && result; +/// @brief Does file exist? +/// +/// @param Path Input path. +/// @returns True if it exists, false otherwise. +inline bool exists(const Twine &Path) { + return !access(Path, AccessMode::Exist); } /// @brief Can we execute this file? /// /// @param Path Input path. /// @returns True if we can execute it, false otherwise. -bool can_execute(const Twine &Path); +inline bool can_execute(const Twine &Path) { + return !access(Path, AccessMode::Execute); +} /// @brief Can we write this file? /// /// @param Path Input path. /// @returns True if we can write to it, false otherwise. -bool can_write(const Twine &Path); +inline bool can_write(const Twine &Path) { + return !access(Path, AccessMode::Write); +} /// @brief Do file_status's represent the same thing? /// diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index b713cc7..8e163dd 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -23,6 +23,9 @@ #ifndef LLVM_SUPPORT_FORMAT_H #define LLVM_SUPPORT_FORMAT_H +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + #include <cassert> #include <cstdio> #ifdef _MSC_VER @@ -41,6 +44,7 @@ namespace llvm { class format_object_base { protected: const char *Fmt; + ~format_object_base() {} // Disallow polymorphic deletion. virtual void home(); // Out of line virtual method. /// Call snprintf() for this object, on the given buffer and size. @@ -48,7 +52,6 @@ protected: public: format_object_base(const char *fmt) : Fmt(fmt) {} - virtual ~format_object_base() {} /// Format the object into the specified buffer. On success, this returns /// the length of the formatted string. If the buffer is too small, this @@ -79,7 +82,7 @@ public: /// returns whether or not it is big enough. template <typename T> -class format_object1 : public format_object_base { +class format_object1 final : public format_object_base { T Val; public: format_object1(const char *fmt, const T &val) @@ -92,7 +95,7 @@ public: }; template <typename T1, typename T2> -class format_object2 : public format_object_base { +class format_object2 final : public format_object_base { T1 Val1; T2 Val2; public: @@ -106,7 +109,7 @@ public: }; template <typename T1, typename T2, typename T3> -class format_object3 : public format_object_base { +class format_object3 final : public format_object_base { T1 Val1; T2 Val2; T3 Val3; @@ -121,7 +124,7 @@ public: }; template <typename T1, typename T2, typename T3, typename T4> -class format_object4 : public format_object_base { +class format_object4 final : public format_object_base { T1 Val1; T2 Val2; T3 Val3; @@ -138,7 +141,7 @@ public: }; template <typename T1, typename T2, typename T3, typename T4, typename T5> -class format_object5 : public format_object_base { +class format_object5 final : public format_object_base { T1 Val1; T2 Val2; T3 Val3; @@ -158,7 +161,7 @@ public: template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> -class format_object6 : public format_object_base { +class format_object6 final : public format_object_base { T1 Val1; T2 Val2; T3 Val3; @@ -225,6 +228,66 @@ format(const char *Fmt, const T1 &Val1, const T2 &Val2, const T3 &Val3, Val5, Val6); } +/// This is a helper class used for left_justify() and right_justify(). +class FormattedString { + StringRef Str; + unsigned Width; + bool RightJustify; + friend class raw_ostream; +public: + FormattedString(StringRef S, unsigned W, bool R) + : Str(S), Width(W), RightJustify(R) { } +}; + +/// left_justify - append spaces after string so total output is +/// \p Width characters. If \p Str is larger that \p Width, full string +/// is written with no padding. +inline FormattedString left_justify(StringRef Str, unsigned Width) { + return FormattedString(Str, Width, false); +} + +/// right_justify - add spaces before string so total output is +/// \p Width characters. If \p Str is larger that \p Width, full string +/// is written with no padding. +inline FormattedString right_justify(StringRef Str, unsigned Width) { + return FormattedString(Str, Width, true); +} + +/// This is a helper class used for format_hex() and format_decimal(). +class FormattedNumber { + uint64_t HexValue; + int64_t DecValue; + unsigned Width; + bool Hex; + bool Upper; + friend class raw_ostream; +public: + FormattedNumber(uint64_t HV, int64_t DV, unsigned W, bool H, bool U) + : HexValue(HV), DecValue(DV), Width(W), Hex(H), Upper(U) { } +}; + +/// format_hex - Output \p N as a fixed width hexadecimal. If number will not +/// fit in width, full number is still printed. Examples: +/// OS << format_hex(255, 4) => 0xff +/// OS << format_hex(255, 4, true) => 0xFF +/// OS << format_hex(255, 6) => 0x00ff +/// OS << format_hex(255, 2) => 0xff +inline FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false) { + assert(Width <= 18 && "hex width must be <= 18"); + return FormattedNumber(N, 0, Width, true, Upper); +} + +/// format_decimal - Output \p N as a right justified, fixed-width decimal. If +/// number will not fit in width, full number is still printed. Examples: +/// OS << format_decimal(0, 5) => " 0" +/// OS << format_decimal(255, 5) => " 255" +/// OS << format_decimal(-1, 3) => " -1" +/// OS << format_decimal(12345, 3) => "12345" +inline FormattedNumber format_decimal(int64_t N, unsigned Width) { + return FormattedNumber(0, N, Width, false, false); +} + + } // end namespace llvm #endif diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index 0cb6cfd..e378602 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -100,7 +100,7 @@ public: /// cursor and return true otherwise return false. bool readFunctionTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' || Tag[3] != '\1') { return false; @@ -113,7 +113,7 @@ public: /// cursor and return true otherwise return false. bool readBlockTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' || Tag[3] != '\x01') { return false; @@ -126,7 +126,7 @@ public: /// cursor and return true otherwise return false. bool readEdgeTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' || Tag[3] != '\x01') { return false; @@ -139,7 +139,7 @@ public: /// cursor and return true otherwise return false. bool readLineTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' || Tag[3] != '\x01') { return false; @@ -152,7 +152,7 @@ public: /// cursor and return true otherwise return false. bool readArcTag() { StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); - if (Tag.empty() || + if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' || Tag[3] != '\1') { return false; diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index 876ab6e..6bc4b44 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -15,8 +15,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H -#define LLVM_SUPPORT_GENERIC_DOM_TREE_H +#ifndef LLVM_SUPPORT_GENERICDOMTREE_H +#define LLVM_SUPPORT_GENERICDOMTREE_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" diff --git a/include/llvm/Support/GenericDomTreeConstruction.h b/include/llvm/Support/GenericDomTreeConstruction.h index bcba5e0..ad4f8a9 100644 --- a/include/llvm/Support/GenericDomTreeConstruction.h +++ b/include/llvm/Support/GenericDomTreeConstruction.h @@ -22,8 +22,8 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H -#define LLVM_SUPPORT_GENERIC_DOM_TREE_CONSTRUCTION_H +#ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H +#define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/GenericDomTree.h" @@ -125,7 +125,7 @@ Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent]; // Process Ancestor first - if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) { + if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) { Work.push_back(VAncestor); continue; } diff --git a/include/llvm/Support/IncludeFile.h b/include/llvm/Support/IncludeFile.h deleted file mode 100644 index 2067e34..0000000 --- a/include/llvm/Support/IncludeFile.h +++ /dev/null @@ -1,79 +0,0 @@ -//===- llvm/Support/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR -// macros. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_INCLUDEFILE_H -#define LLVM_SUPPORT_INCLUDEFILE_H - -/// This macro is the public interface that IncludeFile.h exports. This gives -/// us the option to implement the "link the definition" capability in any -/// manner that we choose. All header files that depend on a specific .cpp -/// file being linked at run time should use this macro instead of the -/// IncludeFile class directly. -/// -/// For example, foo.h would use:<br/> -/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/> -/// -/// And, foo.cp would use:<br/> -/// <tt>DEFINING_FILE_FOR(foo)</tt><br/> -#ifdef __GNUC__ -// If the `used' attribute is available, use it to create a variable -// with an initializer that will force the linking of the defining file. -#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ - namespace llvm { \ - extern const char name ## LinkVar; \ - __attribute__((used)) static const char *const name ## LinkObj = \ - &name ## LinkVar; \ - } -#else -// Otherwise use a constructor call. -#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \ - namespace llvm { \ - extern const char name ## LinkVar; \ - static const IncludeFile name ## LinkObj ( &name ## LinkVar ); \ - } -#endif - -/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should -/// be used in a .cpp file to define the name referenced in a header file that -/// will cause linkage of the .cpp file. It should only be used at extern level. -#define DEFINING_FILE_FOR(name) \ - namespace llvm { const char name ## LinkVar = 0; } - -namespace llvm { - -/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED -/// macro to make sure that the implementation of a header file is included -/// into a tool that uses the header. This is solely -/// to overcome problems linking .a files and not getting the implementation -/// of compilation units we need. This is commonly an issue with the various -/// Passes but also occurs elsewhere in LLVM. We like to use .a files because -/// they link faster and provide the smallest executables. However, sometimes -/// those executables are too small, if the program doesn't reference something -/// that might be needed, especially by a loaded share object. This little class -/// helps to resolve that problem. The basic strategy is to use this class in -/// a header file and pass the address of a variable to the constructor. If the -/// variable is defined in the header file's corresponding .cpp file then all -/// tools/libraries that \#include the header file will require the .cpp as -/// well. -/// For example:<br/> -/// <tt>extern int LinkMyCodeStub;</tt><br/> -/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/> -/// @brief Class to ensure linking of corresponding object file. -struct IncludeFile { - explicit IncludeFile(const void *); -}; - -} - -#endif diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h index ea76c9b..6a95432 100644 --- a/include/llvm/Support/LEB128.h +++ b/include/llvm/Support/LEB128.h @@ -82,7 +82,7 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) { uint64_t Value = 0; unsigned Shift = 0; do { - Value += (*p & 0x7f) << Shift; + Value += uint64_t(*p & 0x7f) << Shift; Shift += 7; } while (*p++ >= 128); if (n) @@ -90,6 +90,26 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr) { return Value; } +/// Utility function to decode a SLEB128 value. +inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr) { + const uint8_t *orig_p = p; + int64_t Value = 0; + unsigned Shift = 0; + uint8_t Byte; + do { + Byte = *p++; + Value |= ((Byte & 0x7f) << Shift); + Shift += 7; + } while (Byte >= 128); + // Sign extend negative numbers. + if (Byte & 0x40) + Value |= (-1ULL) << Shift; + if (n) + *n = (unsigned)(p - orig_p); + return Value; +} + + /// Utility function to get the size of the ULEB128-encoded value. extern unsigned getULEB128Size(uint64_t Value); diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h index 2a58262..9d4cd3b 100644 --- a/include/llvm/Support/LineIterator.h +++ b/include/llvm/Support/LineIterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_LINEITERATOR_H__ -#define LLVM_SUPPORT_LINEITERATOR_H__ +#ifndef LLVM_SUPPORT_LINEITERATOR_H +#define LLVM_SUPPORT_LINEITERATOR_H #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -18,20 +18,22 @@ namespace llvm { class MemoryBuffer; -/// \brief A forward iterator which reads non-blank text lines from a buffer. +/// \brief A forward iterator which reads text lines from a buffer. /// /// This class provides a forward iterator interface for reading one line at /// a time from a buffer. When default constructed the iterator will be the /// "end" iterator. /// -/// The iterator also is aware of what line number it is currently processing -/// and can strip comment lines given the comment-starting character. +/// The iterator is aware of what line number it is currently processing. It +/// strips blank lines by default, and comment lines given a comment-starting +/// character. /// /// Note that this iterator requires the buffer to be nul terminated. class line_iterator : public std::iterator<std::forward_iterator_tag, StringRef> { const MemoryBuffer *Buffer; char CommentMarker; + bool SkipBlanks; unsigned LineNumber; StringRef CurrentLine; @@ -41,7 +43,8 @@ public: line_iterator() : Buffer(nullptr) {} /// \brief Construct a new iterator around some memory buffer. - explicit line_iterator(const MemoryBuffer &Buffer, char CommentMarker = '\0'); + explicit line_iterator(const MemoryBuffer &Buffer, bool SkipBlanks = true, + char CommentMarker = '\0'); /// \brief Return true if we've reached EOF or are an "end" iterator. bool is_at_eof() const { return !Buffer; } @@ -82,4 +85,4 @@ private: }; } -#endif // LLVM_SUPPORT_LINEITERATOR_H__ +#endif diff --git a/include/llvm/Support/MD5.h b/include/llvm/Support/MD5.h index 4eb8507..f6e1e92 100644 --- a/include/llvm/Support/MD5.h +++ b/include/llvm/Support/MD5.h @@ -25,8 +25,8 @@ * See md5.c for more information. */ -#ifndef LLVM_SYSTEM_MD5_H -#define LLVM_SYSTEM_MD5_H +#ifndef LLVM_SUPPORT_MD5_H +#define LLVM_SUPPORT_MD5_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" @@ -55,11 +55,11 @@ public: void update(StringRef Str); /// \brief Finishes off the hash and puts the result in result. - void final(MD5Result &result); + void final(MD5Result &Result); /// \brief Translates the bytes in \p Res to a hex string that is /// deposited into \p Str. The result will be of length 32. - static void stringifyResult(MD5Result &Res, SmallString<32> &Str); + static void stringifyResult(MD5Result &Result, SmallString<32> &Str); private: const uint8_t *body(ArrayRef<uint8_t> Data); diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index bd4dc2f..c07bd88 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -73,7 +73,10 @@ namespace llvm { MH_SETUID_SAFE = 0x00080000u, MH_NO_REEXPORTED_DYLIBS = 0x00100000u, MH_PIE = 0x00200000u, - MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u + MH_DEAD_STRIPPABLE_DYLIB = 0x00400000u, + MH_HAS_TLV_DESCRIPTORS = 0x00800000u, + MH_NO_HEAP_EXECUTION = 0x01000000u, + MH_APP_EXTENSION_SAFE = 0x02000000u }; enum : uint32_t { @@ -327,7 +330,8 @@ namespace llvm { enum ExportSymbolKind { EXPORT_SYMBOL_FLAGS_KIND_REGULAR = 0x00u, - EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u + EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL = 0x01u, + EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE = 0x02u }; @@ -386,13 +390,15 @@ namespace llvm { enum StabType { // Constant values for the "n_type" field in llvm::MachO::nlist and - // llvm::MachO::nlist_64 when "(n_type & NlistMaskStab) != 0" + // llvm::MachO::nlist_64 when "(n_type & N_STAB) != 0" N_GSYM = 0x20u, N_FNAME = 0x22u, N_FUN = 0x24u, N_STSYM = 0x26u, N_LCSYM = 0x28u, N_BNSYM = 0x2Eu, + N_PC = 0x30u, + N_AST = 0x32u, N_OPT = 0x3Cu, N_RSYM = 0x40u, N_SLINE = 0x44u, @@ -841,7 +847,7 @@ namespace llvm { // LC_VERSION_MIN_IPHONEOS uint32_t cmdsize; // sizeof(struct version_min_command) uint32_t version; // X.Y.Z is encoded in nibbles xxxx.yy.zz - uint32_t reserved; + uint32_t sdk; // X.Y.Z is encoded in nibbles xxxx.yy.zz }; struct dyld_info_command { @@ -957,6 +963,13 @@ namespace llvm { }; // Structs from <mach-o/nlist.h> + struct nlist_base { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; + }; + struct nlist { uint32_t n_strx; uint8_t n_type; @@ -973,6 +986,217 @@ namespace llvm { uint64_t n_value; }; + + // Byte order swapping functions for MachO structs + + inline void swapStruct(mach_header &mh) { + sys::swapByteOrder(mh.magic); + sys::swapByteOrder(mh.cputype); + sys::swapByteOrder(mh.cpusubtype); + sys::swapByteOrder(mh.filetype); + sys::swapByteOrder(mh.ncmds); + sys::swapByteOrder(mh.sizeofcmds); + sys::swapByteOrder(mh.flags); + } + + inline void swapStruct(mach_header_64 &H) { + sys::swapByteOrder(H.magic); + sys::swapByteOrder(H.cputype); + sys::swapByteOrder(H.cpusubtype); + sys::swapByteOrder(H.filetype); + sys::swapByteOrder(H.ncmds); + sys::swapByteOrder(H.sizeofcmds); + sys::swapByteOrder(H.flags); + sys::swapByteOrder(H.reserved); + } + + inline void swapStruct(load_command &lc) { + sys::swapByteOrder(lc.cmd); + sys::swapByteOrder(lc.cmdsize); + } + + inline void swapStruct(symtab_command &lc) { + sys::swapByteOrder(lc.cmd); + sys::swapByteOrder(lc.cmdsize); + sys::swapByteOrder(lc.symoff); + sys::swapByteOrder(lc.nsyms); + sys::swapByteOrder(lc.stroff); + sys::swapByteOrder(lc.strsize); + } + + inline void swapStruct(segment_command_64 &seg) { + sys::swapByteOrder(seg.cmd); + sys::swapByteOrder(seg.cmdsize); + sys::swapByteOrder(seg.vmaddr); + sys::swapByteOrder(seg.vmsize); + sys::swapByteOrder(seg.fileoff); + sys::swapByteOrder(seg.filesize); + sys::swapByteOrder(seg.maxprot); + sys::swapByteOrder(seg.initprot); + sys::swapByteOrder(seg.nsects); + sys::swapByteOrder(seg.flags); + } + + inline void swapStruct(segment_command &seg) { + sys::swapByteOrder(seg.cmd); + sys::swapByteOrder(seg.cmdsize); + sys::swapByteOrder(seg.vmaddr); + sys::swapByteOrder(seg.vmsize); + sys::swapByteOrder(seg.fileoff); + sys::swapByteOrder(seg.filesize); + sys::swapByteOrder(seg.maxprot); + sys::swapByteOrder(seg.initprot); + sys::swapByteOrder(seg.nsects); + sys::swapByteOrder(seg.flags); + } + + inline void swapStruct(section_64 §) { + sys::swapByteOrder(sect.addr); + sys::swapByteOrder(sect.size); + sys::swapByteOrder(sect.offset); + sys::swapByteOrder(sect.align); + sys::swapByteOrder(sect.reloff); + sys::swapByteOrder(sect.nreloc); + sys::swapByteOrder(sect.flags); + sys::swapByteOrder(sect.reserved1); + sys::swapByteOrder(sect.reserved2); + } + + inline void swapStruct(section §) { + sys::swapByteOrder(sect.addr); + sys::swapByteOrder(sect.size); + sys::swapByteOrder(sect.offset); + sys::swapByteOrder(sect.align); + sys::swapByteOrder(sect.reloff); + sys::swapByteOrder(sect.nreloc); + sys::swapByteOrder(sect.flags); + sys::swapByteOrder(sect.reserved1); + sys::swapByteOrder(sect.reserved2); + } + + inline void swapStruct(dyld_info_command &info) { + sys::swapByteOrder(info.cmd); + sys::swapByteOrder(info.cmdsize); + sys::swapByteOrder(info.rebase_off); + sys::swapByteOrder(info.rebase_size); + sys::swapByteOrder(info.bind_off); + sys::swapByteOrder(info.bind_size); + sys::swapByteOrder(info.weak_bind_off); + sys::swapByteOrder(info.weak_bind_size); + sys::swapByteOrder(info.lazy_bind_off); + sys::swapByteOrder(info.lazy_bind_size); + sys::swapByteOrder(info.export_off); + sys::swapByteOrder(info.export_size); + } + + inline void swapStruct(dylib_command &d) { + sys::swapByteOrder(d.cmd); + sys::swapByteOrder(d.cmdsize); + sys::swapByteOrder(d.dylib.name); + sys::swapByteOrder(d.dylib.timestamp); + sys::swapByteOrder(d.dylib.current_version); + sys::swapByteOrder(d.dylib.compatibility_version); + } + + inline void swapStruct(dylinker_command &d) { + sys::swapByteOrder(d.cmd); + sys::swapByteOrder(d.cmdsize); + sys::swapByteOrder(d.name); + } + + inline void swapStruct(uuid_command &u) { + sys::swapByteOrder(u.cmd); + sys::swapByteOrder(u.cmdsize); + } + + inline void swapStruct(source_version_command &s) { + sys::swapByteOrder(s.cmd); + sys::swapByteOrder(s.cmdsize); + sys::swapByteOrder(s.version); + } + + inline void swapStruct(entry_point_command &e) { + sys::swapByteOrder(e.cmd); + sys::swapByteOrder(e.cmdsize); + sys::swapByteOrder(e.entryoff); + sys::swapByteOrder(e.stacksize); + } + + inline void swapStruct(dysymtab_command &dst) { + sys::swapByteOrder(dst.cmd); + sys::swapByteOrder(dst.cmdsize); + sys::swapByteOrder(dst.ilocalsym); + sys::swapByteOrder(dst.nlocalsym); + sys::swapByteOrder(dst.iextdefsym); + sys::swapByteOrder(dst.nextdefsym); + sys::swapByteOrder(dst.iundefsym); + sys::swapByteOrder(dst.nundefsym); + sys::swapByteOrder(dst.tocoff); + sys::swapByteOrder(dst.ntoc); + sys::swapByteOrder(dst.modtaboff); + sys::swapByteOrder(dst.nmodtab); + sys::swapByteOrder(dst.extrefsymoff); + sys::swapByteOrder(dst.nextrefsyms); + sys::swapByteOrder(dst.indirectsymoff); + sys::swapByteOrder(dst.nindirectsyms); + sys::swapByteOrder(dst.extreloff); + sys::swapByteOrder(dst.nextrel); + sys::swapByteOrder(dst.locreloff); + sys::swapByteOrder(dst.nlocrel); + } + + inline void swapStruct(any_relocation_info &reloc) { + sys::swapByteOrder(reloc.r_word0); + sys::swapByteOrder(reloc.r_word1); + } + + inline void swapStruct(nlist_base &S) { + sys::swapByteOrder(S.n_strx); + sys::swapByteOrder(S.n_desc); + } + + inline void swapStruct(nlist &sym) { + sys::swapByteOrder(sym.n_strx); + sys::swapByteOrder(sym.n_desc); + sys::swapByteOrder(sym.n_value); + } + + inline void swapStruct(nlist_64 &sym) { + sys::swapByteOrder(sym.n_strx); + sys::swapByteOrder(sym.n_desc); + sys::swapByteOrder(sym.n_value); + } + + inline void swapStruct(linkedit_data_command &C) { + sys::swapByteOrder(C.cmd); + sys::swapByteOrder(C.cmdsize); + sys::swapByteOrder(C.dataoff); + sys::swapByteOrder(C.datasize); + } + + inline void swapStruct(linker_options_command &C) { + sys::swapByteOrder(C.cmd); + sys::swapByteOrder(C.cmdsize); + sys::swapByteOrder(C.count); + } + + inline void swapStruct(version_min_command&C) { + sys::swapByteOrder(C.cmd); + sys::swapByteOrder(C.cmdsize); + sys::swapByteOrder(C.version); + sys::swapByteOrder(C.sdk); + } + + inline void swapStruct(data_in_code_entry &C) { + sys::swapByteOrder(C.offset); + sys::swapByteOrder(C.length); + sys::swapByteOrder(C.kind); + } + + inline void swapStruct(uint32_t &C) { + sys::swapByteOrder(C); + } + // Get/Set functions from <mach-o/nlist.h> static inline uint16_t GET_LIBRARY_ORDINAL(uint16_t n_desc) { diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h index d8fbfeb..addd34e 100644 --- a/include/llvm/Support/ManagedStatic.h +++ b/include/llvm/Support/ManagedStatic.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_MANAGED_STATIC_H -#define LLVM_SUPPORT_MANAGED_STATIC_H +#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H +#define LLVM_SUPPORT_MANAGEDSTATIC_H #include "llvm/Support/Atomic.h" #include "llvm/Support/Threading.h" diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h index 0abba62..9d16182 100644 --- a/include/llvm/Support/MathExtras.h +++ b/include/llvm/Support/MathExtras.h @@ -22,7 +22,6 @@ #ifdef _MSC_VER #include <intrin.h> -#include <limits> #endif namespace llvm { @@ -81,7 +80,7 @@ inline std::size_t countTrailingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; -#if __has_builtin(__builtin_ctz) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_ctz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctz(Val); #elif _MSC_VER unsigned long Index; @@ -96,7 +95,7 @@ inline std::size_t countTrailingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; -#if __has_builtin(__builtin_ctzll) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_ctzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_ctzll(Val); #elif _MSC_VER unsigned long Index; @@ -147,7 +146,7 @@ inline std::size_t countLeadingZeros<uint32_t>(uint32_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 32; -#if __has_builtin(__builtin_clz) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_clz) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clz(Val); #elif _MSC_VER unsigned long Index; @@ -162,7 +161,7 @@ inline std::size_t countLeadingZeros<uint64_t>(uint64_t Val, ZeroBehavior ZB) { if (ZB != ZB_Undefined && Val == 0) return 64; -#if __has_builtin(__builtin_clzll) || __GNUC_PREREQ(4, 0) +#if __has_builtin(__builtin_clzll) || LLVM_GNUC_PREREQ(4, 0, 0) return __builtin_clzll(Val); #elif _MSC_VER unsigned long Index; @@ -550,16 +549,23 @@ inline uint64_t MinAlign(uint64_t A, uint64_t B) { return (A | B) & (1 + ~(A | B)); } -/// \brief Aligns \c Ptr to \c Alignment bytes, rounding up. +/// \brief Aligns \c Addr to \c Alignment bytes, rounding up. /// /// Alignment should be a power of two. This method rounds up, so -/// AlignPtr(7, 4) == 8 and AlignPtr(8, 4) == 8. -inline char *alignPtr(char *Ptr, size_t Alignment) { +/// alignAddr(7, 4) == 8 and alignAddr(8, 4) == 8. +inline uintptr_t alignAddr(void *Addr, size_t Alignment) { assert(Alignment && isPowerOf2_64((uint64_t)Alignment) && "Alignment is not a power of two!"); - return (char *)(((uintptr_t)Ptr + Alignment - 1) & - ~(uintptr_t)(Alignment - 1)); + assert((uintptr_t)Addr + Alignment - 1 >= (uintptr_t)Addr); + + return (((uintptr_t)Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1)); +} + +/// \brief Returns the necessary adjustment for aligning \c Ptr to \c Alignment +/// bytes, rounding up. +inline size_t alignmentAdjustment(void *Ptr, size_t Alignment) { + return alignAddr(Ptr, Alignment) - (uintptr_t)Ptr; } /// NextPowerOf2 - Returns the next power of two (in 64-bits) @@ -589,9 +595,10 @@ inline uint64_t PowerOf2Floor(uint64_t A) { /// RoundUpToAlignment(5, 8) = 8 /// RoundUpToAlignment(17, 8) = 24 /// RoundUpToAlignment(~0LL, 8) = 0 +/// RoundUpToAlignment(321, 255) = 510 /// \endcode inline uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align) { - return ((Value + Align - 1) / Align) * Align; + return (Value + Align - 1) / Align * Align; } /// Returns the offset to the next integer (mod 2**64) that is greater than @@ -632,13 +639,7 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) { return int64_t(X << (64 - B)) >> (64 - B); } -#if defined(_MSC_VER) - // Visual Studio defines the HUGE_VAL class of macros using purposeful - // constant arithmetic overflow, which it then warns on when encountered. - const float huge_valf = std::numeric_limits<float>::infinity(); -#else - const float huge_valf = HUGE_VALF; -#endif +extern const float huge_valf; } // End llvm namespace #endif diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 147be47..e2f8d7e 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -24,11 +24,13 @@ #include <system_error> namespace llvm { -/// MemoryBuffer - This interface provides simple read-only access to a block -/// of memory, and provides simple methods for reading files and standard input -/// into a memory buffer. In addition to basic access to the characters in the -/// file, this interface guarantees you can read one character past the end of -/// the file, and that this character will read as '\0'. +class MemoryBufferRef; + +/// This interface provides simple read-only access to a block of memory, and +/// provides simple methods for reading files and standard input into a memory +/// buffer. In addition to basic access to the characters in the file, this +/// interface guarantees you can read one character past the end of the file, +/// and that this character will read as '\0'. /// /// The '\0' guarantee is needed to support an optimization -- it's intended to /// be more efficient for clients which are reading all the data to stop @@ -55,8 +57,8 @@ public: return StringRef(BufferStart, getBufferSize()); } - /// getBufferIdentifier - Return an identifier for this buffer, typically the - /// filename it was read from. + /// Return an identifier for this buffer, typically the filename it was read + /// from. virtual const char *getBufferIdentifier() const { return "Unknown buffer"; } @@ -70,19 +72,15 @@ public: /// changing, e.g. when libclang tries to parse while the user is /// editing/updating the file. static ErrorOr<std::unique_ptr<MemoryBuffer>> - getFile(Twine Filename, int64_t FileSize = -1, + getFile(const Twine &Filename, int64_t FileSize = -1, 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. - /// - /// \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 ErrorOr<std::unique_ptr<MemoryBuffer>> - getOpenFileSlice(int FD, const char *Filename, uint64_t MapSize, - int64_t Offset, bool IsVolatileSize = false); + getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize, + int64_t Offset); /// Given an already-open file descriptor, read the file and return a /// MemoryBuffer. @@ -91,33 +89,34 @@ public: /// changing, e.g. when libclang tries to parse while the user is /// editing/updating the file. static ErrorOr<std::unique_ptr<MemoryBuffer>> - getOpenFile(int FD, const char *Filename, uint64_t FileSize, + getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, 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. - static MemoryBuffer *getMemBuffer(StringRef InputData, - StringRef BufferName = "", - bool RequiresNullTerminator = true); - - /// getMemBufferCopy - Open the specified memory range as a MemoryBuffer, - /// copying the contents and taking ownership of it. InputData does not - /// have to be null terminated. - static MemoryBuffer *getMemBufferCopy(StringRef InputData, - StringRef BufferName = ""); - - /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that - /// is completely initialized to zeros. Note that the caller should - /// initialize the memory allocated by this method. The memory is owned by - /// the MemoryBuffer object. - static MemoryBuffer *getNewMemBuffer(size_t Size, StringRef BufferName = ""); - - /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size - /// that is not initialized. Note that the caller should initialize the - /// memory allocated by this method. The memory is owned by the MemoryBuffer - /// object. - static MemoryBuffer *getNewUninitMemBuffer(size_t Size, - StringRef BufferName = ""); + /// Open the specified memory range as a MemoryBuffer. Note that InputData + /// must be null terminated if RequiresNullTerminator is true. + static std::unique_ptr<MemoryBuffer> + getMemBuffer(StringRef InputData, StringRef BufferName = "", + bool RequiresNullTerminator = true); + + static std::unique_ptr<MemoryBuffer> + getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator = true); + + /// Open the specified memory range as a MemoryBuffer, copying the contents + /// and taking ownership of it. InputData does not have to be null terminated. + static std::unique_ptr<MemoryBuffer> + getMemBufferCopy(StringRef InputData, const Twine &BufferName = ""); + + /// Allocate a new zero-initialized MemoryBuffer of the specified size. Note + /// that the caller need not initialize the memory allocated by this method. + /// The memory is owned by the MemoryBuffer object. + static std::unique_ptr<MemoryBuffer> + getNewMemBuffer(size_t Size, StringRef BufferName = ""); + + /// Allocate a new MemoryBuffer of the specified size that is not initialized. + /// Note that the caller should initialize the memory allocated by this + /// method. The memory is owned by the MemoryBuffer object. + static std::unique_ptr<MemoryBuffer> + getNewUninitMemBuffer(size_t Size, const Twine &BufferName = ""); /// Read all of stdin into a file buffer, and return it. static ErrorOr<std::unique_ptr<MemoryBuffer>> getSTDIN(); @@ -125,7 +124,11 @@ public: /// Open the specified file as a MemoryBuffer, or open stdin if the Filename /// is "-". static ErrorOr<std::unique_ptr<MemoryBuffer>> - getFileOrSTDIN(StringRef Filename, int64_t FileSize = -1); + getFileOrSTDIN(const Twine &Filename, int64_t FileSize = -1); + + /// Map a subrange of the the specified file as a MemoryBuffer. + static ErrorOr<std::unique_ptr<MemoryBuffer>> + getFileSlice(const Twine &Filename, uint64_t MapSize, uint64_t Offset); //===--------------------------------------------------------------------===// // Provided for performance analysis. @@ -139,7 +142,27 @@ public: /// Return information on the memory mechanism used to support the /// MemoryBuffer. - virtual BufferKind getBufferKind() const = 0; + virtual BufferKind getBufferKind() const = 0; + + MemoryBufferRef getMemBufferRef() const; +}; + +class MemoryBufferRef { + StringRef Buffer; + StringRef Identifier; + +public: + MemoryBufferRef() {} + MemoryBufferRef(StringRef Buffer, StringRef Identifier) + : Buffer(Buffer), Identifier(Identifier) {} + + StringRef getBuffer() const { return Buffer; } + + StringRef getBufferIdentifier() const { return Identifier; } + + const char *getBufferStart() const { return Buffer.begin(); } + const char *getBufferEnd() const { return Buffer.end(); } + size_t getBufferSize() const { return Buffer.size(); } }; // Create wrappers for C Binding types (see CBindingWrapping.h). diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h index 17aa9d2..e0c8749 100644 --- a/include/llvm/Support/MemoryObject.h +++ b/include/llvm/Support/MemoryObject.h @@ -14,49 +14,53 @@ namespace llvm { -/// MemoryObject - Abstract base class for contiguous addressable memory. -/// Necessary for cases in which the memory is in another process, in a -/// file, or on a remote machine. -/// All size and offset parameters are uint64_ts, to allow 32-bit processes -/// access to 64-bit address spaces. +/// Interface to data which might be streamed. Streamability has 2 important +/// implications/restrictions. First, the data might not yet exist in memory +/// when the request is made. This just means that readByte/readBytes might have +/// to block or do some work to get it. More significantly, the exact size of +/// the object might not be known until it has all been fetched. This means that +/// to return the right result, getExtent must also wait for all the data to +/// arrive; therefore it should not be called on objects which are actually +/// streamed (this would defeat the purpose of streaming). Instead, +/// isValidAddress can be used to test addresses without knowing the exact size +/// of the stream. Finally, getPointer can be used instead of readBytes to avoid +/// extra copying. class MemoryObject { public: - /// Destructor - Override as necessary. virtual ~MemoryObject(); - /// getBase - Returns the lowest valid address in the region. - /// - /// @result - The lowest valid address. - virtual uint64_t getBase() const = 0; - - /// getExtent - Returns the size of the region in bytes. (The region is - /// contiguous, so the highest valid address of the region - /// is getBase() + getExtent() - 1). + /// Returns the size of the region in bytes. (The region is contiguous, so + /// the highest valid address of the region is getExtent() - 1). /// /// @result - The size of the region. virtual uint64_t getExtent() const = 0; - /// readByte - Tries to read a single byte from the region. - /// - /// @param address - The address of the byte, in the same space as getBase(). - /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. - /// @result - 0 if successful; -1 if not. Failure may be due to a - /// bounds violation or an implementation-specific error. - virtual int readByte(uint64_t address, uint8_t *ptr) const = 0; - - /// readBytes - Tries to read a contiguous range of bytes from the - /// region, up to the end of the region. - /// You should override this function if there is a quicker - /// way than going back and forth with individual bytes. + /// Tries to read a contiguous range of bytes from the region, up to the end + /// of the region. /// - /// @param address - The address of the first byte, in the same space as - /// getBase(). - /// @param size - The number of bytes to copy. - /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL + /// @param Buf - A pointer to a buffer to be filled in. Must be non-NULL /// and large enough to hold size bytes. - /// @result - 0 if successful; -1 if not. Failure may be due to a - /// bounds violation or an implementation-specific error. - virtual int readBytes(uint64_t address, uint64_t size, uint8_t *buf) const; + /// @param Size - The number of bytes to copy. + /// @param Address - The address of the first byte, in the same space as + /// getBase(). + /// @result - The number of bytes read. + virtual uint64_t readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const = 0; + + /// Ensures that the requested data is in memory, and returns a pointer to it. + /// More efficient than using readBytes if the data is already in memory. May + /// block until (address - base + size) bytes have been read + /// @param address - address of the byte, in the same space as getBase() + /// @param size - amount of data that must be available on return + /// @result - valid pointer to the requested data + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0; + + /// Returns true if the address is within the object (i.e. between base and + /// base + extent - 1 inclusive). May block until (address - base) bytes have + /// been read + /// @param address - address of the byte, in the same space as getBase() + /// @result - true if the address may be read with readByte() + virtual bool isValidAddress(uint64_t address) const = 0; }; } diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h index 496a438..97dd501 100644 --- a/include/llvm/Support/Mutex.h +++ b/include/llvm/Support/Mutex.h @@ -86,16 +86,17 @@ namespace llvm /// indicates whether this mutex should become a no-op when we're not /// running in multithreaded mode. template<bool mt_only> - class SmartMutex : public MutexImpl { + class SmartMutex { + MutexImpl impl; unsigned acquired; bool recursive; public: explicit SmartMutex(bool rec = true) : - MutexImpl(rec), acquired(0), recursive(rec) { } + impl(rec), acquired(0), recursive(rec) { } - bool acquire() { + bool lock() { if (!mt_only || llvm_is_multithreaded()) { - return MutexImpl::acquire(); + return impl.acquire(); } else { // Single-threaded debugging code. This would be racy in // multithreaded mode, but provides not sanity checks in single @@ -106,9 +107,9 @@ namespace llvm } } - bool release() { + bool unlock() { if (!mt_only || llvm_is_multithreaded()) { - return MutexImpl::release(); + return impl.release(); } else { // Single-threaded debugging code. This would be racy in // multithreaded mode, but provides not sanity checks in single @@ -120,9 +121,9 @@ namespace llvm } } - bool tryacquire() { + bool try_lock() { if (!mt_only || llvm_is_multithreaded()) - return MutexImpl::tryacquire(); + return impl.tryacquire(); else return true; } @@ -140,11 +141,11 @@ namespace llvm public: SmartScopedLock(SmartMutex<mt_only>& m) : mtx(m) { - mtx.acquire(); + mtx.lock(); } ~SmartScopedLock() { - mtx.release(); + mtx.unlock(); } }; diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h index 6bb1622..b9f941d 100644 --- a/include/llvm/Support/MutexGuard.h +++ b/include/llvm/Support/MutexGuard.h @@ -29,8 +29,8 @@ namespace llvm { MutexGuard(const MutexGuard &) LLVM_DELETED_FUNCTION; void operator=(const MutexGuard &) LLVM_DELETED_FUNCTION; public: - MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); } - ~MutexGuard() { M.release(); } + MutexGuard(sys::Mutex &m) : M(m) { M.lock(); } + ~MutexGuard() { M.unlock(); } /// holds - Returns true if this locker instance holds the specified lock. /// This is mostly used in assertions to validate that the correct mutex /// is held. diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h index f6d43a4..b039fae 100644 --- a/include/llvm/Support/OnDiskHashTable.h +++ b/include/llvm/Support/OnDiskHashTable.h @@ -11,8 +11,8 @@ /// \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 +#ifndef LLVM_SUPPORT_ONDISKHASHTABLE_H +#define LLVM_SUPPORT_ONDISKHASHTABLE_H #include "llvm/Support/Allocator.h" #include "llvm/Support/AlignOf.h" @@ -568,4 +568,4 @@ public: } // end namespace llvm -#endif // LLVM_SUPPORT_ON_DISK_HASH_TABLE_H +#endif diff --git a/include/llvm/Support/Options.h b/include/llvm/Support/Options.h new file mode 100644 index 0000000..4fd1bff --- /dev/null +++ b/include/llvm/Support/Options.h @@ -0,0 +1,120 @@ +//===- llvm/Support/Options.h - Debug options support -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// This file declares helper objects for defining debug options that can be +/// configured via the command line. The new API currently builds on the cl::opt +/// API, but does not require the use of static globals. +/// +/// With this API options are registered during initialization. For passes, this +/// happens during pass initialization. Passes with options will call a static +/// registerOptions method during initialization that registers options with the +/// OptionRegistry. An example implementation of registerOptions is: +/// +/// static void registerOptions() { +/// OptionRegistry::registerOption<bool, Scalarizer, +/// &Scalarizer::ScalarizeLoadStore>( +/// "scalarize-load-store", +/// "Allow the scalarizer pass to scalarize loads and store", false); +/// } +/// +/// When reading data for options the interface is via the LLVMContext. Option +/// data for passes should be read from the context during doInitialization. An +/// example of reading the above option would be: +/// +/// ScalarizeLoadStore = +/// M.getContext().getOption<bool, +/// Scalarizer, +/// &Scalarizer::ScalarizeLoadStore>(); +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_OPTIONS_H +#define LLVM_SUPPORT_OPTIONS_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/CommandLine.h" + +namespace llvm { + +namespace detail { + +// Options are keyed of the unique address of a static character synthesized +// based on template arguments. +template <typename ValT, typename Base, ValT(Base::*Mem)> class OptionKey { +public: + static char ID; +}; + +template <typename ValT, typename Base, ValT(Base::*Mem)> +char OptionKey<ValT, Base, Mem>::ID = 0; + +} // namespace detail + +/// \brief Singleton class used to register debug options. +/// +/// The OptionRegistry is responsible for managing lifetimes of the options and +/// provides interfaces for option registration and reading values from options. +/// This object is a singleton, only one instance should ever exist so that all +/// options are registered in teh same place. +class OptionRegistry { +private: + DenseMap<void *, cl::Option *> Options; + + /// \brief Adds a cl::Option to the registry. + /// + /// \param Key unique key for option + /// \param O option to map to \p Key + /// + /// Allocated cl::Options are owened by the OptionRegistry and are deallocated + /// on destruction or removal + void addOption(void *Key, cl::Option *O); + +public: + ~OptionRegistry(); + OptionRegistry() {} + + /// \brief Returns a reference to the singleton instance. + static OptionRegistry &instance(); + + /// \brief Registers an option with the OptionRegistry singleton. + /// + /// \tparam ValT type of the option's data + /// \tparam Base class used to key the option + /// \tparam Mem member of \p Base used for keying the option + /// + /// Options are keyed off the template parameters to generate unique static + /// characters. The template parameters are (1) the type of the data the + /// option stores (\p ValT), the class that will read the option (\p Base), + /// and the memeber that the class will store the data into (\p Mem). + template <typename ValT, typename Base, ValT(Base::*Mem)> + static void registerOption(const char *ArgStr, const char *Desc, + const ValT &InitValue) { + cl::opt<ValT> *Option = new cl::opt<ValT>(ArgStr, cl::desc(Desc), + cl::Hidden, cl::init(InitValue)); + instance().addOption(&detail::OptionKey<ValT, Base, Mem>::ID, Option); + } + + /// \brief Returns the value of the option. + /// + /// \tparam ValT type of the option's data + /// \tparam Base class used to key the option + /// \tparam Mem member of \p Base used for keying the option + /// + /// Reads option values based on the key generated by the template parameters. + /// Keying for get() is the same as keying for registerOption. + template <typename ValT, typename Base, ValT(Base::*Mem)> ValT get() const { + auto It = Options.find(&detail::OptionKey<ValT, Base, Mem>::ID); + assert(It != Options.end() && "Option not in OptionRegistry"); + return *(cl::opt<ValT> *)It->second; + } +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/Support/Path.h b/include/llvm/Support/Path.h index cf821f0..8fae853 100644 --- a/include/llvm/Support/Path.h +++ b/include/llvm/Support/Path.h @@ -30,13 +30,13 @@ namespace path { /// @brief Path iterator. /// -/// This is a bidirectional iterator that iterates over the individual -/// components in \a path. The forward traversal order is as follows: +/// This is an input iterator that iterates over the individual components in +/// \a path. The traversal order is as follows: /// * The root-name element, if present. /// * The root-directory element, if present. /// * Each successive filename element, if present. /// * Dot, if one or more trailing non-root slash characters are present. -/// The backwards traversal order is the reverse of forward traversal. +/// Traversing backwards is possible with \a reverse_iterator /// /// Iteration examples. Each component is separated by ',': /// @code @@ -47,7 +47,8 @@ namespace path { /// ../ => ..,. /// C:\foo\bar => C:,/,foo,bar /// @endcode -class const_iterator { +class const_iterator + : public std::iterator<std::input_iterator_tag, const StringRef> { StringRef Path; ///< The entire path. StringRef Component; ///< The current component. Not necessarily in Path. size_t Position; ///< The iterators current position within Path. @@ -57,26 +58,39 @@ class const_iterator { friend const_iterator end(StringRef path); public: - typedef const StringRef value_type; - typedef ptrdiff_t difference_type; - typedef value_type &reference; - typedef value_type *pointer; - typedef std::bidirectional_iterator_tag iterator_category; - reference operator*() const { return Component; } pointer operator->() const { return &Component; } const_iterator &operator++(); // preincrement const_iterator &operator++(int); // postincrement - const_iterator &operator--(); // predecrement - const_iterator &operator--(int); // postdecrement bool operator==(const const_iterator &RHS) const; - bool operator!=(const const_iterator &RHS) const; + bool operator!=(const const_iterator &RHS) const { return !(*this == RHS); } /// @brief Difference in bytes between this and RHS. ptrdiff_t operator-(const const_iterator &RHS) const; }; -typedef std::reverse_iterator<const_iterator> reverse_iterator; +/// @brief Reverse path iterator. +/// +/// This is an input iterator that iterates over the individual components in +/// \a path in reverse order. The traversal order is exactly reversed from that +/// of \a const_iterator +class reverse_iterator + : public std::iterator<std::input_iterator_tag, const StringRef> { + StringRef Path; ///< The entire path. + StringRef Component; ///< The current component. Not necessarily in Path. + size_t Position; ///< The iterators current position within Path. + + friend reverse_iterator rbegin(StringRef path); + friend reverse_iterator rend(StringRef path); + +public: + reference operator*() const { return Component; } + pointer operator->() const { return &Component; } + reverse_iterator &operator++(); // preincrement + reverse_iterator &operator++(int); // postincrement + bool operator==(const reverse_iterator &RHS) const; + bool operator!=(const reverse_iterator &RHS) const { return !(*this == RHS); } +}; /// @brief Get begin iterator over \a path. /// @param path Input path. @@ -91,16 +105,12 @@ const_iterator end(StringRef path); /// @brief Get reverse begin iterator over \a path. /// @param path Input path. /// @returns Iterator initialized with the first reverse component of \a path. -inline reverse_iterator rbegin(StringRef path) { - return reverse_iterator(end(path)); -} +reverse_iterator rbegin(StringRef path); /// @brief Get reverse end iterator over \a path. /// @param path Input path. /// @returns Iterator initialized to the reverse end of \a path. -inline reverse_iterator rend(StringRef path) { - return reverse_iterator(begin(path)); -} +reverse_iterator rend(StringRef path); /// @} /// @name Lexical Modifiers @@ -194,7 +204,7 @@ void native(SmallVectorImpl<char> &path); /// /// @param path Input path. /// @result The root name of \a path if it has one, otherwise "". -const StringRef root_name(StringRef path); +StringRef root_name(StringRef path); /// @brief Get root directory. /// @@ -207,7 +217,7 @@ const StringRef root_name(StringRef path); /// @param path Input path. /// @result The root directory of \a path if it has one, otherwise /// "". -const StringRef root_directory(StringRef path); +StringRef root_directory(StringRef path); /// @brief Get root path. /// @@ -215,7 +225,7 @@ const StringRef root_directory(StringRef path); /// /// @param path Input path. /// @result The root path of \a path if it has one, otherwise "". -const StringRef root_path(StringRef path); +StringRef root_path(StringRef path); /// @brief Get relative path. /// @@ -227,7 +237,7 @@ const StringRef root_path(StringRef path); /// /// @param path Input path. /// @result The path starting after root_path if one exists, otherwise "". -const StringRef relative_path(StringRef path); +StringRef relative_path(StringRef path); /// @brief Get parent path. /// @@ -239,7 +249,7 @@ const StringRef relative_path(StringRef path); /// /// @param path Input path. /// @result The parent path of \a path if one exists, otherwise "". -const StringRef parent_path(StringRef path); +StringRef parent_path(StringRef path); /// @brief Get filename. /// @@ -253,7 +263,7 @@ const StringRef parent_path(StringRef path); /// @param path Input path. /// @result The filename part of \a path. This is defined as the last component /// of \a path. -const StringRef filename(StringRef path); +StringRef filename(StringRef path); /// @brief Get stem. /// @@ -271,7 +281,7 @@ const StringRef filename(StringRef path); /// /// @param path Input path. /// @result The stem of \a path. -const StringRef stem(StringRef path); +StringRef stem(StringRef path); /// @brief Get extension. /// @@ -287,7 +297,7 @@ const StringRef stem(StringRef path); /// /// @param path Input path. /// @result The extension of \a path. -const StringRef extension(StringRef path); +StringRef extension(StringRef path); /// @brief Check whether the given char is a path separator on the host OS. /// @@ -298,7 +308,7 @@ 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(); +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/Process.h b/include/llvm/Support/Process.h index 30973de..8616679 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -186,6 +186,21 @@ public: ArrayRef<const char *> ArgsFromMain, SpecificBumpPtrAllocator<char> &ArgAllocator); + // This functions ensures that the standard file descriptors (input, output, + // and error) are properly mapped to a file descriptor before we use any of + // them. This should only be called by standalone programs, library + // components should not call this. + static std::error_code FixupStandardFileDescriptors(); + + // This function safely closes a file descriptor. It is not safe to retry + // close(2) when it returns with errno equivalent to EINTR; this is because + // *nixen cannot agree if the file descriptor is, in fact, closed when this + // occurs. + // + // N.B. Some operating systems, due to thread cancellation, cannot properly + // guarantee that it will or will not be closed one way or the other! + static std::error_code SafelyCloseFileDescriptor(int FD); + /// This function determines if the standard input is connected directly /// to a user's input (keyboard probably), rather than coming from a file /// or pipe. diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h index 51279a9..40dc60f 100644 --- a/include/llvm/Support/Program.h +++ b/include/llvm/Support/Program.h @@ -15,6 +15,7 @@ #define LLVM_SUPPORT_PROGRAM_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/Path.h" #include <system_error> @@ -51,17 +52,22 @@ struct ProcessInfo { ProcessInfo(); }; - /// This function attempts to locate a program in the operating - /// system's file system using some pre-determined set of locations to search - /// (e.g. the PATH on Unix). Paths with slashes are returned unmodified. + /// \brief Find the first executable file \p Name in \p Paths. /// - /// It does not perform hashing as a shell would but instead stats each PATH + /// This does not perform hashing as a shell would but instead stats each PATH /// entry individually so should generally be avoided. Core LLVM library /// functions and options should instead require fully specified paths. /// - /// @returns A string containing the path of the program or an empty string if - /// the program could not be found. - std::string FindProgramByName(const std::string& name); + /// \param Name name of the executable to find. If it contains any system + /// slashes, it will be returned as is. + /// \param Paths optional list of paths to search for \p Name. If empty it + /// will use the system PATH environment instead. + /// + /// \returns The fully qualified path to the first \p Name in \p Paths if it + /// exists. \p Name if \p Name has slashes in it. Otherwise an error. + ErrorOr<std::string> + findProgramByName(StringRef Name, + ArrayRef<StringRef> Paths = ArrayRef<StringRef>()); // These functions change the specified standard stream (stdin or stdout) to // binary mode. They return errc::success if the specified stream @@ -82,7 +88,7 @@ struct ProcessInfo { /// -2 indicates a crash during execution or timeout int ExecuteAndWait( StringRef Program, ///< Path of the program to be executed. It is - /// presumed this is the result of the FindProgramByName method. + /// presumed this is the result of the findProgramByName method. 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. @@ -126,6 +132,40 @@ struct ProcessInfo { /// argument length limits. bool argumentsFitWithinSystemLimits(ArrayRef<const char*> Args); + /// File encoding options when writing contents that a non-UTF8 tool will + /// read (on Windows systems). For UNIX, we always use UTF-8. + enum WindowsEncodingMethod { + /// UTF-8 is the LLVM native encoding, being the same as "do not perform + /// encoding conversion". + WEM_UTF8, + WEM_CurrentCodePage, + WEM_UTF16 + }; + + /// Saves the UTF8-encoded \p contents string into the file \p FileName + /// using a specific encoding. + /// + /// This write file function adds the possibility to choose which encoding + /// to use when writing a text file. On Windows, this is important when + /// writing files with internationalization support with an encoding that is + /// different from the one used in LLVM (UTF-8). We use this when writing + /// response files, since GCC tools on MinGW only understand legacy code + /// pages, and VisualStudio tools only understand UTF-16. + /// For UNIX, using different encodings is silently ignored, since all tools + /// work well with UTF-8. + /// This function assumes that you only use UTF-8 *text* data and will convert + /// it to your desired encoding before writing to the file. + /// + /// FIXME: We use EM_CurrentCodePage to write response files for GNU tools in + /// a MinGW/MinGW-w64 environment, which has serious flaws but currently is + /// our best shot to make gcc/ld understand international characters. This + /// should be changed as soon as binutils fix this to support UTF16 on mingw. + /// + /// \returns non-zero error_code if failed + std::error_code + writeFileWithEncoding(StringRef FileName, StringRef Contents, + WindowsEncodingMethod Encoding = WEM_UTF8); + /// This function waits for the process specified by \p PI to finish. /// \returns A \see ProcessInfo struct with Pid set to: /// \li The process id of the child process if the child process has changed diff --git a/include/llvm/Support/RWMutex.h b/include/llvm/Support/RWMutex.h index 935b307..b80b855 100644 --- a/include/llvm/Support/RWMutex.h +++ b/include/llvm/Support/RWMutex.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SYSTEM_RWMUTEX_H -#define LLVM_SYSTEM_RWMUTEX_H +#ifndef LLVM_SUPPORT_RWMUTEX_H +#define LLVM_SUPPORT_RWMUTEX_H #include "llvm/Support/Compiler.h" #include "llvm/Support/Threading.h" @@ -85,14 +85,15 @@ namespace llvm /// indicates whether this mutex should become a no-op when we're not /// running in multithreaded mode. template<bool mt_only> - class SmartRWMutex : public RWMutexImpl { + class SmartRWMutex { + RWMutexImpl impl; unsigned readers, writers; public: - explicit SmartRWMutex() : RWMutexImpl(), readers(0), writers(0) { } + explicit SmartRWMutex() : impl(), readers(0), writers(0) { } - bool reader_acquire() { + bool lock_shared() { if (!mt_only || llvm_is_multithreaded()) - return RWMutexImpl::reader_acquire(); + return impl.reader_acquire(); // Single-threaded debugging code. This would be racy in multithreaded // mode, but provides not sanity checks in single threaded mode. @@ -100,9 +101,9 @@ namespace llvm return true; } - bool reader_release() { + bool unlock_shared() { if (!mt_only || llvm_is_multithreaded()) - return RWMutexImpl::reader_release(); + return impl.reader_release(); // Single-threaded debugging code. This would be racy in multithreaded // mode, but provides not sanity checks in single threaded mode. @@ -111,9 +112,9 @@ namespace llvm return true; } - bool writer_acquire() { + bool lock() { if (!mt_only || llvm_is_multithreaded()) - return RWMutexImpl::writer_acquire(); + return impl.writer_acquire(); // Single-threaded debugging code. This would be racy in multithreaded // mode, but provides not sanity checks in single threaded mode. @@ -122,9 +123,9 @@ namespace llvm return true; } - bool writer_release() { + bool unlock() { if (!mt_only || llvm_is_multithreaded()) - return RWMutexImpl::writer_release(); + return impl.writer_release(); // Single-threaded debugging code. This would be racy in multithreaded // mode, but provides not sanity checks in single threaded mode. @@ -145,11 +146,11 @@ namespace llvm SmartRWMutex<mt_only>& mutex; explicit SmartScopedReader(SmartRWMutex<mt_only>& m) : mutex(m) { - mutex.reader_acquire(); + mutex.lock_shared(); } ~SmartScopedReader() { - mutex.reader_release(); + mutex.unlock_shared(); } }; typedef SmartScopedReader<false> ScopedReader; @@ -160,11 +161,11 @@ namespace llvm SmartRWMutex<mt_only>& mutex; explicit SmartScopedWriter(SmartRWMutex<mt_only>& m) : mutex(m) { - mutex.writer_acquire(); + mutex.lock(); } ~SmartScopedWriter() { - mutex.writer_release(); + mutex.unlock(); } }; typedef SmartScopedWriter<false> ScopedWriter; diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 4717553..f9e114b 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -19,11 +19,11 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SMLoc.h" #include <string> namespace llvm { - class MemoryBuffer; class SourceMgr; class SMDiagnostic; class SMFixIt; @@ -47,10 +47,15 @@ public: private: struct SrcBuffer { /// The memory buffer for the file. - MemoryBuffer *Buffer; + std::unique_ptr<MemoryBuffer> Buffer; /// This is the location of the parent include, or null if at the top level. SMLoc IncludeLoc; + + SrcBuffer() {} + + SrcBuffer(SrcBuffer &&O) + : Buffer(std::move(O.Buffer)), IncludeLoc(O.IncludeLoc) {} }; /// This is all of the buffers that we are reading from. @@ -96,7 +101,7 @@ public: const MemoryBuffer *getMemoryBuffer(unsigned i) const { assert(isValidBufferID(i)); - return Buffers[i - 1].Buffer; + return Buffers[i - 1].Buffer.get(); } unsigned getNumBuffers() const { @@ -115,11 +120,12 @@ public: /// Add a new source buffer to this source manager. This takes ownership of /// the memory buffer. - unsigned AddNewSourceBuffer(MemoryBuffer *F, SMLoc IncludeLoc) { + unsigned AddNewSourceBuffer(std::unique_ptr<MemoryBuffer> F, + SMLoc IncludeLoc) { SrcBuffer NB; - NB.Buffer = F; + NB.Buffer = std::move(F); NB.IncludeLoc = IncludeLoc; - Buffers.push_back(NB); + Buffers.push_back(std::move(NB)); return Buffers.size(); } diff --git a/include/llvm/Support/SpecialCaseList.h b/include/llvm/Support/SpecialCaseList.h index 098b9c7..313212e 100644 --- a/include/llvm/Support/SpecialCaseList.h +++ b/include/llvm/Support/SpecialCaseList.h @@ -56,17 +56,19 @@ class Regex; class StringRef; class SpecialCaseList { - public: +public: /// Parses the special case list from a file. If Path is empty, returns /// an empty special case list. On failure, returns 0 and writes an error /// message to string. - static SpecialCaseList *create(const StringRef Path, std::string &Error); + static std::unique_ptr<SpecialCaseList> create(StringRef Path, + std::string &Error); /// Parses the special case list from a memory buffer. On failure, returns /// 0 and writes an error message to string. - static SpecialCaseList *create(const MemoryBuffer *MB, std::string &Error); + static std::unique_ptr<SpecialCaseList> create(const MemoryBuffer *MB, + std::string &Error); /// Parses the special case list from a file. On failure, reports a fatal /// error. - static SpecialCaseList *createOrDie(const StringRef Path); + static std::unique_ptr<SpecialCaseList> createOrDie(StringRef Path); ~SpecialCaseList(); @@ -75,10 +77,10 @@ class SpecialCaseList { /// @Section:<E>=@Category /// \endcode /// and @Query satisfies a wildcard expression <E>. - bool inSection(const StringRef Section, const StringRef Query, - const StringRef Category = StringRef()) const; + bool inSection(StringRef Section, StringRef Query, + StringRef Category = StringRef()) const; - private: +private: SpecialCaseList(SpecialCaseList const &) LLVM_DELETED_FUNCTION; SpecialCaseList &operator=(SpecialCaseList const &) LLVM_DELETED_FUNCTION; diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h deleted file mode 100644 index 6e71ad4..0000000 --- a/include/llvm/Support/StreamableMemoryObject.h +++ /dev/null @@ -1,178 +0,0 @@ -//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - - -#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H -#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H - -#include "llvm/Support/Compiler.h" -#include "llvm/Support/DataStream.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryObject.h" -#include <cassert> -#include <memory> -#include <vector> - -namespace llvm { - -/// StreamableMemoryObject - Interface to data which might be streamed. -/// Streamability has 2 important implications/restrictions. First, the data -/// might not yet exist in memory when the request is made. This just means -/// that readByte/readBytes might have to block or do some work to get it. -/// More significantly, the exact size of the object might not be known until -/// it has all been fetched. This means that to return the right result, -/// getExtent must also wait for all the data to arrive; therefore it should -/// not be called on objects which are actually streamed (this would defeat -/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be -/// used to test addresses without knowing the exact size of the stream. -/// Finally, getPointer can be used instead of readBytes to avoid extra copying. -class StreamableMemoryObject : public MemoryObject { - public: - /// Destructor - Override as necessary. - virtual ~StreamableMemoryObject(); - - /// getBase - Returns the lowest valid address in the region. - /// - /// @result - The lowest valid address. - uint64_t getBase() const override = 0; - - /// getExtent - Returns the size of the region in bytes. (The region is - /// contiguous, so the highest valid address of the region - /// is getBase() + getExtent() - 1). - /// May block until all bytes in the stream have been read - /// - /// @result - The size of the region. - uint64_t getExtent() const override = 0; - - /// readByte - Tries to read a single byte from the region. - /// May block until (address - base) bytes have been read - /// @param address - The address of the byte, in the same space as getBase(). - /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. - /// @result - 0 if successful; -1 if not. Failure may be due to a - /// bounds violation or an implementation-specific error. - int readByte(uint64_t address, uint8_t *ptr) const override = 0; - - /// readBytes - Tries to read a contiguous range of bytes from the - /// region, up to the end of the region. - /// May block until (address - base + size) bytes have - /// been read. Additionally, StreamableMemoryObjects will - /// not do partial reads - if size bytes cannot be read, - /// readBytes will fail. - /// - /// @param address - The address of the first byte, in the same space as - /// getBase(). - /// @param size - The number of bytes to copy. - /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL - /// and large enough to hold size bytes. - /// @result - 0 if successful; -1 if not. Failure may be due to a - /// bounds violation or an implementation-specific error. - int readBytes(uint64_t address, uint64_t size, - uint8_t *buf) const override = 0; - - /// getPointer - Ensures that the requested data is in memory, and returns - /// A pointer to it. More efficient than using readBytes if the - /// data is already in memory. - /// May block until (address - base + size) bytes have been read - /// @param address - address of the byte, in the same space as getBase() - /// @param size - amount of data that must be available on return - /// @result - valid pointer to the requested data - virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0; - - /// isValidAddress - Returns true if the address is within the object - /// (i.e. between base and base + extent - 1 inclusive) - /// May block until (address - base) bytes have been read - /// @param address - address of the byte, in the same space as getBase() - /// @result - true if the address may be read with readByte() - virtual bool isValidAddress(uint64_t address) const = 0; - - /// isObjectEnd - Returns true if the address is one past the end of the - /// object (i.e. if it is equal to base + extent) - /// May block until (address - base) bytes have been read - /// @param address - address of the byte, in the same space as getBase() - /// @result - true if the address is equal to base + extent - virtual bool isObjectEnd(uint64_t address) const = 0; -}; - -/// StreamingMemoryObject - interface to data which is actually streamed from -/// a DataStreamer. In addition to inherited members, it has the -/// dropLeadingBytes and setKnownObjectSize methods which are not applicable -/// to non-streamed objects. -class StreamingMemoryObject : public StreamableMemoryObject { -public: - StreamingMemoryObject(DataStreamer *streamer); - uint64_t getBase() const override { return 0; } - uint64_t getExtent() const override; - int readByte(uint64_t address, uint8_t *ptr) const override; - int readBytes(uint64_t address, uint64_t size, - uint8_t *buf) const override; - const uint8_t *getPointer(uint64_t address, uint64_t size) const override { - // This could be fixed by ensuring the bytes are fetched and making a copy, - // requiring that the bitcode size be known, or otherwise ensuring that - // the memory doesn't go away/get reallocated, but it's - // not currently necessary. Users that need the pointer don't stream. - llvm_unreachable("getPointer in streaming memory objects not allowed"); - return nullptr; - } - bool isValidAddress(uint64_t address) const override; - bool isObjectEnd(uint64_t address) const override; - - /// Drop s bytes from the front of the stream, pushing the positions of the - /// remaining bytes down by s. This is used to skip past the bitcode header, - /// since we don't know a priori if it's present, and we can't put bytes - /// back into the stream once we've read them. - bool dropLeadingBytes(size_t s); - - /// If the data object size is known in advance, many of the operations can - /// be made more efficient, so this method should be called before reading - /// starts (although it can be called anytime). - void setKnownObjectSize(size_t size); - -private: - const static uint32_t kChunkSize = 4096 * 4; - mutable std::vector<unsigned char> Bytes; - std::unique_ptr<DataStreamer> Streamer; - mutable size_t BytesRead; // Bytes read from stream - size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) - mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached - mutable bool EOFReached; - - // Fetch enough bytes such that Pos can be read or EOF is reached - // (i.e. BytesRead > Pos). Return true if Pos can be read. - // Unlike most of the functions in BitcodeReader, returns true on success. - // Most of the requests will be small, but we fetch at kChunkSize bytes - // at a time to avoid making too many potentially expensive GetBytes calls - bool fetchToPos(size_t Pos) const { - if (EOFReached) return Pos < ObjectSize; - while (Pos >= BytesRead) { - Bytes.resize(BytesRead + BytesSkipped + kChunkSize); - size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], - kChunkSize); - BytesRead += bytes; - if (bytes < kChunkSize) { - assert((!ObjectSize || BytesRead >= Pos) && - "Unexpected short read fetching bitcode"); - if (BytesRead <= Pos) { // reached EOF/ran out of bytes - ObjectSize = BytesRead; - EOFReached = true; - return false; - } - } - } - return true; - } - - StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; - void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; -}; - -StreamableMemoryObject *getNonStreamedMemoryObject( - const unsigned char *Start, const unsigned char *End); - -} -#endif // STREAMABLEMEMORYOBJECT_H_ diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h new file mode 100644 index 0000000..6957c6e --- /dev/null +++ b/include/llvm/Support/StreamingMemoryObject.h @@ -0,0 +1,91 @@ +//===- StreamingMemoryObject.h - Streamable data interface -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_STREAMINGMEMORYOBJECT_H +#define LLVM_SUPPORT_STREAMINGMEMORYOBJECT_H + +#include "llvm/Support/Compiler.h" +#include "llvm/Support/DataStream.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MemoryObject.h" +#include <cassert> +#include <memory> +#include <vector> + +namespace llvm { + +/// Interface to data which is actually streamed from a DataStreamer. In +/// addition to inherited members, it has the dropLeadingBytes and +/// setKnownObjectSize methods which are not applicable to non-streamed objects. +class StreamingMemoryObject : public MemoryObject { +public: + StreamingMemoryObject(DataStreamer *streamer); + uint64_t getExtent() const override; + uint64_t readBytes(uint8_t *Buf, uint64_t Size, + uint64_t Address) const override; + const uint8_t *getPointer(uint64_t address, uint64_t size) const override { + // This could be fixed by ensuring the bytes are fetched and making a copy, + // requiring that the bitcode size be known, or otherwise ensuring that + // the memory doesn't go away/get reallocated, but it's + // not currently necessary. Users that need the pointer don't stream. + llvm_unreachable("getPointer in streaming memory objects not allowed"); + return nullptr; + } + bool isValidAddress(uint64_t address) const override; + + /// Drop s bytes from the front of the stream, pushing the positions of the + /// remaining bytes down by s. This is used to skip past the bitcode header, + /// since we don't know a priori if it's present, and we can't put bytes + /// back into the stream once we've read them. + bool dropLeadingBytes(size_t s); + + /// If the data object size is known in advance, many of the operations can + /// be made more efficient, so this method should be called before reading + /// starts (although it can be called anytime). + void setKnownObjectSize(size_t size); + +private: + const static uint32_t kChunkSize = 4096 * 4; + mutable std::vector<unsigned char> Bytes; + std::unique_ptr<DataStreamer> Streamer; + mutable size_t BytesRead; // Bytes read from stream + size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) + mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached + mutable bool EOFReached; + + // Fetch enough bytes such that Pos can be read or EOF is reached + // (i.e. BytesRead > Pos). Return true if Pos can be read. + // Unlike most of the functions in BitcodeReader, returns true on success. + // Most of the requests will be small, but we fetch at kChunkSize bytes + // at a time to avoid making too many potentially expensive GetBytes calls + bool fetchToPos(size_t Pos) const { + if (EOFReached) return Pos < ObjectSize; + while (Pos >= BytesRead) { + Bytes.resize(BytesRead + BytesSkipped + kChunkSize); + size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], + kChunkSize); + BytesRead += bytes; + if (BytesRead <= Pos) { // reached EOF/ran out of bytes + ObjectSize = BytesRead; + EOFReached = true; + return false; + } + } + return true; + } + + StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; + void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; +}; + +MemoryObject *getNonStreamedMemoryObject( + const unsigned char *Start, const unsigned char *End); + +} +#endif // STREAMINGMEMORYOBJECT_H_ diff --git a/include/llvm/Support/StringRefMemoryObject.h b/include/llvm/Support/StringRefMemoryObject.h deleted file mode 100644 index 8a349ea..0000000 --- a/include/llvm/Support/StringRefMemoryObject.h +++ /dev/null @@ -1,41 +0,0 @@ -//===- llvm/Support/StringRefMemoryObject.h ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains the declaration of the StringRefMemObject class, a simple -// wrapper around StringRef implementing the MemoryObject interface. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H -#define LLVM_SUPPORT_STRINGREFMEMORYOBJECT_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryObject.h" - -namespace llvm { - -/// StringRefMemoryObject - Simple StringRef-backed MemoryObject -class StringRefMemoryObject : public MemoryObject { - StringRef Bytes; - uint64_t Base; -public: - StringRefMemoryObject(StringRef Bytes, uint64_t Base = 0) - : Bytes(Bytes), Base(Base) {} - - uint64_t getBase() const override { return Base; } - uint64_t getExtent() const override { return Bytes.size(); } - - int readByte(uint64_t Addr, uint8_t *Byte) const override; - int readBytes(uint64_t Addr, uint64_t Size, uint8_t *Buf) const override; -}; - -} - -#endif diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h index 340954f..9c5a3c5 100644 --- a/include/llvm/Support/SwapByteOrder.h +++ b/include/llvm/Support/SwapByteOrder.h @@ -15,6 +15,7 @@ #ifndef LLVM_SUPPORT_SWAPBYTEORDER_H #define LLVM_SUPPORT_SWAPBYTEORDER_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" #include <cstddef> #include <limits> @@ -39,8 +40,7 @@ inline uint16_t SwapByteOrder_16(uint16_t value) { /// SwapByteOrder_32 - This function returns a byte-swapped representation of /// the 32-bit argument. inline uint32_t SwapByteOrder_32(uint32_t value) { -#if defined(__llvm__) || \ -(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) +#if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) return __builtin_bswap32(value); #elif defined(_MSC_VER) && !defined(_DEBUG) return _byteswap_ulong(value); @@ -56,8 +56,7 @@ inline uint32_t SwapByteOrder_32(uint32_t value) { /// SwapByteOrder_64 - This function returns a byte-swapped representation of /// the 64-bit argument. inline uint64_t SwapByteOrder_64(uint64_t value) { -#if defined(__llvm__) || \ -(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__ICC) +#if defined(__llvm__) || (LLVM_GNUC_PREREQ(4, 3, 0) && !defined(__ICC)) return __builtin_bswap64(value); #elif defined(_MSC_VER) && !defined(_DEBUG) return _byteswap_uint64(value); diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h index 5d5b86a..8ac4b90 100644 --- a/include/llvm/Support/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -123,15 +123,10 @@ namespace llvm { const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx); - typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T, - StringRef TT, - MCContext &Ctx, - MCAsmBackend &TAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - const MCSubtargetInfo &STI, - bool RelaxAll, - bool NoExecStack); + typedef MCStreamer *(*MCObjectStreamerCtorTy)( + const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB, + raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI, + bool RelaxAll); typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, @@ -423,18 +418,15 @@ namespace llvm { /// \param _OS The stream object. /// \param _Emitter The target independent assembler object.Takes ownership. /// \param RelaxAll Relax all fixups? - /// \param NoExecStack Mark file as not needing a executable stack. MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx, - MCAsmBackend &TAB, - raw_ostream &_OS, + MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI, - bool RelaxAll, - bool NoExecStack) const { + bool RelaxAll) const { if (!MCObjectStreamerCtorFn) return nullptr; return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI, - RelaxAll, NoExecStack); + RelaxAll); } /// createAsmStreamer - Create a target specific MCStreamer. diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h index ee0e286..6bca58b 100644 --- a/include/llvm/Support/TimeValue.h +++ b/include/llvm/Support/TimeValue.h @@ -38,28 +38,38 @@ namespace sys { /// value permissible by the class. MinTime is some point /// in the distant past, about 300 billion years BCE. /// @brief The smallest possible time value. - static const TimeValue MinTime; + static TimeValue MinTime() { + return TimeValue ( INT64_MIN,0 ); + } /// A constant TimeValue representing the largest time /// value permissible by the class. MaxTime is some point /// in the distant future, about 300 billion years AD. /// @brief The largest possible time value. - static const TimeValue MaxTime; + static TimeValue MaxTime() { + return TimeValue ( INT64_MAX,0 ); + } /// A constant TimeValue representing the base time, /// or zero time of 00:00:00 (midnight) January 1st, 2000. /// @brief 00:00:00 Jan 1, 2000 UTC. - static const TimeValue ZeroTime; + static TimeValue ZeroTime() { + return TimeValue ( 0,0 ); + } /// A constant TimeValue for the Posix base time which is /// 00:00:00 (midnight) January 1st, 1970. /// @brief 00:00:00 Jan 1, 1970 UTC. - static const TimeValue PosixZeroTime; + static TimeValue PosixZeroTime() { + return TimeValue ( PosixZeroTimeSeconds,0 ); + } /// A constant TimeValue for the Win32 base time which is /// 00:00:00 (midnight) January 1st, 1601. /// @brief 00:00:00 Jan 1, 1601 UTC. - static const TimeValue Win32ZeroTime; + static TimeValue Win32ZeroTime() { + return TimeValue ( Win32ZeroTimeSeconds,0 ); + } /// @} /// @name Types diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h index 88f8ccc..d98e7bb 100644 --- a/include/llvm/Support/ToolOutputFile.h +++ b/include/llvm/Support/ToolOutputFile.h @@ -29,13 +29,13 @@ class tool_output_file { /// destructed after the raw_fd_ostream is destructed. It installs /// cleanups in its constructor and uninstalls them in its destructor. class CleanupInstaller { - /// Filename - The name of the file. + /// The name of the file. std::string Filename; public: - /// Keep - The flag which indicates whether we should not delete the file. + /// The flag which indicates whether we should not delete the file. bool Keep; - explicit CleanupInstaller(const char *filename); + explicit CleanupInstaller(StringRef ilename); ~CleanupInstaller(); } Installer; @@ -44,12 +44,12 @@ class tool_output_file { raw_fd_ostream OS; public: - /// tool_output_file - This constructor's arguments are passed to - /// to raw_fd_ostream's constructor. - tool_output_file(const char *filename, std::string &ErrorInfo, + /// This constructor's arguments are passed to to raw_fd_ostream's + /// constructor. + tool_output_file(StringRef Filename, std::error_code &EC, sys::fs::OpenFlags Flags); - tool_output_file(const char *Filename, int FD); + tool_output_file(StringRef Filename, int FD); /// os - Return the contained raw_fd_ostream. raw_fd_ostream &os() { return OS; } diff --git a/include/llvm/Support/UniqueLock.h b/include/llvm/Support/UniqueLock.h new file mode 100644 index 0000000..5a4c273 --- /dev/null +++ b/include/llvm/Support/UniqueLock.h @@ -0,0 +1,67 @@ +//===-- Support/UniqueLock.h - Acquire/Release Mutex In Scope ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a guard for a block of code that ensures a Mutex is locked +// upon construction and released upon destruction. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_UNIQUE_LOCK_H +#define LLVM_SUPPORT_UNIQUE_LOCK_H + +#include "llvm/Support/Mutex.h" + +namespace llvm { + /// A pared-down imitation of std::unique_lock from C++11. Contrary to the + /// name, it's really more of a wrapper for a lock. It may or may not have + /// an associated mutex, which is guaranteed to be locked upon creation + /// and unlocked after destruction. unique_lock can also unlock the mutex + /// and re-lock it freely during its lifetime. + /// @brief Guard a section of code with a mutex. + template<typename MutexT> + class unique_lock { + MutexT *M; + bool locked; + + unique_lock(const unique_lock &) LLVM_DELETED_FUNCTION; + void operator=(const unique_lock &) LLVM_DELETED_FUNCTION; + public: + unique_lock() : M(nullptr), locked(false) {} + explicit unique_lock(MutexT &m) : M(&m), locked(true) { M->lock(); } + + void operator=(unique_lock &&o) { + if (owns_lock()) + M->unlock(); + M = o.M; + locked = o.locked; + o.M = nullptr; + o.locked = false; + } + + ~unique_lock() { if (owns_lock()) M->unlock(); } + + void lock() { + assert(!locked && "mutex already locked!"); + assert(M && "no associated mutex!"); + M->lock(); + locked = true; + } + + void unlock() { + assert(locked && "unlocking a mutex that isn't locked!"); + assert(M && "no associated mutex!"); + M->unlock(); + locked = false; + } + + bool owns_lock() { return locked; } + }; +} + +#endif // LLVM_SUPPORT_UNIQUE_LOCK_H diff --git a/include/llvm/Support/Win64EH.h b/include/llvm/Support/Win64EH.h index 7ca218e..f6c4927 100644 --- a/include/llvm/Support/Win64EH.h +++ b/include/llvm/Support/Win64EH.h @@ -40,8 +40,8 @@ enum UnwindOpcodes { /// or part thereof. union UnwindCode { struct { - support::ulittle8_t CodeOffset; - support::ulittle8_t UnwindOpAndOpInfo; + uint8_t CodeOffset; + uint8_t UnwindOpAndOpInfo; } u; support::ulittle16_t FrameOffset; @@ -74,10 +74,10 @@ struct RuntimeFunction { /// UnwindInfo - An entry in the exception table. struct UnwindInfo { - support::ulittle8_t VersionAndFlags; - support::ulittle8_t PrologSize; - support::ulittle8_t NumCodes; - support::ulittle8_t FrameRegisterAndOffset; + uint8_t VersionAndFlags; + uint8_t PrologSize; + uint8_t NumCodes; + uint8_t FrameRegisterAndOffset; UnwindCode UnwindCodes[1]; uint8_t getVersion() const { diff --git a/include/llvm/Support/WindowsError.h b/include/llvm/Support/WindowsError.h index 0e909a0..63bfe59 100644 --- a/include/llvm/Support/WindowsError.h +++ b/include/llvm/Support/WindowsError.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_WINDOWS_ERROR_H -#define LLVM_SUPPORT_WINDOWS_ERROR_H +#ifndef LLVM_SUPPORT_WINDOWSERROR_H +#define LLVM_SUPPORT_WINDOWSERROR_H #include <system_error> diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h index c39874c..de6e654 100644 --- a/include/llvm/Support/YAMLParser.h +++ b/include/llvm/Support/YAMLParser.h @@ -41,13 +41,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SMLoc.h" #include <limits> #include <map> #include <utility> namespace llvm { -class MemoryBuffer; class SourceMgr; class raw_ostream; class Twine; @@ -79,8 +79,7 @@ public: /// \brief This keeps a reference to the string referenced by \p Input. Stream(StringRef Input, SourceMgr &); - /// \brief This takes ownership of \p InputBuffer. - Stream(MemoryBuffer *InputBuffer, SourceMgr &); + Stream(MemoryBufferRef InputBuffer, SourceMgr &); ~Stream(); document_iterator begin(); diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index a23faf6..023dcee7 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -943,16 +943,17 @@ private: }; class MapHNode : public HNode { + virtual void anchor(); + public: MapHNode(Node *n) : HNode(n) { } - virtual ~MapHNode(); static inline bool classof(const HNode *n) { return MappingNode::classof(n->_node); } static inline bool classof(const MapHNode *) { return true; } - typedef llvm::StringMap<HNode*> NameToNode; + typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode; bool isValidKey(StringRef key); @@ -961,19 +962,20 @@ private: }; class SequenceHNode : public HNode { + virtual void anchor(); + public: SequenceHNode(Node *n) : HNode(n) { } - virtual ~SequenceHNode(); static inline bool classof(const HNode *n) { return SequenceNode::classof(n->_node); } static inline bool classof(const SequenceHNode *) { return true; } - std::vector<HNode*> Entries; + std::vector<std::unique_ptr<HNode>> Entries; }; - Input::HNode *createHNodes(Node *node); + std::unique_ptr<Input::HNode> createHNodes(Node *node); void setError(HNode *hnode, const Twine &message); void setError(Node *node, const Twine &message); diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 34fbe08..c9ef637 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -17,9 +17,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" +#include <system_error> namespace llvm { class format_object_base; + class FormattedString; + class FormattedNumber; template <typename T> class SmallVectorImpl; @@ -210,6 +213,12 @@ public: // Formatted output, see the format() function in Support/Format.h. raw_ostream &operator<<(const format_object_base &Fmt); + // Formatted output, see the leftJustify() function in Support/Format.h. + raw_ostream &operator<<(const FormattedString &); + + // Formatted output, see the formatHex() function in Support/Format.h. + raw_ostream &operator<<(const FormattedNumber &); + /// indent - Insert 'NumSpaces' spaces. raw_ostream &indent(unsigned NumSpaces); @@ -341,17 +350,17 @@ class raw_fd_ostream : public raw_ostream { void error_detected() { Error = true; } public: - /// raw_fd_ostream - Open the specified file for writing. If an error occurs, - /// information about the error is put into ErrorInfo, and the stream should - /// be immediately destroyed; the string will be empty if no error occurred. - /// This allows optional flags to control how the file will be opened. + /// Open the specified file for writing. If an error occurs, information + /// about the error is put into EC, and the stream should be immediately + /// destroyed; + /// \p Flags allows optional flags to control how the file will be opened. /// /// As a special case, if Filename is "-", then the stream will use /// STDOUT_FILENO instead of opening a file. Note that it will still consider /// itself to own the file descriptor. In particular, it will close the /// file descriptor when it is done (this is necessary to detect /// output errors). - raw_fd_ostream(const char *Filename, std::string &ErrorInfo, + raw_fd_ostream(StringRef Filename, std::error_code &EC, sys::fs::OpenFlags Flags); /// raw_fd_ostream ctor - FD is the file descriptor that this writes to. If |