;
40#define DEBUG_TYPE "file-search" 48: FS(
std::move(FS)), FileSystemOpts(FSO), SeenDirEntries(64),
49SeenFileEntries(64), NextFileUID(0) {
53this->FS = llvm::vfs::getRealFileSystem();
59assert(statCache &&
"No stat cache provided?");
60StatCache = std::move(statCache);
71 returnllvm::errorCodeToError(
75 returnllvm::errorCodeToError(
make_error_code(std::errc::is_a_directory));
77StringRef DirName = llvm::sys::path::parent_path(
Filename);
85DirectoryEntry*&FileManager::getRealDirEntry(
constllvm::vfs::Status &Status) {
86assert(Status.isDirectory() &&
"The directory should exist!");
103voidFileManager::addAncestorsAsVirtualDirs(StringRef
Path) {
104StringRef DirName = llvm::sys::path::parent_path(
Path);
108 auto&NamedDirEnt = *SeenDirEntries.insert(
109{DirName, std::errc::no_such_file_or_directory}).first;
115 if(NamedDirEnt.second)
119llvm::vfs::Status Status;
121getStatValue(DirName, Status,
false,
nullptr);
126NamedDirEnt.second = *UDE;
127VirtualDirectoryEntries.push_back(UDE);
131NamedDirEnt.second = *UDE;
135addAncestorsAsVirtualDirs(DirName);
143 if(DirName.size() > 1 &&
144DirName != llvm::sys::path::root_path(DirName) &&
145llvm::sys::path::is_separator(DirName.back()))
146DirName = DirName.substr(0, DirName.size()-1);
147std::optional<std::string> DirNameStr;
148 if(is_style_windows(llvm::sys::path::Style::native)) {
151 if(DirName.size() > 1 && DirName.back() ==
':'&&
152DirName.equals_insensitive(llvm::sys::path::root_name(DirName))) {
153DirNameStr = DirName.str() +
'.';
154DirName = *DirNameStr;
162 autoSeenDirInsertResult =
163SeenDirEntries.insert({DirName, std::errc::no_such_file_or_directory});
164 if(!SeenDirInsertResult.second) {
165 if(SeenDirInsertResult.first->second)
167 returnllvm::errorCodeToError(SeenDirInsertResult.first->second.getError());
172 auto&NamedDirEnt = *SeenDirInsertResult.first;
173assert(!NamedDirEnt.second &&
"should be newly-created");
177StringRef InterndDirName = NamedDirEnt.first();
180llvm::vfs::Status Status;
181 autostatError = getStatValue(InterndDirName, Status,
false,
186NamedDirEnt.second = statError;
188SeenDirEntries.erase(DirName);
189 returnllvm::errorCodeToError(statError);
194NamedDirEnt.second = *UDE;
199llvm::ErrorOr<const DirectoryEntry *>
200FileManager::getDirectory(StringRef DirName,
boolCacheFailure) {
203 return&
Result->getDirEntry();
204 returnllvm::errorToErrorCode(
Result.takeError());
207llvm::ErrorOr<const FileEntry *>
208FileManager::getFile(StringRef
Filename,
boolopenFile,
boolCacheFailure) {
211 return&
Result->getFileEntry();
212 returnllvm::errorToErrorCode(
Result.takeError());
222 autoSeenFileInsertResult =
223SeenFileEntries.insert({
Filename, std::errc::no_such_file_or_directory});
224 if(!SeenFileInsertResult.second) {
225 if(!SeenFileInsertResult.first->second)
226 returnllvm::errorCodeToError(
227SeenFileInsertResult.first->second.getError());
232++NumFileCacheMisses;
233 auto*NamedFileEnt = &*SeenFileInsertResult.first;
234assert(!NamedFileEnt->second &&
"should be newly-created");
238StringRef InterndFileName = NamedFileEnt->first();
247std::error_code Err = errorToErrorCode(DirInfoOrErr.takeError());
249NamedFileEnt->second = Err;
253 returnllvm::errorCodeToError(Err);
261std::unique_ptr<llvm::vfs::File> F;
262llvm::vfs::Status Status;
263 autostatError = getStatValue(InterndFileName, Status,
true,
264openFile ? &F :
nullptr, IsText);
268NamedFileEnt->second = statError;
272 returnllvm::errorCodeToError(statError);
275assert((openFile || !F) &&
"undesired open file");
279 FileEntry*&UFE = UniqueRealFiles[Status.getUniqueID()];
280 boolReusingEntry = UFE !=
nullptr;
282UFE =
new(FilesAlloc.Allocate())
FileEntry();
284 if(!Status.ExposesExternalVFSPath || Status.getName() ==
Filename) {
327assert(isa<FileEntry *>(Redirection.second->V) &&
328 "filename redirected to a non-canonical filename?");
329assert(cast<FileEntry *>(Redirection.second->V) == UFE &&
330 "filename from getStatValue() refers to wrong file");
343UFE->Size = Status.getSize();
344UFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
346UFE->UID = NextFileUID++;
347UFE->UniqueID = Status.getUniqueID();
348UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
349UFE->File = std::move(F);
352 if(
autoPathName = UFE->File->getName())
353fillRealPathName(UFE, *PathName);
354}
else if(!openFile) {
356fillRealPathName(UFE, InterndFileName);
366std::unique_ptr<llvm::MemoryBuffer> Content;
367 if(
autoContentOrError = llvm::MemoryBuffer::getSTDIN())
368Content = std::move(*ContentOrError);
370 returnllvm::errorCodeToError(ContentOrError.getError());
373Content->getBufferSize(), 0);
375FE.Content = std::move(Content);
376FE.IsNamedPipe =
true;
381FS->visit([Active](llvm::vfs::FileSystem &FileSys) {
382 if(
auto*RFS = dyn_cast<llvm::vfs::RedirectingFileSystem>(&FileSys))
383RFS->setUsageTrackingActive(Active);
388time_t ModificationTime) {
393time_t ModificationTime) {
397 auto&NamedFileEnt = *SeenFileEntries.insert(
398{
Filename, std::errc::no_such_file_or_directory}).first;
399 if(NamedFileEnt.second) {
401 if(LLVM_LIKELY(isa<FileEntry *>(
Value.V)))
407++NumFileCacheMisses;
408addAncestorsAsVirtualDirs(
Filename);
420 "The directory of a virtual file should already be in the cache.");
423llvm::vfs::Status Status;
424 const char*InterndFileName = NamedFileEnt.first().data();
425 if(!getStatValue(InterndFileName, Status,
true,
nullptr)) {
426Status = llvm::vfs::Status(
427Status.getName(), Status.getUniqueID(),
429Status.getUser(), Status.getGroup(),
Size,
430Status.getType(), Status.getPermissions());
432 auto&RealFE = UniqueRealFiles[Status.getUniqueID()];
447RealFE =
new(FilesAlloc.Allocate())
FileEntry();
448RealFE->UniqueID = Status.getUniqueID();
449RealFE->IsNamedPipe =
450Status.getType() == llvm::sys::fs::file_type::fifo_file;
451fillRealPathName(RealFE, Status.getName());
456UFE =
new(FilesAlloc.Allocate())
FileEntry();
457VirtualFileEntries.push_back(UFE);
463UFE->Dir = &DirInfo->getDirEntry();
464UFE->UID = NextFileUID++;
471llvm::vfs::Status Status;
472 if(getStatValue(VF.
getName(), Status,
true,
nullptr))
475 if(!SeenBypassFileEntries)
476SeenBypassFileEntries = std::make_unique<
477llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>>>();
480 autoInsertion = SeenBypassFileEntries->insert(
481{VF.
getName(), std::errc::no_such_file_or_directory});
482 if(!Insertion.second)
487BypassFileEntries.push_back(BFE);
489BFE->Size = Status.getSize();
491BFE->ModTime = llvm::sys::toTimeT(Status.getLastModificationTime());
492BFE->UID = NextFileUID++;
499StringRef pathRef(path.data(), path.size());
502|| llvm::sys::path::is_absolute(pathRef))
506llvm::sys::path::append(NewPath, pathRef);
514 if(!llvm::sys::path::is_absolute(StringRef(
Path.data(),
Path.size()))) {
515FS->makeAbsolute(
Path);
529llvm::sys::path::remove_dots(AbsPath,
true);
530UFE->RealPathName = std::string(AbsPath);
533llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
535 boolRequiresNullTerminator,
536std::optional<int64_t> MaybeLimit,
boolIsText) {
540 returnllvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef());
542uint64_t FileSize = Entry->
getSize();
545FileSize = *MaybeLimit;
556RequiresNullTerminator, isVolatile);
562 returngetBufferForFileImpl(
Filename, FileSize, isVolatile,
563RequiresNullTerminator, IsText);
566llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
567FileManager::getBufferForFileImpl(StringRef
Filename, int64_t FileSize,
568 boolisVolatile,
boolRequiresNullTerminator,
571 returnFS->getBufferForFile(
Filename, FileSize, RequiresNullTerminator,
576 returnFS->getBufferForFile(FilePath, FileSize, RequiresNullTerminator,
585std::error_code FileManager::getStatValue(StringRef
Path,
586llvm::vfs::Status &Status,
588std::unique_ptr<llvm::vfs::File> *F,
600StatCache.get(), *FS, IsText);
605llvm::vfs::Status &
Result) {
609llvm::ErrorOr<llvm::vfs::Status> S = FS->status(FilePath.c_str());
613 returnstd::error_code();
619UIDToFiles.resize(NextFileUID);
621 for(
const auto&Entry : SeenFileEntries) {
623 if(!Entry.getValue() || !isa<FileEntry *>(Entry.getValue()->V))
643llvm::DenseMap<const void *, llvm::StringRef>::iterator Known =
644CanonicalNames.find(Entry);
645 if(Known != CanonicalNames.end())
646 returnKnown->second;
650StringRef CanonicalName(Name);
654 if(!FS->getRealPath(Name, RealPathBuf)) {
655 if(is_style_windows(llvm::sys::path::Style::native)) {
659 if(!FS->makeAbsolute(AbsPathBuf)) {
660 if(llvm::sys::path::root_name(RealPathBuf) ==
661llvm::sys::path::root_name(AbsPathBuf)) {
662CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
667llvm::sys::path::remove_dots(AbsPathBuf,
true);
668CanonicalName = AbsPathBuf.str().copy(CanonicalNameStorage);
672CanonicalName = RealPathBuf.str().copy(CanonicalNameStorage);
676CanonicalNames.insert({Entry, CanonicalName});
677 returnCanonicalName;
681assert(&
Other!=
this&&
"Collecting stats into the same FileManager");
682NumDirLookups +=
Other.NumDirLookups;
683NumFileLookups +=
Other.NumFileLookups;
684NumDirCacheMisses +=
Other.NumDirCacheMisses;
685NumFileCacheMisses +=
Other.NumFileCacheMisses;
689llvm::errs() <<
"\n*** File Manager Stats:\n";
690llvm::errs() << UniqueRealFiles.size() <<
" real files found, " 691<< UniqueRealDirs.size() <<
" real dirs found.\n";
692llvm::errs() << VirtualFileEntries.size() <<
" virtual files found, " 693<< VirtualDirectoryEntries.size() <<
" virtual dirs found.\n";
694llvm::errs() << NumDirLookups <<
" dir lookups, " 695<< NumDirCacheMisses <<
" dir cache misses.\n";
696llvm::errs() << NumFileLookups <<
" file lookups, " 697<< NumFileCacheMisses <<
" file cache misses.\n";
700 if(
auto*
T= dyn_cast_or_null<llvm::vfs::TracingFileSystem>(&VFS))
701llvm::errs() <<
"\n*** Virtual File System Stats:\n" 702<<
T->NumStatusCalls <<
" status() calls\n" 703<<
T->NumOpenFileForReadCalls <<
" openFileForRead() calls\n" 704<<
T->NumDirBeginCalls <<
" dir_begin() calls\n" 705<<
T->NumGetRealPathCalls <<
" getRealPath() calls\n" 706<<
T->NumExistsCalls <<
" exists() calls\n" 707<<
T->NumIsLocalCalls <<
" isLocal() calls\n";
static llvm::Expected< DirectoryEntryRef > getDirectoryFromFile(FileManager &FileMgr, StringRef Filename, bool CacheFailure)
Retrieve the directory that the given file name resides in.
Defines the clang::FileManager interface and associated types.
Defines the FileSystemStatCache interface.
A reference to a DirectoryEntry that includes the name of the directory as it was accessed by the Fil...
StringRef getName() const
const DirectoryEntry & getDirEntry() const
Cached information about one directory (either on disk or in the virtual file system).
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
const FileEntry & getFileEntry() const
StringRef getName() const
The name of this FileEntry.
DirectoryEntryRef getDir() const
Cached information about one file (either on disk or in the virtual file system).
bool isNamedPipe() const
Check whether the file is a named pipe (and thus can't be opened by the native FileManager methods).
Implements support for file system lookup, file system caching, and directory search management.
void AddStats(const FileManager &Other)
Import statistics from a child FileManager and add them to this current FileManager.
void trackVFSUsage(bool Active)
Enable or disable tracking of VFS usage.
void clearStatCache()
Removes the FileSystemStatCache object from the manager.
off_t time_t ModificationTime
llvm::vfs::FileSystem & getVirtualFileSystem() const
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(FileEntryRef Entry, bool isVolatile=false, bool RequiresNullTerminator=true, std::optional< int64_t > MaybeLimit=std::nullopt, bool IsText=true)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
std::error_code getNoncachedStatValue(StringRef Path, llvm::vfs::Status &Result)
Get the 'stat' information for the given Path.
FileManager(const FileSystemOptions &FileSystemOpts, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=nullptr)
Construct a file manager, optionally with a custom VFS.
llvm::Expected< FileEntryRef > getSTDIN()
Get the FileEntryRef for stdin, returning an error if stdin cannot be read.
StringRef getCanonicalName(DirectoryEntryRef Dir)
Retrieve the canonical name for a given directory.
void GetUniqueIDMapping(SmallVectorImpl< OptionalFileEntryRef > &UIDToFiles) const
Produce an array mapping from the unique IDs assigned to each file to the corresponding FileEntryRef.
bool makeAbsolutePath(SmallVectorImpl< char > &Path) const
Makes Path absolute taking into account FileSystemOptions and the working directory option.
llvm::Expected< DirectoryEntryRef > getDirectoryRef(StringRef DirName, bool CacheFailure=true)
Lookup, cache, and verify the specified directory (real or virtual).
void setStatCache(std::unique_ptr< FileSystemStatCache > statCache)
Installs the provided FileSystemStatCache object within the FileManager.
FileEntryRef getVirtualFileRef(StringRef Filename, off_t Size, time_t ModificationTime)
Retrieve a file entry for a "virtual" file that acts as if there were a file with the given name on d...
bool FixupRelativePath(SmallVectorImpl< char > &path) const
If path is not absolute and FileSystemOptions set the working directory, the path is modified to be r...
OptionalFileEntryRef getBypassFile(FileEntryRef VFE)
Retrieve a FileEntry that bypasses VFE, which is expected to be a virtual file entry,...
LLVM_DEPRECATED("Functions returning DirectoryEntry are deprecated.", "getOptionalDirectoryRef()") llvm LLVM_DEPRECATED("Functions returning FileEntry are deprecated.", "getOptionalFileRef()") llvm llvm::Expected< FileEntryRef > getFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true, bool IsText=true)
Lookup, cache, and verify the specified directory (real or virtual).
Keeps track of options that affect how file operations are performed.
std::string WorkingDir
If set, paths are resolved as if the working directory was set to the value of WorkingDir.
static std::error_code get(StringRef Path, llvm::vfs::Status &Status, bool isFile, std::unique_ptr< llvm::vfs::File > *F, FileSystemStatCache *Cache, llvm::vfs::FileSystem &FS, bool IsText=true)
Get the 'stat' information for the specified path, using the cache to accelerate it if possible.
The JSON file list parser is used to communicate input to InstallAPI.
std::error_code make_error_code(BuildPreambleError Error)
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Other
Other implicit parameter.
Type stored in the StringMap.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4