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