xref: /llvm-project/clang-tools-extra/clangd/support/ThreadsafeFS.h (revision f7dffc28b3f82e25a0e283d2b11ffb9c6a129340)
1 //===--- ThreadsafeFS.h ------------------------------------------*- C++-*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADSAFEFS_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SUPPORT_THREADSAFEFS_H
11 
12 #include "Path.h"
13 #include "llvm/ADT/IntrusiveRefCntPtr.h"
14 #include "llvm/Support/VirtualFileSystem.h"
15 #include <memory>
16 
17 namespace clang {
18 namespace clangd {
19 
20 /// Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
21 /// As FileSystem is not threadsafe, concurrent threads must each obtain one.
22 /// Implementations may choose to depend on Context::current() e.g. to implement
23 /// snapshot semantics. clangd will not create vfs::FileSystems for use in
24 /// different contexts, so either ThreadsafeFS::view or the returned FS may
25 /// contain this logic.
26 class ThreadsafeFS {
27 public:
28   virtual ~ThreadsafeFS() = default;
29 
30   /// Obtain a vfs::FileSystem with an arbitrary initial working directory.
31   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
view(std::nullopt_t CWD)32   view(std::nullopt_t CWD) const {
33     return viewImpl();
34   }
35 
36   /// Obtain a vfs::FileSystem with a specified working directory.
37   /// If the working directory can't be set (e.g. doesn't exist), logs and
38   /// returns the FS anyway.
39   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> view(PathRef CWD) const;
40 
41 private:
42   /// Overridden by implementations to provide a vfs::FileSystem.
43   /// This is distinct from view(NoneType) to avoid GCC's -Woverloaded-virtual.
44   virtual llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const = 0;
45 };
46 
47 class RealThreadsafeFS : public ThreadsafeFS {
48 private:
49   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const override;
50 };
51 
52 } // namespace clangd
53 } // namespace clang
54 
55 #endif
56