summaryrefslogtreecommitdiff
path: root/llvm/lib/Support/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorBen Barham <ben_barham@apple.com>2022-03-09 12:23:22 -0800
committerBen Barham <ben_barham@apple.com>2022-03-17 13:02:40 -0700
commit4125524112e00c61547e83804279ef7889c8636a (patch)
treef8a409025335012bb8476efcf628adfc0886b755 /llvm/lib/Support/VirtualFileSystem.cpp
parentb4cc3b1dd8d7200640210513263b28187f810703 (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.cpp95
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;