diff --git a/llvm/include/llvm/Support/FileOutputBuffer.h b/llvm/include/llvm/Support/FileOutputBuffer.h --- a/llvm/include/llvm/Support/FileOutputBuffer.h +++ b/llvm/include/llvm/Support/FileOutputBuffer.h @@ -32,6 +32,9 @@ enum { /// set the 'x' bit on the resulting file F_executable = 1, + + /// Always use an in-memory buffer instead of an on-disk buffer. + F_in_memory = 2, }; /// Factory method to create an OutputBuffer object which manages a read/write diff --git a/llvm/lib/Support/FileOutputBuffer.cpp b/llvm/lib/Support/FileOutputBuffer.cpp --- a/llvm/lib/Support/FileOutputBuffer.cpp +++ b/llvm/lib/Support/FileOutputBuffer.cpp @@ -189,7 +189,10 @@ case fs::file_type::regular_file: case fs::file_type::file_not_found: case fs::file_type::status_error: - return createOnDiskBuffer(Path, Size, Mode); + if (Flags & F_in_memory) + return createInMemoryBuffer(Path, Size, Mode); + else + return createOnDiskBuffer(Path, Size, Mode); default: return createInMemoryBuffer(Path, Size, Mode); } diff --git a/llvm/unittests/Support/FileOutputBufferTest.cpp b/llvm/unittests/Support/FileOutputBufferTest.cpp --- a/llvm/unittests/Support/FileOutputBufferTest.cpp +++ b/llvm/unittests/Support/FileOutputBufferTest.cpp @@ -118,6 +118,28 @@ EXPECT_TRUE(IsExecutable); ASSERT_NO_ERROR(fs::remove(File4.str())); + // TEST 5: In-memory buffer works as expected. + SmallString<128> File5(TestDirectory); + File5.append("/file5"); + { + Expected> BufferOrErr = + FileOutputBuffer::create(File5, 8000, FileOutputBuffer::F_in_memory); + ASSERT_NO_ERROR(errorToErrorCode(BufferOrErr.takeError())); + std::unique_ptr &Buffer = *BufferOrErr; + // Start buffer with special header. + memcpy(Buffer->getBufferStart(), "AABBCCDDEEFFGGHHIIJJ", 20); + ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit())); + // Write to end of buffer to verify it is writable. + memcpy(Buffer->getBufferEnd() - 20, "AABBCCDDEEFFGGHHIIJJ", 20); + // Commit buffer. + ASSERT_NO_ERROR(errorToErrorCode(Buffer->commit())); + } + + // Verify file is correct size. + uint64_t File5Size; + ASSERT_NO_ERROR(fs::file_size(Twine(File5), File5Size)); + ASSERT_EQ(File5Size, 8000ULL); + ASSERT_NO_ERROR(fs::remove(File5.str())); // Clean up. ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); }