diff options
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/APFloat.cpp | 4 | ||||
-rw-r--r-- | lib/Support/CachePruning.cpp | 4 | ||||
-rw-r--r-- | lib/Support/MemoryBuffer.cpp | 162 | ||||
-rw-r--r-- | lib/Support/StringRef.cpp | 2 | ||||
-rw-r--r-- | lib/Support/TargetParser.cpp | 5 | ||||
-rw-r--r-- | lib/Support/YAMLTraits.cpp | 7 |
6 files changed, 110 insertions, 74 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index f7fb0cef16bf4..3489feb93a02b 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -2546,12 +2546,12 @@ IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) { } bool IEEEFloat::convertFromStringSpecials(StringRef str) { - if (str.equals("inf") || str.equals("INFINITY")) { + if (str.equals("inf") || str.equals("INFINITY") || str.equals("+Inf")) { makeInf(false); return true; } - if (str.equals("-inf") || str.equals("-INFINITY")) { + if (str.equals("-inf") || str.equals("-INFINITY") || str.equals("-Inf")) { makeInf(true); return true; } diff --git a/lib/Support/CachePruning.cpp b/lib/Support/CachePruning.cpp index 3e97c991f5047..141573c2a1c73 100644 --- a/lib/Support/CachePruning.cpp +++ b/lib/Support/CachePruning.cpp @@ -165,12 +165,14 @@ bool llvm::pruneCache(StringRef Path, CachePruningPolicy Policy) { return false; } } else { + if (!Policy.Interval) + return false; if (Policy.Interval != seconds(0)) { // Check whether the time stamp is older than our pruning interval. // If not, do nothing. const auto TimeStampModTime = FileStatus.getLastModificationTime(); auto TimeStampAge = CurrentTime - TimeStampModTime; - if (TimeStampAge <= Policy.Interval) { + if (TimeStampAge <= *Policy.Interval) { DEBUG(dbgs() << "Timestamp file too recent (" << duration_cast<seconds>(TimeStampAge).count() << "s old), do not prune.\n"); diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index 85e782b2c048a..c709fc416df60 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -80,10 +80,12 @@ void *operator new(size_t N, const NamedBufferAlloc &Alloc) { namespace { /// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory. -class MemoryBufferMem : public MemoryBuffer { +template<typename MB> +class MemoryBufferMem : public MB { public: MemoryBufferMem(StringRef InputData, bool RequiresNullTerminator) { - init(InputData.begin(), InputData.end(), RequiresNullTerminator); + MemoryBuffer::init(InputData.begin(), InputData.end(), + RequiresNullTerminator); } /// Disable sized deallocation for MemoryBufferMem, because it has @@ -95,21 +97,22 @@ public: return StringRef(reinterpret_cast<const char *>(this + 1)); } - BufferKind getBufferKind() const override { - return MemoryBuffer_Malloc; + MemoryBuffer::BufferKind getBufferKind() const override { + return MemoryBuffer::MemoryBuffer_Malloc; } }; } -static ErrorOr<std::unique_ptr<MemoryBuffer>> -getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, +template <typename MB> +static ErrorOr<std::unique_ptr<MB>> +getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile); std::unique_ptr<MemoryBuffer> MemoryBuffer::getMemBuffer(StringRef InputData, StringRef BufferName, bool RequiresNullTerminator) { auto *Ret = new (NamedBufferAlloc(BufferName)) - MemoryBufferMem(InputData, RequiresNullTerminator); + MemoryBufferMem<MemoryBuffer>(InputData, RequiresNullTerminator); return std::unique_ptr<MemoryBuffer>(Ret); } @@ -119,50 +122,30 @@ MemoryBuffer::getMemBuffer(MemoryBufferRef Ref, bool RequiresNullTerminator) { Ref.getBuffer(), Ref.getBufferIdentifier(), RequiresNullTerminator)); } -std::unique_ptr<MemoryBuffer> -MemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) { - std::unique_ptr<MemoryBuffer> Buf = - getNewUninitMemBuffer(InputData.size(), BufferName); +static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> +getMemBufferCopyImpl(StringRef InputData, const Twine &BufferName) { + auto Buf = WritableMemoryBuffer::getNewUninitMemBuffer(InputData.size(), BufferName); if (!Buf) - return nullptr; - memcpy(const_cast<char*>(Buf->getBufferStart()), InputData.data(), - InputData.size()); - return Buf; + return make_error_code(errc::not_enough_memory); + memcpy(Buf->getBufferStart(), InputData.data(), InputData.size()); + return std::move(Buf); } std::unique_ptr<MemoryBuffer> -MemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName) { - // Allocate space for the MemoryBuffer, the data and the name. It is important - // that MemoryBuffer and data are aligned so PointerIntPair works with them. - // TODO: Is 16-byte alignment enough? We copy small object files with large - // alignment expectations into this buffer. - SmallString<256> NameBuf; - StringRef NameRef = BufferName.toStringRef(NameBuf); - size_t AlignedStringLen = - alignTo(sizeof(MemoryBufferMem) + NameRef.size() + 1, 16); - size_t RealLen = AlignedStringLen + Size + 1; - char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); - if (!Mem) - return nullptr; - - // The name is stored after the class itself. - CopyStringRef(Mem + sizeof(MemoryBufferMem), NameRef); - - // The buffer begins after the name and must be aligned. - char *Buf = Mem + AlignedStringLen; - Buf[Size] = 0; // Null terminate buffer. - - auto *Ret = new (Mem) MemoryBufferMem(StringRef(Buf, Size), true); - return std::unique_ptr<MemoryBuffer>(Ret); +MemoryBuffer::getMemBufferCopy(StringRef InputData, const Twine &BufferName) { + auto Buf = getMemBufferCopyImpl(InputData, BufferName); + if (Buf) + return std::move(*Buf); + return nullptr; } std::unique_ptr<MemoryBuffer> MemoryBuffer::getNewMemBuffer(size_t Size, StringRef BufferName) { - std::unique_ptr<MemoryBuffer> SB = getNewUninitMemBuffer(Size, BufferName); + auto SB = WritableMemoryBuffer::getNewUninitMemBuffer(Size, BufferName); if (!SB) return nullptr; - memset(const_cast<char*>(SB->getBufferStart()), 0, Size); - return SB; + memset(SB->getBufferStart(), 0, Size); + return std::move(SB); } ErrorOr<std::unique_ptr<MemoryBuffer>> @@ -179,10 +162,10 @@ MemoryBuffer::getFileOrSTDIN(const Twine &Filename, int64_t FileSize, ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getFileSlice(const Twine &FilePath, uint64_t MapSize, uint64_t Offset, bool IsVolatile) { - return getFileAux(FilePath, -1, MapSize, Offset, false, IsVolatile); + return getFileAux<MemoryBuffer>(FilePath, -1, MapSize, Offset, false, + IsVolatile); } - //===----------------------------------------------------------------------===// // MemoryBuffer::getFile implementation. //===----------------------------------------------------------------------===// @@ -191,7 +174,8 @@ namespace { /// \brief Memory maps a file descriptor using sys::fs::mapped_file_region. /// /// This handles converting the offset into a legal offset on the platform. -class MemoryBufferMMapFile : public MemoryBuffer { +template<typename MB> +class MemoryBufferMMapFile : public MB { sys::fs::mapped_file_region MFR; static uint64_t getLegalMapOffset(uint64_t Offset) { @@ -209,11 +193,13 @@ class MemoryBufferMMapFile : public MemoryBuffer { public: MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len, uint64_t Offset, std::error_code &EC) - : MFR(FD, sys::fs::mapped_file_region::readonly, + : MFR(FD, + MB::Writable ? sys::fs::mapped_file_region::priv + : sys::fs::mapped_file_region::readonly, getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) { if (!EC) { const char *Start = getStart(Len, Offset); - init(Start, Start + Len, RequiresNullTerminator); + MemoryBuffer::init(Start, Start + Len, RequiresNullTerminator); } } @@ -226,13 +212,13 @@ public: return StringRef(reinterpret_cast<const char *>(this + 1)); } - BufferKind getBufferKind() const override { - return MemoryBuffer_MMap; + MemoryBuffer::BufferKind getBufferKind() const override { + return MemoryBuffer::MemoryBuffer_MMap; } }; } -static ErrorOr<std::unique_ptr<MemoryBuffer>> +static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> getMemoryBufferForStream(int FD, const Twine &BufferName) { const ssize_t ChunkSize = 4096*4; SmallString<ChunkSize> Buffer; @@ -246,37 +232,80 @@ getMemoryBufferForStream(int FD, const Twine &BufferName) { Buffer.set_size(Buffer.size() + ReadBytes); } while (ReadBytes != 0); - return MemoryBuffer::getMemBufferCopy(Buffer, BufferName); + return getMemBufferCopyImpl(Buffer, BufferName); } ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getFile(const Twine &Filename, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) { - return getFileAux(Filename, FileSize, FileSize, 0, - RequiresNullTerminator, IsVolatile); + return getFileAux<MemoryBuffer>(Filename, FileSize, FileSize, 0, + RequiresNullTerminator, IsVolatile); } -static ErrorOr<std::unique_ptr<MemoryBuffer>> +template <typename MB> +static ErrorOr<std::unique_ptr<MB>> getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatile); -static ErrorOr<std::unique_ptr<MemoryBuffer>> +template <typename MB> +static ErrorOr<std::unique_ptr<MB>> getFileAux(const Twine &Filename, int64_t FileSize, uint64_t MapSize, uint64_t Offset, bool RequiresNullTerminator, bool IsVolatile) { int FD; std::error_code EC = sys::fs::openFileForRead(Filename, FD); + if (EC) return EC; - ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = - getOpenFileImpl(FD, Filename, FileSize, MapSize, Offset, - RequiresNullTerminator, IsVolatile); + auto Ret = getOpenFileImpl<MB>(FD, Filename, FileSize, MapSize, Offset, + RequiresNullTerminator, IsVolatile); close(FD); return Ret; } +ErrorOr<std::unique_ptr<WritableMemoryBuffer>> +WritableMemoryBuffer::getFile(const Twine &Filename, int64_t FileSize, + bool IsVolatile) { + return getFileAux<WritableMemoryBuffer>(Filename, FileSize, FileSize, 0, + /*RequiresNullTerminator*/ false, + IsVolatile); +} + +ErrorOr<std::unique_ptr<WritableMemoryBuffer>> +WritableMemoryBuffer::getFileSlice(const Twine &Filename, uint64_t MapSize, + uint64_t Offset, bool IsVolatile) { + return getFileAux<WritableMemoryBuffer>(Filename, -1, MapSize, Offset, false, + IsVolatile); +} + +std::unique_ptr<WritableMemoryBuffer> +WritableMemoryBuffer::getNewUninitMemBuffer(size_t Size, const Twine &BufferName) { + using MemBuffer = MemoryBufferMem<WritableMemoryBuffer>; + // Allocate space for the MemoryBuffer, the data and the name. It is important + // that MemoryBuffer and data are aligned so PointerIntPair works with them. + // TODO: Is 16-byte alignment enough? We copy small object files with large + // alignment expectations into this buffer. + SmallString<256> NameBuf; + StringRef NameRef = BufferName.toStringRef(NameBuf); + size_t AlignedStringLen = alignTo(sizeof(MemBuffer) + NameRef.size() + 1, 16); + size_t RealLen = AlignedStringLen + Size + 1; + char *Mem = static_cast<char*>(operator new(RealLen, std::nothrow)); + if (!Mem) + return nullptr; + + // The name is stored after the class itself. + CopyStringRef(Mem + sizeof(MemBuffer), NameRef); + + // The buffer begins after the name and must be aligned. + char *Buf = Mem + AlignedStringLen; + Buf[Size] = 0; // Null terminate buffer. + + auto *Ret = new (Mem) MemBuffer(StringRef(Buf, Size), true); + return std::unique_ptr<WritableMemoryBuffer>(Ret); +} + static bool shouldUseMmap(int FD, size_t FileSize, size_t MapSize, @@ -332,7 +361,8 @@ static bool shouldUseMmap(int FD, return true; } -static ErrorOr<std::unique_ptr<MemoryBuffer>> +template <typename MB> +static ErrorOr<std::unique_ptr<MB>> getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator, bool IsVolatile) { @@ -364,22 +394,21 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, PageSize, IsVolatile)) { std::error_code EC; - std::unique_ptr<MemoryBuffer> Result( - new (NamedBufferAlloc(Filename)) - MemoryBufferMMapFile(RequiresNullTerminator, FD, MapSize, Offset, EC)); + std::unique_ptr<MB> Result( + new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile<MB>( + RequiresNullTerminator, FD, MapSize, Offset, EC)); if (!EC) return std::move(Result); } - std::unique_ptr<MemoryBuffer> Buf = - MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); + auto Buf = WritableMemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); if (!Buf) { // Failed to create a buffer. The only way it can fail is if // new(std::nothrow) returns 0. return make_error_code(errc::not_enough_memory); } - char *BufPtr = const_cast<char *>(Buf->getBufferStart()); + char *BufPtr = Buf.get()->getBufferStart(); size_t BytesLeft = MapSize; #ifndef HAVE_PREAD @@ -412,7 +441,7 @@ getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize, ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getOpenFile(int FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) { - return getOpenFileImpl(FD, Filename, FileSize, FileSize, 0, + return getOpenFileImpl<MemoryBuffer>(FD, Filename, FileSize, FileSize, 0, RequiresNullTerminator, IsVolatile); } @@ -420,7 +449,8 @@ ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getOpenFileSlice(int FD, const Twine &Filename, uint64_t MapSize, int64_t Offset, bool IsVolatile) { assert(MapSize != uint64_t(-1)); - return getOpenFileImpl(FD, Filename, -1, MapSize, Offset, false, IsVolatile); + return getOpenFileImpl<MemoryBuffer>(FD, Filename, -1, MapSize, Offset, false, + IsVolatile); } ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() { diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index 90992fce0bcc5..9ba7a09f99624 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -586,7 +586,7 @@ bool StringRef::getAsDouble(double &Result, bool AllowInexact) const { APFloat::opStatus Status = F.convertFromString(*this, APFloat::rmNearestTiesToEven); if (Status != APFloat::opOK) { - if (!AllowInexact || Status != APFloat::opInexact) + if (!AllowInexact || !(Status & APFloat::opInexact)) return true; } diff --git a/lib/Support/TargetParser.cpp b/lib/Support/TargetParser.cpp index c59068cb3550b..b96ca084e9bf5 100644 --- a/lib/Support/TargetParser.cpp +++ b/lib/Support/TargetParser.cpp @@ -537,7 +537,7 @@ StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) { } unsigned llvm::AArch64::checkArchVersion(StringRef Arch) { - if (Arch[0] == 'v' && std::isdigit(Arch[1])) + if (Arch.size() >= 2 && Arch[0] == 'v' && std::isdigit(Arch[1])) return (Arch[1] - 48); return 0; } @@ -633,7 +633,7 @@ StringRef llvm::ARM::getCanonicalArchName(StringRef Arch) { // Only match non-marketing names if (offset != StringRef::npos) { // Must start with 'vN'. - if (A[0] != 'v' || !std::isdigit(A[1])) + if (A.size() >= 2 && (A[0] != 'v' || !std::isdigit(A[1]))) return Error; // Can't have an extra 'eb'. if (A.find("eb") != StringRef::npos) @@ -739,7 +739,6 @@ ARM::ProfileKind ARM::parseArchProfile(StringRef Arch) { case ARM::ArchKind::ARMV8_2A: case ARM::ArchKind::ARMV8_3A: return ARM::ProfileKind::A; - LLVM_FALLTHROUGH; case ARM::ArchKind::ARMV2: case ARM::ArchKind::ARMV2A: case ARM::ArchKind::ARMV3: diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp index 05ca40f03018a..f8a80ba87873f 100644 --- a/lib/Support/YAMLTraits.cpp +++ b/lib/Support/YAMLTraits.cpp @@ -657,7 +657,12 @@ void Output::scalarString(StringRef &S, QuotingType MustQuote) { } i = j + 1; } else if (MustQuote == QuotingType::Double && - !sys::unicode::isPrintable(S[j])) { + !sys::unicode::isPrintable(S[j]) && (S[j] & 0x80) == 0) { + // If we're double quoting non-printable characters, we prefer printing + // them as "\x" + their hex representation. Note that special casing is + // needed for UTF-8, where a byte may be part of a UTF-8 sequence and + // appear as non-printable, in which case we want to print the correct + // unicode character and not its hex representation. output(StringRef(&Base[i], j - i)); // "flush" output(StringLiteral("\\x")); |