diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h --- a/llvm/include/llvm/Support/VirtualFileSystem.h +++ b/llvm/include/llvm/Support/VirtualFileSystem.h @@ -306,6 +306,12 @@ /// \returns success if \a path has been made absolute, otherwise a /// platform-specific error_code. virtual std::error_code makeAbsolute(SmallVectorImpl &Path) const; + + virtual void dump(raw_ostream &OS) const {} + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) + LLVM_DUMP_METHOD void dump() const; +#endif }; /// Gets an \p vfs::FileSystem for the 'real' file system, as seen by @@ -357,6 +363,8 @@ using const_iterator = FileSystemList::const_reverse_iterator; using reverse_iterator = FileSystemList::iterator; using const_reverse_iterator = FileSystemList::const_iterator; + using range = iterator_range; + using const_range = iterator_range; /// Get an iterator pointing to the most recently added file system. iterator overlays_begin() { return FSList.rbegin(); } @@ -373,6 +381,12 @@ /// Get an iterator pointing one-past the most recently added file system. reverse_iterator overlays_rend() { return FSList.end(); } const_reverse_iterator overlays_rend() const { return FSList.end(); } + + range overlays_range() { return llvm::reverse(FSList); } + + const_range overlays_range() const { return llvm::reverse(FSList); } + + void dump(raw_ostream &OS) const override; }; /// By default, this delegates all calls to the underlying file system. This @@ -520,6 +534,8 @@ SmallVectorImpl &Output) const override; std::error_code isLocal(const Twine &Path, bool &Result) override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + + void dump(raw_ostream &OS) const override; }; /// Get a globally unique ID for a virtual file or directory. @@ -910,11 +926,8 @@ std::vector getRoots() const; - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS) const override; void dumpEntry(raw_ostream &OS, Entry *E, int NumSpaces = 0) const; -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) - LLVM_DUMP_METHOD void dump() const; -#endif }; /// Collect all pairs of entries from the diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -151,6 +151,10 @@ return Status && Status->exists(); } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void FileSystem::dump() const { dump(dbgs()); } +#endif + #ifndef NDEBUG static bool isTraversalComponent(StringRef Component) { return Component.equals("..") || Component.equals("."); @@ -273,6 +277,8 @@ std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) const override; + virtual void dump(raw_ostream &OS) 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 +360,15 @@ return llvm::sys::fs::real_path(adjustPath(Path, Storage), Output); } +void RealFileSystem::dump(raw_ostream &OS) const { + OS << "RealFileSystem using "; + if (WD) + OS << "own"; + else + OS << "process"; + OS << " CWD\n"; +} + IntrusiveRefCntPtr vfs::getRealFileSystem() { static IntrusiveRefCntPtr FS(new RealFileSystem(true)); return FS; @@ -459,6 +474,15 @@ return errc::no_such_file_or_directory; } +void OverlayFileSystem::dump(raw_ostream &OS) const { + OS << "OverlayFileSystem running operations on: \n"; + for (auto FS : enumerate(overlays_range())) { + OS << FS.index() << ") "; + FS.value()->dump(OS); + OS << "\n"; + } +} + llvm::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { @@ -1047,6 +1071,10 @@ return {}; } +void InMemoryFileSystem::dump(raw_ostream &OS) const { + OS << "InMemoryFileSystem\n"; +} + } // namespace vfs } // namespace llvm @@ -1382,6 +1410,7 @@ } void RedirectingFileSystem::dump(raw_ostream &OS) const { + OS << "RedirectingFileSystem\n"; for (const auto &Root : Roots) dumpEntry(OS, Root.get()); } @@ -1392,23 +1421,29 @@ StringRef Name = E->getName(); for (int i = 0, e = NumSpaces; i < e; ++i) OS << " "; - OS << "'" << Name.str().c_str() << "'" - << "\n"; + OS << "'" << Name.str().c_str() << "'"; - if (E->getKind() == RedirectingFileSystem::EK_Directory) { - auto *DE = dyn_cast(E); - assert(DE && "Should be a directory"); + switch (E->getKind()) { + case EK_Directory: { + auto *DE = cast(E); + OS << "\n"; for (std::unique_ptr &SubEntry : llvm::make_range(DE->contents_begin(), DE->contents_end())) dumpEntry(OS, SubEntry.get(), NumSpaces + 2); + break; + } + case EK_DirectoryRemap: { + auto *DRE = cast(E); + OS << " -> '" << DRE->getExternalContentsPath() << "'\n"; + break; + } + case EK_File: + OS << "\n"; + break; } } -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void RedirectingFileSystem::dump() const { dump(dbgs()); } -#endif - /// A helper class to hold the common YAML parsing state. class llvm::vfs::RedirectingFileSystemParser { yaml::Stream &Stream; diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -171,6 +171,8 @@ sys::fs::file_type::symlink_file, sys::fs::all_all); addEntry(Path, S); } + + void dump(raw_ostream &OS) const override { OS << "DummyFileSystem\n"; } }; class ErrorDummyFileSystem : public DummyFileSystem {