[PATCH] D48903: [VirtualFileSystem] InMemoryFileSystem::status: Return a Status with the requested name

Simon Marchi via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 3 15:41:47 PDT 2018

simark created this revision.
Herald added subscribers: cfe-commits, ioeric, ilya-biryukov.

InMemoryFileSystem::status behaves differently than
RealFileSystem::status.  The Name contained in the Status returned by
RealFileSystem::status will be the path as requested by the caller,
whereas InMemoryFileSystem::status returns the normalized path.

For example, when requested the status for "../src/first.h",
RealFileSystem returns a Status with "../src/first.h" as the Name.
InMemoryFileSystem returns "/absolute/path/to/src/first.h".

The reason for this change is that I want to make a unit test in the
clangd testsuite (where we use an InMemoryFileSystem) to reproduce a
bug I get with the clangd program (where a RealFileSystem is used).
This difference in behavior "hides" the bug in the unit test version.

  rC Clang



Index: lib/Basic/VirtualFileSystem.cpp
--- lib/Basic/VirtualFileSystem.cpp
+++ lib/Basic/VirtualFileSystem.cpp
@@ -508,10 +508,18 @@
 class InMemoryFileAdaptor : public File {
   InMemoryFile &Node;
+  // The name to use when returning a Status for this file.
+  std::string RequestedName;
-  explicit InMemoryFileAdaptor(InMemoryFile &Node) : Node(Node) {}
+  explicit InMemoryFileAdaptor(InMemoryFile &Node, std::string RequestedName)
+  : Node(Node), RequestedName (std::move (RequestedName))
+  {}
-  llvm::ErrorOr<Status> status() override { return Node.getStatus(); }
+  llvm::ErrorOr<Status> status() override {
+    Status St = Node.getStatus();
+    return Status::copyWithNewName(St, RequestedName);
+  }
   getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator,
@@ -711,7 +719,10 @@
 llvm::ErrorOr<Status> InMemoryFileSystem::status(const Twine &Path) {
   auto Node = lookupInMemoryNode(*this, Root.get(), Path);
   if (Node)
-    return (*Node)->getStatus();
+    {
+      Status St = (*Node)->getStatus();
+      return Status::copyWithNewName(St, Path.str());
+    }
   return Node.getError();
@@ -724,7 +735,7 @@
   // When we have a file provide a heap-allocated wrapper for the memory buffer
   // to match the ownership semantics for File.
   if (auto *F = dyn_cast<detail::InMemoryFile>(*Node))
-    return std::unique_ptr<File>(new detail::InMemoryFileAdaptor(*F));
+    return std::unique_ptr<File>(new detail::InMemoryFileAdaptor(*F, Path.str()));
   // FIXME: errc::not_a_file?
   return make_error_code(llvm::errc::invalid_argument);

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48903.154009.patch
Type: text/x-patch
Size: 1726 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180703/edf03415/attachment.bin>

More information about the cfe-commits mailing list