10 #include "clang/Basic/LLVM.h"
11 #include "llvm/ADT/None.h"
12 #include "llvm/Support/Path.h"
13 #include "llvm/Support/VirtualFileSystem.h"
19 assert(llvm::sys::path::is_absolute(MainFilePath));
20 llvm::SmallString<256> MainFileCanonical(MainFilePath);
21 llvm::sys::path::remove_dots(MainFileCanonical,
true);
22 this->MainFilePath = std::string(MainFileCanonical.str());
26 llvm::vfs::Status S) {
28 llvm::SmallString<32> PathStore(S.getName());
29 if (
FS.makeAbsolute(PathStore))
31 llvm::sys::path::remove_dots(PathStore,
true);
33 if (PathStore == MainFilePath)
36 StatCache.insert({PathStore, std::move(S)});
39 llvm::Optional<llvm::vfs::Status>
43 llvm::SmallString<256> PathLookup(
File);
44 llvm::sys::path::remove_dots(PathLookup,
true);
46 auto I = StatCache.find(PathLookup);
47 if (I != StatCache.end())
49 return llvm::vfs::Status::copyWithNewName(I->getValue(),
File);
53 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
55 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
FS) {
58 class CollectFS :
public llvm::vfs::ProxyFileSystem {
60 CollectFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
FS,
62 : ProxyFileSystem(std::move(
FS)), StatCache(StatCache) {}
64 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
65 openFileForRead(
const llvm::Twine &
Path)
override {
66 auto File = getUnderlyingFS().openFileForRead(
Path);
74 if (
auto S =
File->get()->status())
75 StatCache.
update(getUnderlyingFS(), std::move(*S));
79 llvm::ErrorOr<llvm::vfs::Status> status(
const llvm::Twine &
Path)
override {
80 auto S = getUnderlyingFS().status(
Path);
82 StatCache.
update(getUnderlyingFS(), *S);
89 return llvm::IntrusiveRefCntPtr<CollectFS>(
90 new CollectFS(std::move(
FS), *
this));
93 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
95 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
FS)
const {
96 class CacheVFS :
public llvm::vfs::ProxyFileSystem {
98 CacheVFS(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
FS,
100 : ProxyFileSystem(std::move(
FS)), StatCache(StatCache) {}
102 llvm::ErrorOr<llvm::vfs::Status> status(
const llvm::Twine &
Path)
override {
105 return getUnderlyingFS().status(
Path);
111 return llvm::IntrusiveRefCntPtr<CacheVFS>(
new CacheVFS(std::move(
FS), *
this));
115 llvm::SmallString<128> CanonPath(File);
116 llvm::sys::path::remove_dots(CanonPath,
true);
117 return CanonPath.str().str();