Skip to content

Commit 8359513

Browse files
authored
[clang][deps] Enable calling DepScanFile::getBuffer() repeatedly (#168789)
This PR makes it possible to call `getBuffer()` on `DepScanFile` (a `llvm::vfs::File`) repeatedly. Previously, this function would return a moved-from `unique_ptr`. This doesn't fix any existing bugs, I discovered this while experimenting with the VFSs in the scanner. Note that the returned instances of `llvm::MemoryBuffer` are non-owning and share the underlying buffer storage.
1 parent 80f862b commit 8359513

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,8 @@ class DepScanFile final : public llvm::vfs::File {
366366
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
367367
getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
368368
bool IsVolatile) override {
369-
return std::move(Buffer);
369+
return llvm::MemoryBuffer::getMemBuffer(Buffer->getMemBufferRef(),
370+
RequiresNullTerminator);
370371
}
371372

372373
std::error_code close() override { return {}; }

clang/unittests/Tooling/DependencyScanning/DependencyScanningFilesystemTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,39 @@
1313

1414
using namespace clang::tooling::dependencies;
1515

16+
TEST(DependencyScanningFilesystem, OpenFileAndGetBufferRepeatedly) {
17+
auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
18+
InMemoryFS->setCurrentWorkingDirectory("/");
19+
InMemoryFS->addFile("/foo", 0, llvm::MemoryBuffer::getMemBuffer("content"));
20+
21+
DependencyScanningFilesystemSharedCache SharedCache;
22+
DependencyScanningWorkerFilesystem DepFS(SharedCache, InMemoryFS);
23+
24+
auto FileOrErr1 = DepFS.openFileForRead("foo");
25+
auto FileOrErr2 = DepFS.openFileForRead("foo");
26+
ASSERT_EQ(FileOrErr1.getError(), std::error_code{});
27+
ASSERT_EQ(FileOrErr1.getError(), std::error_code{});
28+
std::unique_ptr<llvm::vfs::File> File1 = std::move(*FileOrErr1);
29+
std::unique_ptr<llvm::vfs::File> File2 = std::move(*FileOrErr2);
30+
ASSERT_NE(File1, nullptr);
31+
ASSERT_NE(File2, nullptr);
32+
auto BufOrErr11 = File1->getBuffer("buf11");
33+
auto BufOrErr12 = File1->getBuffer("buf12");
34+
auto BufOrErr21 = File1->getBuffer("buf21");
35+
ASSERT_EQ(BufOrErr11.getError(), std::error_code{});
36+
ASSERT_EQ(BufOrErr12.getError(), std::error_code{});
37+
ASSERT_EQ(BufOrErr21.getError(), std::error_code{});
38+
std::unique_ptr<llvm::MemoryBuffer> Buf11 = std::move(*BufOrErr11);
39+
std::unique_ptr<llvm::MemoryBuffer> Buf12 = std::move(*BufOrErr12);
40+
std::unique_ptr<llvm::MemoryBuffer> Buf21 = std::move(*BufOrErr21);
41+
ASSERT_NE(Buf11, nullptr);
42+
ASSERT_NE(Buf12, nullptr);
43+
ASSERT_NE(Buf21, nullptr);
44+
ASSERT_EQ(Buf11->getBuffer().data(), Buf12->getBuffer().data());
45+
ASSERT_EQ(Buf11->getBuffer().data(), Buf21->getBuffer().data());
46+
EXPECT_EQ(Buf11->getBuffer(), "content");
47+
}
48+
1649
TEST(DependencyScanningWorkerFilesystem, CacheStatusFailures) {
1750
auto InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
1851

0 commit comments

Comments
 (0)