#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileSystem/UniqueID.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <system_error>
#include <utility>
#include <vector>
usingnamespacellvm;
usingnamespacellvm::vfs;
file_t;
file_status;
file_type;
kInvalidFile;
perms;
UniqueID;
Status::Status(const file_status &Status)
: … { … }
Status::Status(const Twine &Name, UniqueID UID, sys::TimePoint<> MTime,
uint32_t User, uint32_t Group, uint64_t Size, file_type Type,
perms Perms)
: … { … }
Status Status::copyWithNewSize(const Status &In, uint64_t NewSize) { … }
Status Status::copyWithNewName(const Status &In, const Twine &NewName) { … }
Status Status::copyWithNewName(const file_status &In, const Twine &NewName) { … }
bool Status::equivalent(const Status &Other) const { … }
bool Status::isDirectory() const { … }
bool Status::isRegularFile() const { … }
bool Status::isOther() const { … }
bool Status::isSymlink() const { … }
bool Status::isStatusKnown() const { … }
bool Status::exists() const { … }
File::~File() = default;
FileSystem::~FileSystem() = default;
ErrorOr<std::unique_ptr<MemoryBuffer>>
FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize,
bool RequiresNullTerminator, bool IsVolatile) { … }
std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { … }
std::error_code FileSystem::getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) { … }
std::error_code FileSystem::isLocal(const Twine &Path, bool &Result) { … }
bool FileSystem::exists(const Twine &Path) { … }
llvm::ErrorOr<bool> FileSystem::equivalent(const Twine &A, const Twine &B) { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void FileSystem::dump() const { print(dbgs(), PrintType::RecursiveContents); }
#endif
#ifndef NDEBUG
static bool isTraversalComponent(StringRef Component) {
return Component == ".." || Component == ".";
}
static bool pathHasTraversal(StringRef Path) {
using namespace llvm::sys;
for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path)))
if (isTraversalComponent(Comp))
return true;
return false;
}
#endif
namespace {
class RealFile : public File { … };
}
RealFile::~RealFile() { … }
ErrorOr<Status> RealFile::status() { … }
ErrorOr<std::string> RealFile::getName() { … }
ErrorOr<std::unique_ptr<MemoryBuffer>>
RealFile::getBuffer(const Twine &Name, int64_t FileSize,
bool RequiresNullTerminator, bool IsVolatile) { … }
std::error_code RealFile::close() { … }
void RealFile::setPath(const Twine &Path) { … }
namespace {
class RealFileSystem : public FileSystem { … };
}
ErrorOr<Status> RealFileSystem::status(const Twine &Path) { … }
ErrorOr<std::unique_ptr<File>>
RealFileSystem::openFileForRead(const Twine &Name) { … }
llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const { … }
std::error_code RealFileSystem::setCurrentWorkingDirectory(const Twine &Path) { … }
std::error_code RealFileSystem::isLocal(const Twine &Path, bool &Result) { … }
std::error_code RealFileSystem::getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) { … }
void RealFileSystem::printImpl(raw_ostream &OS, PrintType Type,
unsigned IndentLevel) const { … }
IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { … }
std::unique_ptr<FileSystem> vfs::createPhysicalFileSystem() { … }
namespace {
class RealFSDirIter : public llvm::vfs::detail::DirIterImpl { … };
}
directory_iterator RealFileSystem::dir_begin(const Twine &Dir,
std::error_code &EC) { … }
OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) { … }
void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) { … }
ErrorOr<Status> OverlayFileSystem::status(const Twine &Path) { … }
bool OverlayFileSystem::exists(const Twine &Path) { … }
ErrorOr<std::unique_ptr<File>>
OverlayFileSystem::openFileForRead(const llvm::Twine &Path) { … }
llvm::ErrorOr<std::string>
OverlayFileSystem::getCurrentWorkingDirectory() const { … }
std::error_code
OverlayFileSystem::setCurrentWorkingDirectory(const Twine &Path) { … }
std::error_code OverlayFileSystem::isLocal(const Twine &Path, bool &Result) { … }
std::error_code OverlayFileSystem::getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) { … }
void OverlayFileSystem::visitChildFileSystems(VisitCallbackTy Callback) { … }
void OverlayFileSystem::printImpl(raw_ostream &OS, PrintType Type,
unsigned IndentLevel) const { … }
llvm::vfs::detail::DirIterImpl::~DirIterImpl() = default;
namespace {
class CombiningDirIterImpl : public llvm::vfs::detail::DirIterImpl { … };
}
directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir,
std::error_code &EC) { … }
void ProxyFileSystem::anchor() { … }
namespace llvm {
namespace vfs {
namespace detail {
enum InMemoryNodeKind { … };
class InMemoryNode { … };
class InMemoryFile : public InMemoryNode { … };
namespace {
class InMemoryHardLink : public InMemoryNode { … };
class InMemorySymbolicLink : public InMemoryNode { … };
class InMemoryFileAdaptor : public File { … };
}
class InMemoryDirectory : public InMemoryNode { … };
}
static sys::fs::UniqueID getUniqueID(hash_code Hash) { … }
static sys::fs::UniqueID getFileID(sys::fs::UniqueID Parent,
llvm::StringRef Name,
llvm::StringRef Contents) { … }
static sys::fs::UniqueID getDirectoryID(sys::fs::UniqueID Parent,
llvm::StringRef Name) { … }
Status detail::NewInMemoryNodeInfo::makeStatus() const { … }
InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths)
: … { … }
InMemoryFileSystem::~InMemoryFileSystem() = default;
std::string InMemoryFileSystem::toString() const { … }
bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
std::unique_ptr<llvm::MemoryBuffer> Buffer,
std::optional<uint32_t> User,
std::optional<uint32_t> Group,
std::optional<llvm::sys::fs::file_type> Type,
std::optional<llvm::sys::fs::perms> Perms,
MakeNodeFn MakeNode) { … }
bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime,
std::unique_ptr<llvm::MemoryBuffer> Buffer,
std::optional<uint32_t> User,
std::optional<uint32_t> Group,
std::optional<llvm::sys::fs::file_type> Type,
std::optional<llvm::sys::fs::perms> Perms) { … }
bool InMemoryFileSystem::addFileNoOwn(
const Twine &P, time_t ModificationTime,
const llvm::MemoryBufferRef &Buffer, std::optional<uint32_t> User,
std::optional<uint32_t> Group, std::optional<llvm::sys::fs::file_type> Type,
std::optional<llvm::sys::fs::perms> Perms) { … }
detail::NamedNodeOrError
InMemoryFileSystem::lookupNode(const Twine &P, bool FollowFinalSymlink,
size_t SymlinkDepth) const { … }
bool InMemoryFileSystem::addHardLink(const Twine &NewLink,
const Twine &Target) { … }
bool InMemoryFileSystem::addSymbolicLink(
const Twine &NewLink, const Twine &Target, time_t ModificationTime,
std::optional<uint32_t> User, std::optional<uint32_t> Group,
std::optional<llvm::sys::fs::perms> Perms) { … }
llvm::ErrorOr<Status> InMemoryFileSystem::status(const Twine &Path) { … }
llvm::ErrorOr<std::unique_ptr<File>>
InMemoryFileSystem::openFileForRead(const Twine &Path) { … }
class InMemoryFileSystem::DirIterator : public llvm::vfs::detail::DirIterImpl { … };
directory_iterator InMemoryFileSystem::dir_begin(const Twine &Dir,
std::error_code &EC) { … }
std::error_code InMemoryFileSystem::setCurrentWorkingDirectory(const Twine &P) { … }
std::error_code InMemoryFileSystem::getRealPath(const Twine &Path,
SmallVectorImpl<char> &Output) { … }
std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) { … }
void InMemoryFileSystem::printImpl(raw_ostream &OS, PrintType PrintContents,
unsigned IndentLevel) const { … }
}
}
namespace {
static llvm::sys::path::Style getExistingStyle(llvm::StringRef Path) { … }
static llvm::SmallString<256> canonicalize(llvm::StringRef Path) { … }
static bool isFileNotFound(std::error_code EC,
RedirectingFileSystem::Entry *E = nullptr) { … }
}
RedirectingFileSystem::RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> FS)
: … { … }
class llvm::vfs::RedirectingFSDirIterImpl
: public llvm::vfs::detail::DirIterImpl { … };
namespace {
class RedirectingFSDirRemapIterImpl : public llvm::vfs::detail::DirIterImpl { … };
}
llvm::ErrorOr<std::string>
RedirectingFileSystem::getCurrentWorkingDirectory() const { … }
std::error_code
RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) { … }
std::error_code RedirectingFileSystem::isLocal(const Twine &Path_,
bool &Result) { … }
std::error_code RedirectingFileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { … }
std::error_code
RedirectingFileSystem::makeAbsolute(StringRef WorkingDir,
SmallVectorImpl<char> &Path) const { … }
directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
std::error_code &EC) { … }
void RedirectingFileSystem::setOverlayFileDir(StringRef Dir) { … }
StringRef RedirectingFileSystem::getOverlayFileDir() const { … }
void RedirectingFileSystem::setFallthrough(bool Fallthrough) { … }
void RedirectingFileSystem::setRedirection(
RedirectingFileSystem::RedirectKind Kind) { … }
std::vector<StringRef> RedirectingFileSystem::getRoots() const { … }
void RedirectingFileSystem::printImpl(raw_ostream &OS, PrintType Type,
unsigned IndentLevel) const { … }
void RedirectingFileSystem::printEntry(raw_ostream &OS,
RedirectingFileSystem::Entry *E,
unsigned IndentLevel) const { … }
void RedirectingFileSystem::visitChildFileSystems(VisitCallbackTy Callback) { … }
class llvm::vfs::RedirectingFileSystemParser { … };
std::unique_ptr<RedirectingFileSystem>
RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath, void *DiagContext,
IntrusiveRefCntPtr<FileSystem> ExternalFS) { … }
std::unique_ptr<RedirectingFileSystem> RedirectingFileSystem::create(
ArrayRef<std::pair<std::string, std::string>> RemappedFiles,
bool UseExternalNames, FileSystem &ExternalFS) { … }
RedirectingFileSystem::LookupResult::LookupResult(
Entry *E, sys::path::const_iterator Start, sys::path::const_iterator End)
: … { … }
void RedirectingFileSystem::LookupResult::getPath(
llvm::SmallVectorImpl<char> &Result) const { … }
std::error_code RedirectingFileSystem::makeCanonicalForLookup(
SmallVectorImpl<char> &Path) const { … }
ErrorOr<RedirectingFileSystem::LookupResult>
RedirectingFileSystem::lookupPath(StringRef Path) const { … }
ErrorOr<RedirectingFileSystem::LookupResult>
RedirectingFileSystem::lookupPathImpl(
sys::path::const_iterator Start, sys::path::const_iterator End,
RedirectingFileSystem::Entry *From,
llvm::SmallVectorImpl<Entry *> &Entries) const { … }
static Status getRedirectedFileStatus(const Twine &OriginalPath,
bool UseExternalNames,
Status ExternalStatus) { … }
ErrorOr<Status> RedirectingFileSystem::status(
const Twine &LookupPath, const Twine &OriginalPath,
const RedirectingFileSystem::LookupResult &Result) { … }
ErrorOr<Status>
RedirectingFileSystem::getExternalStatus(const Twine &LookupPath,
const Twine &OriginalPath) const { … }
ErrorOr<Status> RedirectingFileSystem::status(const Twine &OriginalPath) { … }
bool RedirectingFileSystem::exists(const Twine &OriginalPath) { … }
namespace {
class FileWithFixedStatus : public File { … };
}
ErrorOr<std::unique_ptr<File>>
File::getWithPath(ErrorOr<std::unique_ptr<File>> Result, const Twine &P) { … }
ErrorOr<std::unique_ptr<File>>
RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) { … }
std::error_code
RedirectingFileSystem::getRealPath(const Twine &OriginalPath,
SmallVectorImpl<char> &Output) { … }
std::unique_ptr<FileSystem>
vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath, void *DiagContext,
IntrusiveRefCntPtr<FileSystem> ExternalFS) { … }
static void getVFSEntries(RedirectingFileSystem::Entry *SrcE,
SmallVectorImpl<StringRef> &Path,
SmallVectorImpl<YAMLVFSEntry> &Entries) { … }
void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer,
SourceMgr::DiagHandlerTy DiagHandler,
StringRef YAMLFilePath,
SmallVectorImpl<YAMLVFSEntry> &CollectedEntries,
void *DiagContext,
IntrusiveRefCntPtr<FileSystem> ExternalFS) { … }
UniqueID vfs::getNextVirtualUniqueID() { … }
void YAMLVFSWriter::addEntry(StringRef VirtualPath, StringRef RealPath,
bool IsDirectory) { … }
void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) { … }
void YAMLVFSWriter::addDirectoryMapping(StringRef VirtualPath,
StringRef RealPath) { … }
namespace {
class JSONWriter { … };
}
bool JSONWriter::containedIn(StringRef Parent, StringRef Path) { … }
StringRef JSONWriter::containedPart(StringRef Parent, StringRef Path) { … }
void JSONWriter::startDirectory(StringRef Path) { … }
void JSONWriter::endDirectory() { … }
void JSONWriter::writeEntry(StringRef VPath, StringRef RPath) { … }
void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries,
std::optional<bool> UseExternalNames,
std::optional<bool> IsCaseSensitive,
std::optional<bool> IsOverlayRelative,
StringRef OverlayDir) { … }
void YAMLVFSWriter::write(llvm::raw_ostream &OS) { … }
vfs::recursive_directory_iterator::recursive_directory_iterator(
FileSystem &FS_, const Twine &Path, std::error_code &EC)
: … { … }
vfs::recursive_directory_iterator &
recursive_directory_iterator::increment(std::error_code &EC) { … }
void TracingFileSystem::printImpl(raw_ostream &OS, PrintType Type,
unsigned IndentLevel) const { … }
const char FileSystem::ID = …;
const char OverlayFileSystem::ID = …;
const char ProxyFileSystem::ID = …;
const char InMemoryFileSystem::ID = …;
const char RedirectingFileSystem::ID = …;
const char TracingFileSystem::ID = …;