diff options
| author | Ben Barham <ben_barham@apple.com> | 2022-03-09 12:23:22 -0800 |
|---|---|---|
| committer | Ben Barham <ben_barham@apple.com> | 2022-03-17 13:02:40 -0700 |
| commit | 4125524112e00c61547e83804279ef7889c8636a (patch) | |
| tree | f8a409025335012bb8476efcf628adfc0886b755 /llvm/lib/Support/VirtualFileSystem.cpp | |
| parent | b4cc3b1dd8d7200640210513263b28187f810703 (diff) | |
[VFS] Add print/dump to the whole FileSystem hierarchy
For now most are implemented by printing out the name of the filesystem,
but this can be expanded in the future. Only `OverlayFileSystem` and
`RedirectingFileSystem` are properly implemented in this patch.
- `OverlayFileSystem`: Prints each filesystem in the order that any
operations are actually run on them. Optionally prints recursively.
- `RedirectingFileSystem`: Prints out all mappings, as well as the
`ExternalFS`. Most of this was already implemented other than the
handling for the `DirectoryRemap` case and to actually print out the
mapping.
Each FS should implement `printImpl` rather than `print`, where the
latter just fowards to the former. This is to avoid spreading the
default arguments through to the subclasses (where we may miss updating
in the future).
Differential Revision: https://reviews.llvm.org/D121421
Diffstat (limited to 'llvm/lib/Support/VirtualFileSystem.cpp')
| -rw-r--r-- | llvm/lib/Support/VirtualFileSystem.cpp | 95 |
1 files changed, 79 insertions, 16 deletions
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index 1ca18e4b82cb..cb34fa60d801 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -151,6 +151,10 @@ bool FileSystem::exists(const Twine &Path) { return Status && Status->exists(); } +#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.equals("..") || Component.equals("."); @@ -273,6 +277,10 @@ public: std::error_code getRealPath(const Twine &Path, SmallVectorImpl<char> &Output) const override; +protected: + void printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const override; + private: // If this FS has its own working dir, use it to make Path absolute. // The returned twine is safe to use as long as both Storage and Path live. @@ -354,6 +362,17 @@ RealFileSystem::getRealPath(const Twine &Path, return llvm::sys::fs::real_path(adjustPath(Path, Storage), Output); } +void RealFileSystem::printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "RealFileSystem using "; + if (WD) + OS << "own"; + else + OS << "process"; + OS << " CWD\n"; +} + IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { static IntrusiveRefCntPtr<FileSystem> FS(new RealFileSystem(true)); return FS; @@ -459,6 +478,19 @@ OverlayFileSystem::getRealPath(const Twine &Path, return errc::no_such_file_or_directory; } +void OverlayFileSystem::printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "OverlayFileSystem\n"; + if (Type == PrintType::Summary) + return; + + if (Type == PrintType::Contents) + Type = PrintType::Summary; + for (auto FS : overlays_range()) + FS->print(OS, Type, IndentLevel + 1); +} + llvm::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { @@ -1047,6 +1079,12 @@ std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) { return {}; } +void InMemoryFileSystem::printImpl(raw_ostream &OS, PrintType PrintContents, + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "InMemoryFileSystem\n"; +} + } // namespace vfs } // namespace llvm @@ -1381,34 +1419,59 @@ std::vector<StringRef> RedirectingFileSystem::getRoots() const { return R; } -void RedirectingFileSystem::print(raw_ostream &OS) const { +void RedirectingFileSystem::printImpl(raw_ostream &OS, PrintType Type, + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "RedirectingFileSystem (UseExternalNames: " + << (UseExternalNames ? "true" : "false") << ")\n"; + if (Type == PrintType::Summary) + return; + for (const auto &Root : Roots) - printEntry(OS, Root.get()); + printEntry(OS, Root.get(), IndentLevel); + + printIndent(OS, IndentLevel); + OS << "ExternalFS:\n"; + ExternalFS->print(OS, Type == PrintType::Contents ? PrintType::Summary : Type, + IndentLevel + 1); } void RedirectingFileSystem::printEntry(raw_ostream &OS, RedirectingFileSystem::Entry *E, - int NumSpaces) const { - StringRef Name = E->getName(); - for (int i = 0, e = NumSpaces; i < e; ++i) - OS << " "; - OS << "'" << Name.str().c_str() << "'" - << "\n"; + unsigned IndentLevel) const { + printIndent(OS, IndentLevel); + OS << "'" << E->getName() << "'"; - if (E->getKind() == RedirectingFileSystem::EK_Directory) { - auto *DE = dyn_cast<RedirectingFileSystem::DirectoryEntry>(E); - assert(DE && "Should be a directory"); + switch (E->getKind()) { + case EK_Directory: { + auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(E); + OS << "\n"; for (std::unique_ptr<Entry> &SubEntry : llvm::make_range(DE->contents_begin(), DE->contents_end())) - printEntry(OS, SubEntry.get(), NumSpaces + 2); + printEntry(OS, SubEntry.get(), IndentLevel + 1); + break; + } + case EK_DirectoryRemap: + case EK_File: { + auto *RE = cast<RedirectingFileSystem::RemapEntry>(E); + OS << " -> '" << RE->getExternalContentsPath() << "'"; + switch (RE->getUseName()) { + case NK_NotSet: + break; + case NK_External: + OS << " (UseExternalName: true)"; + break; + case NK_Virtual: + OS << " (UseExternalName: false)"; + break; + } + OS << "\n"; + break; + } } } -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -void RedirectingFileSystem::dump() const { print(dbgs()); } -#endif - /// A helper class to hold the common YAML parsing state. class llvm::vfs::RedirectingFileSystemParser { yaml::Stream &Stream; |
