clang-tools 8.0.0

FSProvider.cpp
Go to the documentation of this file.
1 //===--- FSProvider.cpp - VFS provider for ClangdServer -------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "FSProvider.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/VirtualFileSystem.h"
16 #include <memory>
17
18 namespace clang {
19 namespace clangd {
20
21 namespace {
22 /// Always opens files in the underlying filesystem as "volatile", meaning they
23 /// won't be memory-mapped. This avoid locking the files on Windows.
24 class VolatileFileSystem : public llvm::vfs::ProxyFileSystem {
25 public:
26 explicit VolatileFileSystem(llvm::IntrusiveRefCntPtr<FileSystem> FS)
27 : ProxyFileSystem(std::move(FS)) {}
28
29 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
30 openFileForRead(const llvm::Twine &InPath) override {
31 llvm::SmallString<128> Path;
32 InPath.toVector(Path);
33
34 auto File = getUnderlyingFS().openFileForRead(Path);
35 if (!File)
36 return File;
37 // Try to guess preamble files, they can be memory-mapped even on Windows as
38 // clangd has exclusive access to those.
39 llvm::StringRef FileName = llvm::sys::path::filename(Path);
40 if (FileName.startswith("preamble-") && FileName.endswith(".pch"))
41 return File;
42 return std::unique_ptr<VolatileFile>(new VolatileFile(std::move(*File)));
43 }
44
45 private:
46 class VolatileFile : public llvm::vfs::File {
47 public:
48 VolatileFile(std::unique_ptr<llvm::vfs::File> Wrapped)
49 : Wrapped(std::move(Wrapped)) {
50 assert(this->Wrapped);
51 }
52
53 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
54 getBuffer(const llvm::Twine &Name, int64_t FileSize,
55 bool RequiresNullTerminator, bool /*IsVolatile*/) override {
56 return Wrapped->getBuffer(Name, FileSize, RequiresNullTerminator,
57 /*IsVolatile=*/true);
58 }
59
60 llvm::ErrorOr<llvm::vfs::Status> status() override {
61 return Wrapped->status();
62 }
63 llvm::ErrorOr<std::string> getName() override { return Wrapped->getName(); }
64 std::error_code close() override { return Wrapped->close(); }
65
66 private:
67 std::unique_ptr<File> Wrapped;
68 };
69 };
70 } // namespace
71
72 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
73 clang::clangd::RealFileSystemProvider::getFileSystem() const {
74 // Avoid using memory-mapped files on Windows, they cause file locking issues.
75 // FIXME: Try to use a similar approach in Sema instead of relying on
76 // propagation of the 'isVolatile' flag through all layers.
77 #ifdef _WIN32
78 return new VolatileFileSystem(llvm::vfs::getRealFileSystem());
79 #else
80 return llvm::vfs::getRealFileSystem();
81 #endif
82 }
83 } // namespace clangd
84 } // namespace clang
clang::clangd::Path
std::string Path
A typedef to represent a file path.
Definition: Path.h:21
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
FileName
PathRef FileName
Definition: CodeComplete.cpp:1004
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ChangeNamespace.cpp:18
FSProvider.h
clang::clangd::RealFileSystemProvider::getFileSystem
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > getFileSystem() const override
Called by ClangdServer to obtain a vfs::FileSystem to be used for parsing.
Definition: FSProvider.cpp:73
clang::clangd::CompletionItemKind::File