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/ADT/None.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/Support/VirtualFileSystem.h"
17 #include <memory>
18 
19 namespace clang {
20 namespace clangd {
21 
22 /// Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
23 /// As FileSystem is not threadsafe, concurrent threads must each obtain one.
24 /// Implementations may choose to depend on Context::current() e.g. to implement
25 /// snapshot semantics. clangd will not create vfs::FileSystems for use in
26 /// different contexts, so either ThreadsafeFS::view or the returned FS may
27 /// contain this logic.
28 class ThreadsafeFS {
29 public:
30   virtual ~ThreadsafeFS() = default;
31 
32   /// Obtain a vfs::FileSystem with an arbitrary initial working directory.
33   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
view(llvm::NoneType CWD)34   view(llvm::NoneType CWD) const {
35     return viewImpl();
36   }
37 
38   /// Obtain a vfs::FileSystem with a specified working directory.
39   /// If the working directory can't be set (e.g. doesn't exist), logs and
40   /// returns the FS anyway.
41   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> view(PathRef CWD) const;
42 
43 private:
44   /// Overridden by implementations to provide a vfs::FileSystem.
45   /// This is distinct from view(NoneType) to avoid GCC's -Woverloaded-virtual.
46   virtual llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const = 0;
47 };
48 
49 class RealThreadsafeFS : public ThreadsafeFS {
50 private:
51   llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const override;
52 };
53 
54 } // namespace clangd
55 } // namespace clang
56 
57 #endif
58