summaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp4
-rw-r--r--lib/Support/CachePruning.cpp4
-rw-r--r--lib/Support/MemoryBuffer.cpp162
-rw-r--r--lib/Support/StringRef.cpp2
-rw-r--r--lib/Support/TargetParser.cpp5
-rw-r--r--lib/Support/YAMLTraits.cpp7
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"));