clang 23.0.0git
DependencyScanningFilesystem.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
10#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
11
12#include "clang/Basic/LLVM.h"
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/StringMap.h"
16#include "llvm/Support/Allocator.h"
17#include "llvm/Support/ErrorOr.h"
18#include "llvm/Support/VirtualFileSystem.h"
19#include <mutex>
20#include <optional>
21#include <variant>
22
23namespace clang {
24namespace dependencies {
25
27
30
31/// Contents and directive tokens of a cached file entry. Single instance can
32/// be shared between multiple entries.
34 CachedFileContents(std::unique_ptr<llvm::MemoryBuffer> Contents)
35 : Original(std::move(Contents)), DepDirectives(nullptr) {}
36
37 /// Owning storage for the original contents.
38 std::unique_ptr<llvm::MemoryBuffer> Original;
39
40 /// The mutex that must be locked before mutating directive tokens.
41 std::mutex ValueLock;
43 /// Accessor to the directive tokens that's atomic to avoid data races.
44 /// \p CachedFileContents has ownership of the pointer.
45 std::atomic<const std::optional<DependencyDirectivesTy> *> DepDirectives;
46
48};
49
50/// An in-memory representation of a file system entity that is of interest to
51/// the dependency scanning filesystem.
52///
53/// It represents one of the following:
54/// - opened file with contents and a stat value,
55/// - opened file with contents, directive tokens and a stat value,
56/// - directory entry with its stat value,
57/// - filesystem error.
58///
59/// Single instance of this class can be shared across different filenames (e.g.
60/// a regular file and a symlink). For this reason the status filename is empty
61/// and is only materialized by \c EntryRef that knows the requested filename.
63public:
64 /// Creates an entry without contents: either a filesystem error or
65 /// a directory with stat value.
66 CachedFileSystemEntry(llvm::ErrorOr<llvm::vfs::Status> Stat)
67 : MaybeStat(std::move(Stat)), Contents(nullptr) {
68 clearStatName();
69 }
70
71 /// Creates an entry representing a file with contents.
72 CachedFileSystemEntry(llvm::ErrorOr<llvm::vfs::Status> Stat,
73 CachedFileContents *Contents)
74 : MaybeStat(std::move(Stat)), Contents(std::move(Contents)) {
75 clearStatName();
76 }
77
78 /// \returns True if the entry is a filesystem error.
79 bool isError() const { return !MaybeStat; }
80
81 /// \returns True if the current entry represents a directory.
82 bool isDirectory() const { return !isError() && MaybeStat->isDirectory(); }
83
84 /// \returns Original contents of the file.
85 StringRef getOriginalContents() const {
86 assert(!isError() && "error");
87 assert(!MaybeStat->isDirectory() && "not a file");
88 assert(Contents && "contents not initialized");
89 return Contents->Original->getBuffer();
90 }
91
92 /// \returns The scanned preprocessor directive tokens of the file that are
93 /// used to speed up preprocessing, if available.
94 std::optional<ArrayRef<dependency_directives_scan::Directive>>
96 assert(!isError() && "error");
97 assert(!isDirectory() && "not a file");
98 assert(Contents && "contents not initialized");
99 if (auto *Directives = Contents->DepDirectives.load()) {
100 if (Directives->has_value())
102 }
103 return std::nullopt;
104 }
105
106 /// \returns The error.
107 std::error_code getError() const { return MaybeStat.getError(); }
108
109 /// \returns The entry status with empty filename.
110 llvm::vfs::Status getStatus() const {
111 assert(!isError() && "error");
112 assert(MaybeStat->getName().empty() && "stat name must be empty");
113 return *MaybeStat;
114 }
115
116 /// \returns The unique ID of the entry.
117 llvm::sys::fs::UniqueID getUniqueID() const {
118 assert(!isError() && "error");
119 return MaybeStat->getUniqueID();
120 }
121
122 /// \returns The data structure holding both contents and directive tokens.
124 assert(!isError() && "error");
125 assert(!isDirectory() && "not a file");
126 return Contents;
127 }
128
129private:
130 void clearStatName() {
131 if (MaybeStat)
132 MaybeStat = llvm::vfs::Status::copyWithNewName(*MaybeStat, "");
133 }
134
135 /// Either the filesystem error or status of the entry.
136 /// The filename is empty and only materialized by \c EntryRef.
137 llvm::ErrorOr<llvm::vfs::Status> MaybeStat;
138
139 /// Non-owning pointer to the file contents.
140 ///
141 /// We're using pointer here to keep the size of this class small. Instances
142 /// representing directories and filesystem errors don't hold any contents
143 /// anyway.
144 CachedFileContents *Contents;
145};
146
147using CachedRealPath = llvm::ErrorOr<std::string>;
148
149/// This class is a shared cache, that caches the 'stat' and 'open' calls to the
150/// underlying real file system, and the scanned preprocessor directives of
151/// files.
152///
153/// It is sharded based on the hash of the key to reduce the lock contention for
154/// the worker threads.
156public:
157 struct CacheShard {
158 /// The mutex that needs to be locked before mutation of any member.
159 mutable std::mutex CacheLock;
160
161 /// Map from filenames to cached entries and real paths.
162 llvm::StringMap<
163 std::pair<const CachedFileSystemEntry *, const CachedRealPath *>,
164 llvm::BumpPtrAllocator>
166
167 /// Map from unique IDs to cached entries.
168 llvm::DenseMap<llvm::sys::fs::UniqueID, const CachedFileSystemEntry *>
170
171 /// The backing storage for cached entries.
172 llvm::SpecificBumpPtrAllocator<CachedFileSystemEntry> EntryStorage;
173
174 /// The backing storage for cached contents.
175 llvm::SpecificBumpPtrAllocator<CachedFileContents> ContentsStorage;
176
177 /// The backing storage for cached real paths.
178 llvm::SpecificBumpPtrAllocator<CachedRealPath> RealPathStorage;
179
180 /// Returns entry associated with the filename or nullptr if none is found.
181 const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const;
182
183 /// Returns entry associated with the unique ID or nullptr if none is found.
185 findEntryByUID(llvm::sys::fs::UniqueID UID) const;
186
187 /// Returns entry associated with the filename if there is some. Otherwise,
188 /// constructs new one with the given status, associates it with the
189 /// filename and returns the result.
191 getOrEmplaceEntryForFilename(StringRef Filename,
192 llvm::ErrorOr<llvm::vfs::Status> Stat);
193
194 /// Returns entry associated with the unique ID if there is some. Otherwise,
195 /// constructs new one with the given status and contents, associates it
196 /// with the unique ID and returns the result.
198 getOrEmplaceEntryForUID(llvm::sys::fs::UniqueID UID, llvm::vfs::Status Stat,
199 std::unique_ptr<llvm::MemoryBuffer> Contents);
200
201 /// Returns entry associated with the filename if there is some. Otherwise,
202 /// associates the given entry with the filename and returns it.
204 getOrInsertEntryForFilename(StringRef Filename,
205 const CachedFileSystemEntry &Entry);
206
207 /// Returns the real path associated with the filename or nullptr if none is
208 /// found.
209 const CachedRealPath *findRealPathByFilename(StringRef Filename) const;
210
211 /// Returns the real path associated with the filename if there is some.
212 /// Otherwise, constructs new one with the given one, associates it with the
213 /// filename and returns the result.
214 const CachedRealPath &
215 getOrEmplaceRealPathForFilename(StringRef Filename,
216 llvm::ErrorOr<StringRef> RealPath);
217 };
218
220
221 /// Returns shard for the given key.
222 CacheShard &getShardForFilename(StringRef Filename) const;
223 CacheShard &getShardForUID(llvm::sys::fs::UniqueID UID) const;
224
226 // A null terminated string that contains a path.
227 const char *Path = nullptr;
228
231 uint64_t CachedSize = 0;
232 uint64_t ActualSize = 0;
233 };
234
235 std::variant<NegativelyCachedInfo, SizeChangedInfo> Info;
236
239
240 OutOfDateEntry(const char *Path, uint64_t CachedSize, uint64_t ActualSize)
241 : Path(Path), Info(SizeChangedInfo{CachedSize, ActualSize}) {}
242 };
243
244 /// Visits all cached entries and re-stat an entry using UnderlyingFS to check
245 /// if the cache contains out-of-date entries. An entry can be out-of-date for
246 /// two reasons:
247 /// 1. The entry contains a stat error, indicating the file did not exist
248 /// in the cache, but the file exists on the UnderlyingFS.
249 /// 2. The entry is associated with a file whose size is different from the
250 /// size of the file on the same path on the UnderlyingFS.
251 std::vector<OutOfDateEntry>
252 getOutOfDateEntries(llvm::vfs::FileSystem &UnderlyingFS) const;
253
254private:
255 std::unique_ptr<CacheShard[]> CacheShards;
256 unsigned NumShards;
257};
258
259/// This class is a local cache, that caches the 'stat' and 'open' calls to the
260/// underlying real file system.
262 llvm::StringMap<
263 std::pair<const CachedFileSystemEntry *, const CachedRealPath *>,
264 llvm::BumpPtrAllocator>
265 Cache;
266
267public:
268 /// Returns entry associated with the filename or nullptr if none is found.
269 const CachedFileSystemEntry *findEntryByFilename(StringRef Filename) const {
270 assert(llvm::sys::path::is_absolute_gnu(Filename));
271 auto It = Cache.find(Filename);
272 return It == Cache.end() ? nullptr : It->getValue().first;
273 }
274
275 /// Associates the given entry with the filename and returns the given entry
276 /// pointer (for convenience).
278 insertEntryForFilename(StringRef Filename,
279 const CachedFileSystemEntry &Entry) {
280 assert(llvm::sys::path::is_absolute_gnu(Filename));
281 auto [It, Inserted] = Cache.insert({Filename, {&Entry, nullptr}});
282 auto &[CachedEntry, CachedRealPath] = It->getValue();
283 if (!Inserted) {
284 // The file is already present in the local cache. If we got here, it only
285 // contains the real path. Let's make sure the entry is populated too.
286 assert((!CachedEntry && CachedRealPath) && "entry already present");
287 CachedEntry = &Entry;
288 }
289 return *CachedEntry;
290 }
291
292 /// Returns real path associated with the filename or nullptr if none is
293 /// found.
294 const CachedRealPath *findRealPathByFilename(StringRef Filename) const {
295 assert(llvm::sys::path::is_absolute_gnu(Filename));
296 auto It = Cache.find(Filename);
297 return It == Cache.end() ? nullptr : It->getValue().second;
298 }
299
300 /// Associates the given real path with the filename and returns the given
301 /// entry pointer (for convenience).
302 const CachedRealPath &
303 insertRealPathForFilename(StringRef Filename,
304 const CachedRealPath &RealPath) {
305 assert(llvm::sys::path::is_absolute_gnu(Filename));
306 auto [It, Inserted] = Cache.insert({Filename, {nullptr, &RealPath}});
307 auto &[CachedEntry, CachedRealPath] = It->getValue();
308 if (!Inserted) {
309 // The file is already present in the local cache. If we got here, it only
310 // contains the entry. Let's make sure the real path is populated too.
311 assert((!CachedRealPath && CachedEntry) && "real path already present");
312 CachedRealPath = &RealPath;
313 }
314 return *CachedRealPath;
315 }
316};
317
318/// Reference to a CachedFileSystemEntry.
319/// If the underlying entry is an opened file, this wrapper returns the file
320/// contents and the scanned preprocessor directives.
321class EntryRef {
322 /// The filename used to access this entry.
323 std::string Filename;
324
325 /// The underlying cached entry.
326 const CachedFileSystemEntry &Entry;
327
329
330public:
331 EntryRef(StringRef Name, const CachedFileSystemEntry &Entry)
332 : Filename(Name), Entry(Entry) {}
333
334 llvm::vfs::Status getStatus() const {
335 llvm::vfs::Status Stat = Entry.getStatus();
336 if (!Stat.isDirectory())
337 Stat = llvm::vfs::Status::copyWithNewSize(Stat, getContents().size());
338 return llvm::vfs::Status::copyWithNewName(Stat, Filename);
339 }
340
341 bool isError() const { return Entry.isError(); }
342 bool isDirectory() const { return Entry.isDirectory(); }
343
344 /// If the cached entry represents an error, promotes it into `ErrorOr`.
345 llvm::ErrorOr<EntryRef> unwrapError() const {
346 if (isError())
347 return Entry.getError();
348 return *this;
349 }
350
351 StringRef getContents() const { return Entry.getOriginalContents(); }
352
353 std::optional<ArrayRef<dependency_directives_scan::Directive>>
355 return Entry.getDirectiveTokens();
356 }
357};
358
359/// A virtual file system optimized for the dependency discovery.
360///
361/// It is primarily designed to work with source files whose contents was
362/// preprocessed to remove any tokens that are unlikely to affect the dependency
363/// computation.
364///
365/// This is not a thread safe VFS. A single instance is meant to be used only in
366/// one thread. Multiple instances are allowed to service multiple threads
367/// running in parallel.
369 : public llvm::RTTIExtends<DependencyScanningWorkerFilesystem,
370 llvm::vfs::ProxyFileSystem> {
371public:
372 static const char ID;
373
377
378 llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override;
379 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
380 openFileForRead(const Twine &Path) override;
381
382 std::error_code getRealPath(const Twine &Path,
383 SmallVectorImpl<char> &Output) override;
384
385 std::error_code setCurrentWorkingDirectory(const Twine &Path) override;
386
387 /// Returns entry for the given filename.
388 ///
389 /// Attempts to use the local and shared caches first, then falls back to
390 /// using the underlying filesystem.
391 llvm::ErrorOr<EntryRef> getOrCreateFileSystemEntry(StringRef Filename);
392
393 /// Ensure the directive tokens are populated for this file entry.
394 ///
395 /// Returns true if the directive tokens are populated for this file entry,
396 /// false if not (i.e. this entry is not a file or its scan fails).
398
399 /// \returns The scanned preprocessor directive tokens of the file that are
400 /// used to speed up preprocessing, if available.
401 std::optional<ArrayRef<dependency_directives_scan::Directive>>
402 getDirectiveTokens(const Twine &Path) {
403 if (llvm::ErrorOr<EntryRef> Entry = getOrCreateFileSystemEntry(Path.str()))
405 return Entry->getDirectiveTokens();
406 return std::nullopt;
407 }
408
409 /// Check whether \p Path exists. By default checks cached result of \c
410 /// status(), and falls back on FS if unable to do so.
411 bool exists(const Twine &Path) override;
412
413private:
414 /// For a filename that's not yet associated with any entry in the caches,
415 /// uses the underlying filesystem to either look up the entry based in the
416 /// shared cache indexed by unique ID, or creates new entry from scratch.
417 /// \p FilenameForLookup will always be an absolute path, and different than
418 /// \p OriginalFilename if \p OriginalFilename is relative.
419 llvm::ErrorOr<const CachedFileSystemEntry &>
420 computeAndStoreResult(StringRef OriginalFilename,
421 StringRef FilenameForLookup);
422
423 /// Represents a filesystem entry that has been stat-ed (and potentially read)
424 /// and that's about to be inserted into the cache as `CachedFileSystemEntry`.
425 struct TentativeEntry {
426 llvm::vfs::Status Status;
427 std::unique_ptr<llvm::MemoryBuffer> Contents;
428
429 TentativeEntry(llvm::vfs::Status Status,
430 std::unique_ptr<llvm::MemoryBuffer> Contents = nullptr)
431 : Status(std::move(Status)), Contents(std::move(Contents)) {}
432 };
433
434 /// Reads file at the given path. Enforces consistency between the file size
435 /// in status and size of read contents.
436 llvm::ErrorOr<TentativeEntry> readFile(StringRef Filename);
437
438 /// Returns entry associated with the unique ID of the given tentative entry
439 /// if there is some in the shared cache. Otherwise, constructs new one,
440 /// associates it with the unique ID and returns the result.
441 const CachedFileSystemEntry &
442 getOrEmplaceSharedEntryForUID(TentativeEntry TEntry);
443
444 /// Returns entry associated with the filename or nullptr if none is found.
445 ///
446 /// Returns entry from local cache if there is some. Otherwise, if the entry
447 /// is found in the shared cache, writes it through the local cache and
448 /// returns it. Otherwise returns nullptr.
449 const CachedFileSystemEntry *
450 findEntryByFilenameWithWriteThrough(StringRef Filename);
451
452 /// Returns entry associated with the unique ID in the shared cache or nullptr
453 /// if none is found.
454 const CachedFileSystemEntry *
455 findSharedEntryByUID(llvm::vfs::Status Stat) const;
456
457 /// Associates the given entry with the filename in the local cache and
458 /// returns it.
459 const CachedFileSystemEntry &
460 insertLocalEntryForFilename(StringRef Filename,
461 const CachedFileSystemEntry &Entry) {
462 return LocalCache.insertEntryForFilename(Filename, Entry);
463 }
464
465 /// Returns entry associated with the filename in the shared cache if there is
466 /// some. Otherwise, constructs new one with the given error code, associates
467 /// it with the filename and returns the result.
468 const CachedFileSystemEntry &
469 getOrEmplaceSharedEntryForFilename(StringRef Filename, std::error_code EC);
470
471 /// Returns entry associated with the filename in the shared cache if there is
472 /// some. Otherwise, associates the given entry with the filename and returns
473 /// it.
474 const CachedFileSystemEntry &
475 getOrInsertSharedEntryForFilename(StringRef Filename,
476 const CachedFileSystemEntry &Entry);
477
478 void printImpl(raw_ostream &OS, PrintType Type,
479 unsigned IndentLevel) const override {
480 printIndent(OS, IndentLevel);
481 OS << "DependencyScanningFilesystem\n";
482 getUnderlyingFS().print(OS, Type, IndentLevel + 1);
483 }
484
485 /// The service associated with this VFS.
486 DependencyScanningService &Service;
487 /// The local cache is used by the worker thread to cache file system queries
488 /// locally instead of querying the global cache every time.
489 DependencyScanningFilesystemLocalCache LocalCache;
490
491 /// The working directory to use for making relative paths absolute before
492 /// using them for cache lookups.
493 llvm::ErrorOr<std::string> WorkingDirForCacheLookup;
494
495 void updateWorkingDirForCacheLookup();
496
497 llvm::ErrorOr<StringRef>
498 tryGetFilenameForLookup(StringRef OriginalFilename,
499 llvm::SmallVectorImpl<char> &PathBuf) const;
500};
501
502} // end namespace dependencies
503} // end namespace clang
504
505#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
unsigned IndentLevel
The indent level of this token. Copied from the surrounding line.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
An in-memory representation of a file system entity that is of interest to the dependency scanning fi...
CachedFileSystemEntry(llvm::ErrorOr< llvm::vfs::Status > Stat, CachedFileContents *Contents)
Creates an entry representing a file with contents.
std::optional< ArrayRef< dependency_directives_scan::Directive > > getDirectiveTokens() const
CachedFileSystemEntry(llvm::ErrorOr< llvm::vfs::Status > Stat)
Creates an entry without contents: either a filesystem error or a directory with stat value.
This class is a local cache, that caches the 'stat' and 'open' calls to the underlying real file syst...
const CachedRealPath & insertRealPathForFilename(StringRef Filename, const CachedRealPath &RealPath)
Associates the given real path with the filename and returns the given entry pointer (for convenience...
const CachedFileSystemEntry & insertEntryForFilename(StringRef Filename, const CachedFileSystemEntry &Entry)
Associates the given entry with the filename and returns the given entry pointer (for convenience).
const CachedFileSystemEntry * findEntryByFilename(StringRef Filename) const
Returns entry associated with the filename or nullptr if none is found.
const CachedRealPath * findRealPathByFilename(StringRef Filename) const
Returns real path associated with the filename or nullptr if none is found.
CacheShard & getShardForFilename(StringRef Filename) const
Returns shard for the given key.
std::vector< OutOfDateEntry > getOutOfDateEntries(llvm::vfs::FileSystem &UnderlyingFS) const
Visits all cached entries and re-stat an entry using UnderlyingFS to check if the cache contains out-...
The dependency scanning service contains shared configuration and state that is used by the individua...
std::optional< ArrayRef< dependency_directives_scan::Directive > > getDirectiveTokens(const Twine &Path)
std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output) override
bool ensureDirectiveTokensArePopulated(EntryRef Entry)
Ensure the directive tokens are populated for this file entry.
bool exists(const Twine &Path) override
Check whether Path exists.
DependencyScanningWorkerFilesystem(DependencyScanningService &Service, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS)
llvm::ErrorOr< EntryRef > getOrCreateFileSystemEntry(StringRef Filename)
Returns entry for the given filename.
llvm::ErrorOr< std::unique_ptr< llvm::vfs::File > > openFileForRead(const Twine &Path) override
std::error_code setCurrentWorkingDirectory(const Twine &Path) override
llvm::ErrorOr< llvm::vfs::Status > status(const Twine &Path) override
Reference to a CachedFileSystemEntry.
std::optional< ArrayRef< dependency_directives_scan::Directive > > getDirectiveTokens() const
llvm::ErrorOr< EntryRef > unwrapError() const
If the cached entry represents an error, promotes it into ErrorOr.
EntryRef(StringRef Name, const CachedFileSystemEntry &Entry)
SmallVector< dependency_directives_scan::Directive, 20 > DependencyDirectivesTy
llvm::ErrorOr< std::string > CachedRealPath
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Type
The name was classified as a type.
Definition Sema.h:564
Contents and directive tokens of a cached file entry.
std::unique_ptr< llvm::MemoryBuffer > Original
Owning storage for the original contents.
SmallVector< dependency_directives_scan::Token, 10 > DepDirectiveTokens
std::atomic< const std::optional< DependencyDirectivesTy > * > DepDirectives
Accessor to the directive tokens that's atomic to avoid data races.
std::mutex ValueLock
The mutex that must be locked before mutating directive tokens.
CachedFileContents(std::unique_ptr< llvm::MemoryBuffer > Contents)
const CachedFileSystemEntry & getOrEmplaceEntryForUID(llvm::sys::fs::UniqueID UID, llvm::vfs::Status Stat, std::unique_ptr< llvm::MemoryBuffer > Contents)
Returns entry associated with the unique ID if there is some.
llvm::SpecificBumpPtrAllocator< CachedFileSystemEntry > EntryStorage
The backing storage for cached entries.
llvm::SpecificBumpPtrAllocator< CachedFileContents > ContentsStorage
The backing storage for cached contents.
llvm::SpecificBumpPtrAllocator< CachedRealPath > RealPathStorage
The backing storage for cached real paths.
const CachedFileSystemEntry * findEntryByUID(llvm::sys::fs::UniqueID UID) const
Returns entry associated with the unique ID or nullptr if none is found.
const CachedRealPath * findRealPathByFilename(StringRef Filename) const
Returns the real path associated with the filename or nullptr if none is found.
std::mutex CacheLock
The mutex that needs to be locked before mutation of any member.
const CachedFileSystemEntry & getOrInsertEntryForFilename(StringRef Filename, const CachedFileSystemEntry &Entry)
Returns entry associated with the filename if there is some.
const CachedFileSystemEntry * findEntryByFilename(StringRef Filename) const
Returns entry associated with the filename or nullptr if none is found.
const CachedFileSystemEntry & getOrEmplaceEntryForFilename(StringRef Filename, llvm::ErrorOr< llvm::vfs::Status > Stat)
Returns entry associated with the filename if there is some.
llvm::StringMap< std::pair< const CachedFileSystemEntry *, const CachedRealPath * >, llvm::BumpPtrAllocator > CacheByFilename
Map from filenames to cached entries and real paths.
const CachedRealPath & getOrEmplaceRealPathForFilename(StringRef Filename, llvm::ErrorOr< StringRef > RealPath)
Returns the real path associated with the filename if there is some.
llvm::DenseMap< llvm::sys::fs::UniqueID, const CachedFileSystemEntry * > EntriesByUID
Map from unique IDs to cached entries.
OutOfDateEntry(const char *Path, uint64_t CachedSize, uint64_t ActualSize)