brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 827b465 Raw
82 lines · c
1//===--- FS.h - File system related utils ------------------------*- 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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FS_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FS_H11 12#include "support/Path.h"13#include "clang/Basic/LLVM.h"14#include "llvm/ADT/StringMap.h"15#include "llvm/Support/VirtualFileSystem.h"16#include <optional>17 18namespace clang {19namespace clangd {20 21/// Records status information for files open()ed or stat()ed during preamble22/// build (except for the main file), so we can avoid stat()s on the underlying23/// FS when reusing the preamble. For example, code completion can re-stat files24/// when getting FileID for source locations stored in preamble (e.g. checking25/// whether a location is in the main file).26///27/// The cache is keyed by absolute path of file name in cached status, as this28/// is what preamble stores.29///30/// The cache is not thread-safe when updates happen, so the use pattern should31/// be:32///   - One FS writes to the cache from one thread (or several but strictly33///   sequenced), e.g. when building preamble.34///   - Sequence point (no writes after this point, no reads before).35///   - Several FSs can read from the cache, e.g. code completions.36///37/// Note that the cache is only valid when reusing preamble.38class PreambleFileStatusCache {39public:40  /// \p MainFilePath is the absolute path of the main source file this preamble41  /// corresponds to. The stat for the main file will not be cached.42  PreambleFileStatusCache(llvm::StringRef MainFilePath);43 44  void update(const llvm::vfs::FileSystem &FS, llvm::vfs::Status S,45              llvm::StringRef File);46 47  /// \p Path is a path stored in preamble.48  std::optional<llvm::vfs::Status> lookup(llvm::StringRef Path) const;49 50  /// Returns a VFS that collects file status.51  /// Only cache stats for files that exist because52  ///   1) we only care about existing files when reusing preamble, unlike53  ///   building preamble.54  ///   2) we use the file name in the Status as the cache key.55  ///56  /// Note that the returned VFS should not outlive the cache.57  IntrusiveRefCntPtr<llvm::vfs::FileSystem>58  getProducingFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);59 60  /// Returns a VFS that uses the cache collected.61  ///62  /// Note that the returned VFS should not outlive the cache.63  IntrusiveRefCntPtr<llvm::vfs::FileSystem>64  getConsumingFS(IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS) const;65 66private:67  std::string MainFilePath;68  llvm::StringMap<llvm::vfs::Status> StatCache;69};70 71/// Returns a version of \p File that doesn't contain dots and dot dots.72/// e.g /a/b/../c -> /a/c73///     /a/b/./c -> /a/b/c74/// FIXME: We should avoid encountering such paths in clangd internals by75/// filtering everything we get over LSP, CDB, etc.76Path removeDots(PathRef File);77 78} // namespace clangd79} // namespace clang80 81#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_FS_H82