[clangd] Change FSProvider::getFileSystem to take CurrentWorkingDirectory
Summary:
We've faced a couple of problems when the returned FS didn't have the
proper working directory. New signature makes the API safer against such
problems.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D81920
diff --git a/clang-tools-extra/clangd/support/FSProvider.cpp b/clang-tools-extra/clangd/support/FSProvider.cpp
index 6474a3c..080bd06 100644
--- a/clang-tools-extra/clangd/support/FSProvider.cpp
+++ b/clang-tools-extra/clangd/support/FSProvider.cpp
@@ -7,6 +7,9 @@
//===----------------------------------------------------------------------===//
#include "support/FSProvider.h"
+#include "Logger.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
@@ -72,7 +75,15 @@
} // namespace
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
-clang::clangd::RealFileSystemProvider::getFileSystem() const {
+FileSystemProvider::getFileSystem(PathRef CWD) const {
+ auto FS = getFileSystem(/*CWD=*/llvm::None);
+ if (auto EC = FS->setCurrentWorkingDirectory(CWD))
+ elog("VFS: failed to set CWD to {0}: {1}", CWD, EC.message());
+ return FS;
+}
+
+llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+clang::clangd::RealFileSystemProvider::getFileSystem(llvm::NoneType) const {
// Avoid using memory-mapped files.
// FIXME: Try to use a similar approach in Sema instead of relying on
// propagation of the 'isVolatile' flag through all layers.
diff --git a/clang-tools-extra/clangd/support/FSProvider.h b/clang-tools-extra/clangd/support/FSProvider.h
index 2686e3e..8c6b8c8 100644
--- a/clang-tools-extra/clangd/support/FSProvider.h
+++ b/clang-tools-extra/clangd/support/FSProvider.h
@@ -9,7 +9,10 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_FSPROVIDER_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_FSPROVIDER_H
+#include "Path.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <memory>
@@ -25,14 +28,21 @@
/// Context::current() will be the context passed to the clang entrypoint,
/// such as addDocument(), and will also be propagated to result callbacks.
/// Embedders may use this to isolate filesystem accesses.
+ /// Initial working directory is arbitrary.
virtual llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
- getFileSystem() const = 0;
+ getFileSystem(llvm::NoneType CWD) const = 0;
+
+ /// As above, except it will try to set current working directory to \p CWD.
+ /// This is an overload instead of an optional to make implicit string ->
+ /// StringRef conversion possible.
+ virtual llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
+ getFileSystem(PathRef CWD) const;
};
class RealFileSystemProvider : public FileSystemProvider {
public:
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
- getFileSystem() const override;
+ getFileSystem(llvm::NoneType) const override;
};
} // namespace clangd