9#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
10#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_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"
45 std::atomic<const std::optional<DependencyDirectivesTy> *>
DepDirectives;
67 : MaybeStat(
std::move(Stat)), Contents(
nullptr) {
74 : MaybeStat(
std::move(Stat)), Contents(
std::move(Contents)) {
79 bool isError()
const {
return !MaybeStat; }
87 assert(!MaybeStat->isDirectory() &&
"not a file");
88 assert(Contents &&
"contents not initialized");
89 return Contents->Original->getBuffer();
94 std::optional<ArrayRef<dependency_directives_scan::Directive>>
98 assert(Contents &&
"contents not initialized");
99 if (
auto *Directives = Contents->DepDirectives.load()) {
100 if (Directives->has_value())
107 std::error_code
getError()
const {
return MaybeStat.getError(); }
112 assert(MaybeStat->getName().empty() &&
"stat name must be empty");
119 return MaybeStat->getUniqueID();
130 void clearStatName() {
132 MaybeStat = llvm::vfs::Status::copyWithNewName(*MaybeStat,
"");
137 llvm::ErrorOr<llvm::vfs::Status> MaybeStat;
144 CachedFileContents *Contents;
163 std::pair<const CachedFileSystemEntry *, const CachedRealPath *>,
164 llvm::BumpPtrAllocator>
168 llvm::DenseMap<llvm::sys::fs::UniqueID, const CachedFileSystemEntry *>
192 llvm::ErrorOr<llvm::vfs::Status> Stat);
199 std::unique_ptr<llvm::MemoryBuffer> Contents);
216 llvm::ErrorOr<StringRef> RealPath);
235 std::variant<NegativelyCachedInfo, SizeChangedInfo>
Info;
251 std::vector<OutOfDateEntry>
255 std::unique_ptr<CacheShard[]> CacheShards;
263 std::pair<const CachedFileSystemEntry *, const CachedRealPath *>,
264 llvm::BumpPtrAllocator>
270 assert(llvm::sys::path::is_absolute_gnu(Filename));
271 auto It = Cache.find(Filename);
272 return It == Cache.end() ?
nullptr : It->getValue().first;
280 assert(llvm::sys::path::is_absolute_gnu(Filename));
281 auto [It, Inserted] = Cache.insert({Filename, {&Entry,
nullptr}});
286 assert((!CachedEntry &&
CachedRealPath) &&
"entry already present");
287 CachedEntry = &Entry;
295 assert(llvm::sys::path::is_absolute_gnu(Filename));
296 auto It = Cache.find(Filename);
297 return It == Cache.end() ?
nullptr : It->getValue().second;
305 assert(llvm::sys::path::is_absolute_gnu(Filename));
306 auto [It, Inserted] = Cache.insert({Filename, {
nullptr, &RealPath}});
311 assert((!
CachedRealPath && CachedEntry) &&
"real path already present");
323 std::string Filename;
332 : Filename(Name), Entry(Entry) {}
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);
341 bool isError()
const {
return Entry.isError(); }
347 return Entry.getError();
351 StringRef
getContents()
const {
return Entry.getOriginalContents(); }
353 std::optional<ArrayRef<dependency_directives_scan::Directive>>
355 return Entry.getDirectiveTokens();
369 :
public llvm::RTTIExtends<DependencyScanningWorkerFilesystem,
370 llvm::vfs::ProxyFileSystem> {
372 static const char ID;
378 llvm::ErrorOr<llvm::vfs::Status>
status(
const Twine &Path)
override;
379 llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
401 std::optional<ArrayRef<dependency_directives_scan::Directive>>
405 return Entry->getDirectiveTokens();
411 bool exists(
const Twine &Path)
override;
419 llvm::ErrorOr<const CachedFileSystemEntry &>
420 computeAndStoreResult(StringRef OriginalFilename,
421 StringRef FilenameForLookup);
425 struct TentativeEntry {
426 llvm::vfs::Status Status;
427 std::unique_ptr<llvm::MemoryBuffer> Contents;
429 TentativeEntry(llvm::vfs::Status Status,
430 std::unique_ptr<llvm::MemoryBuffer> Contents =
nullptr)
431 : Status(
std::move(Status)), Contents(
std::move(Contents)) {}
436 llvm::ErrorOr<TentativeEntry> readFile(StringRef Filename);
441 const CachedFileSystemEntry &
442 getOrEmplaceSharedEntryForUID(TentativeEntry TEntry);
449 const CachedFileSystemEntry *
450 findEntryByFilenameWithWriteThrough(StringRef Filename);
454 const CachedFileSystemEntry *
455 findSharedEntryByUID(llvm::vfs::Status Stat)
const;
459 const CachedFileSystemEntry &
460 insertLocalEntryForFilename(StringRef Filename,
461 const CachedFileSystemEntry &Entry) {
468 const CachedFileSystemEntry &
469 getOrEmplaceSharedEntryForFilename(StringRef Filename, std::error_code EC);
474 const CachedFileSystemEntry &
475 getOrInsertSharedEntryForFilename(StringRef Filename,
476 const CachedFileSystemEntry &Entry);
478 void printImpl(raw_ostream &OS, PrintType
Type,
481 OS <<
"DependencyScanningFilesystem\n";
486 DependencyScanningService &Service;
489 DependencyScanningFilesystemLocalCache LocalCache;
493 llvm::ErrorOr<std::string> WorkingDirForCacheLookup;
495 void updateWorkingDirForCacheLookup();
497 llvm::ErrorOr<StringRef>
498 tryGetFilenameForLookup(StringRef OriginalFilename,
499 llvm::SmallVectorImpl<char> &PathBuf)
const;
This is the interface for scanning header and source files to get the minimum necessary preprocessor ...
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...
llvm::sys::fs::UniqueID getUniqueID() const
CachedFileSystemEntry(llvm::ErrorOr< llvm::vfs::Status > Stat, CachedFileContents *Contents)
Creates an entry representing a file with contents.
StringRef getOriginalContents() const
CachedFileContents * getCachedContents() const
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.
llvm::vfs::Status getStatus() const
std::error_code getError() const
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 & getShardForUID(llvm::sys::fs::UniqueID UID) const
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-...
DependencyScanningFilesystemSharedCache()
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.
llvm::vfs::Status getStatus() const
StringRef getContents() const
friend class DependencyScanningWorkerFilesystem
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.
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)
std::variant< NegativelyCachedInfo, SizeChangedInfo > Info
OutOfDateEntry(const char *Path, uint64_t CachedSize, uint64_t ActualSize)