arphaman created this revision. arphaman added a reviewer: JDevlieghere. Herald added subscribers: dexonsmith, jkorous, hiraditya, mgorny. Herald added projects: LLDB, LLVM.
The file collector class is useful for creating reproducers, not just for LLDB, but for other tools. That's why it should live in LLVM. I'm planning to use it in Clang to generate reproducers for `clang-scan-deps`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D65237 Files: lldb/include/lldb/Utility/FileCollector.h lldb/source/Utility/CMakeLists.txt lldb/source/Utility/FileCollector.cpp lldb/unittests/Utility/CMakeLists.txt lldb/unittests/Utility/FileCollectorTest.cpp llvm/include/llvm/Support/FileCollector.h llvm/lib/Support/CMakeLists.txt llvm/lib/Support/FileCollector.cpp llvm/unittests/Support/CMakeLists.txt llvm/unittests/Support/FileCollectorTest.cpp
Index: llvm/unittests/Support/FileCollectorTest.cpp =================================================================== --- llvm/unittests/Support/FileCollectorTest.cpp +++ llvm/unittests/Support/FileCollectorTest.cpp @@ -9,13 +9,10 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "lldb/Utility/FileCollector.h" -#include "lldb/Utility/FileSpec.h" - +#include "llvm/Support/FileCollector.h" #include "llvm/Support/FileSystem.h" using namespace llvm; -using namespace lldb_private; namespace llvm { namespace vfs { @@ -35,8 +32,8 @@ using FileCollector::m_symlink_map; using FileCollector::m_vfs_writer; - bool HasSeen(FileSpec fs) { - return m_seen.find(fs.GetPath()) != m_seen.end(); + bool HasSeen(StringRef fs) { + return m_seen.find(fs) != m_seen.end(); } }; @@ -104,23 +101,23 @@ TEST(FileCollectorTest, AddFile) { ScopedDir root("add_file_root", true); - FileSpec root_fs(root.Path); + std::string root_fs = root.Path.str(); TestingFileCollector file_collector(root_fs, root_fs); - file_collector.AddFile(FileSpec("/path/to/a")); - file_collector.AddFile(FileSpec("/path/to/b")); - file_collector.AddFile(FileSpec("/path/to/c")); + file_collector.AddFile("/path/to/a"); + file_collector.AddFile("/path/to/b"); + file_collector.AddFile("/path/to/c"); // Make sure the root is correct. EXPECT_EQ(file_collector.m_root, root_fs); // Make sure we've seen all the added files. - EXPECT_TRUE(file_collector.HasSeen(FileSpec("/path/to/a"))); - EXPECT_TRUE(file_collector.HasSeen(FileSpec("/path/to/b"))); - EXPECT_TRUE(file_collector.HasSeen(FileSpec("/path/to/c"))); + EXPECT_TRUE(file_collector.HasSeen("/path/to/a")); + EXPECT_TRUE(file_collector.HasSeen("/path/to/b")); + EXPECT_TRUE(file_collector.HasSeen("/path/to/c")); // Make sure we've only seen the added files. - EXPECT_FALSE(file_collector.HasSeen(FileSpec("/path/to/d"))); + EXPECT_FALSE(file_collector.HasSeen("/path/to/d")); } TEST(FileCollectorTest, CopyFiles) { @@ -131,7 +128,7 @@ // Create file collector and add files. ScopedDir root("copy_files_root", true); - FileSpec root_fs(root.Path); + std::string root_fs = root.Path.str(); TestingFileCollector file_collector(root_fs, root_fs); file_collector.AddFile(a.Path); file_collector.AddFile(b.Path); @@ -173,7 +170,7 @@ // Root where files are copied to. ScopedDir reproducer_root("reproducer_root", true); - FileSpec root_fs(reproducer_root.Path); + std::string root_fs = reproducer_root.Path.str(); TestingFileCollector file_collector(root_fs, root_fs); // Add all the files to the collector. Index: llvm/unittests/Support/CMakeLists.txt =================================================================== --- llvm/unittests/Support/CMakeLists.txt +++ llvm/unittests/Support/CMakeLists.txt @@ -30,6 +30,7 @@ ErrorOrTest.cpp ErrorTest.cpp FileCheckTest.cpp + FileCollectorTest.cpp FileOutputBufferTest.cpp FormatVariadicTest.cpp GlobPatternTest.cpp Index: llvm/lib/Support/FileCollector.cpp =================================================================== --- llvm/lib/Support/FileCollector.cpp +++ llvm/lib/Support/FileCollector.cpp @@ -6,14 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Utility/FileCollector.h" - +#include "llvm/Support/FileCollector.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" -using namespace lldb_private; using namespace llvm; static bool IsCaseSensitivePath(StringRef path) { @@ -34,9 +32,9 @@ return true; } -FileCollector::FileCollector(const FileSpec &root, const FileSpec &overlay_root) - : m_root(root), m_overlay_root(overlay_root) { - sys::fs::create_directories(m_root.GetPath(), true); +FileCollector::FileCollector(std::string root, std::string overlay_root) + : m_root(std::move(root)), m_overlay_root(std::move(overlay_root)) { + sys::fs::create_directories(this->m_root, true); } bool FileCollector::GetRealPath(StringRef src_path, @@ -71,8 +69,6 @@ } void FileCollector::AddFileImpl(StringRef src_path) { - std::string root = m_root.GetPath(); - // We need an absolute src path to append to the root. SmallString<256> absolute_src = src_path; sys::fs::make_absolute(absolute_src); @@ -94,7 +90,7 @@ if (!GetRealPath(absolute_src, copy_from)) copy_from = virtual_path; - SmallString<256> dst_path = StringRef(root); + SmallString<256> dst_path = StringRef(m_root); sys::path::append(dst_path, sys::path::relative_path(copy_from)); // Always map a canonical src path to its real path into the YAML, by doing @@ -162,17 +158,16 @@ return {}; } -std::error_code FileCollector::WriteMapping(const FileSpec &mapping_file) { +std::error_code FileCollector::WriteMapping(StringRef mapping_file) { std::lock_guard<std::mutex> lock(m_mutex); - std::string root = m_overlay_root.GetPath(); - + StringRef root = m_overlay_root; m_vfs_writer.setOverlayDir(root); m_vfs_writer.setCaseSensitivity(IsCaseSensitivePath(root)); m_vfs_writer.setUseExternalNames(false); std::error_code ec; - raw_fd_ostream os(mapping_file.GetPath(), ec, sys::fs::F_Text); + raw_fd_ostream os(mapping_file, ec, sys::fs::F_Text); if (ec) return ec; @@ -180,3 +175,4 @@ return {}; } + Index: llvm/lib/Support/CMakeLists.txt =================================================================== --- llvm/lib/Support/CMakeLists.txt +++ llvm/lib/Support/CMakeLists.txt @@ -89,6 +89,7 @@ Error.cpp ErrorHandling.cpp FileCheck.cpp + FileCollector.cpp FileUtilities.cpp FileOutputBuffer.cpp FoldingSet.cpp Index: llvm/include/llvm/Support/FileCollector.h =================================================================== --- /dev/null +++ llvm/include/llvm/Support/FileCollector.h @@ -0,0 +1,74 @@ +//===-- FileCollector.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_FILE_COLLECTOR_H +#define LLVM_SUPPORT_FILE_COLLECTOR_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/VirtualFileSystem.h" + +#include <mutex> + +namespace llvm { + +/// Collects files into a directory and generates a mapping that can be used by +/// the VFS. +class FileCollector { +public: + FileCollector(std::string root, std::string overlay); + + void AddFile(const Twine &file); + + /// Write the yaml mapping (for the VFS) to the given file. + std::error_code WriteMapping(StringRef mapping_file); + + /// Copy the files into the root directory. + /// + /// When stop_on_error is true (the default) we abort as soon as one file + /// cannot be copied. This is relatively common, for example when a file was + /// removed after it was added to the mapping. + std::error_code CopyFiles(bool stop_on_error = true); + +protected: + void AddFileImpl(StringRef src_path); + + bool MarkAsSeen(StringRef path) { return m_seen.insert(path).second; } + + bool GetRealPath(StringRef src_path, + SmallVectorImpl<char> &result); + + void AddFileToMapping(StringRef virtual_path, + StringRef real_path) { + m_vfs_writer.addFileMapping(virtual_path, real_path); + } + + /// Synchronizes adding files. + std::mutex m_mutex; + + /// The root directory where files are copied. + std::string m_root; + + /// The root directory where the VFS overlay lives. + std::string m_overlay_root; + + /// Tracks already seen files so they can be skipped. + StringSet<> m_seen; + + /// The yaml mapping writer. + vfs::YAMLVFSWriter m_vfs_writer; + + /// Caches real_path calls when resolving symlinks. + StringMap<std::string> m_symlink_map; +}; + +} // end namespace llvm + +#endif // LLVM_SUPPORT_FILE_COLLECTOR_H Index: lldb/unittests/Utility/CMakeLists.txt =================================================================== --- lldb/unittests/Utility/CMakeLists.txt +++ lldb/unittests/Utility/CMakeLists.txt @@ -10,7 +10,6 @@ DataExtractorTest.cpp EnvironmentTest.cpp EventTest.cpp - FileCollectorTest.cpp FileSpecTest.cpp FlagsTest.cpp JSONTest.cpp Index: lldb/source/Utility/CMakeLists.txt =================================================================== --- lldb/source/Utility/CMakeLists.txt +++ lldb/source/Utility/CMakeLists.txt @@ -23,7 +23,6 @@ DataEncoder.cpp DataExtractor.cpp Environment.cpp - FileCollector.cpp Event.cpp FileSpec.cpp IOObject.cpp Index: lldb/include/lldb/Utility/FileCollector.h =================================================================== --- lldb/include/lldb/Utility/FileCollector.h +++ lldb/include/lldb/Utility/FileCollector.h @@ -11,65 +11,27 @@ #include "lldb/Utility/FileSpec.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/VirtualFileSystem.h" - -#include <mutex> +#include "llvm/Support/FileCollector.h" namespace lldb_private { /// Collects files into a directory and generates a mapping that can be used by /// the VFS. -class FileCollector { +class FileCollector : public llvm::FileCollector { public: - FileCollector(const FileSpec &root, const FileSpec &overlay); + FileCollector(const FileSpec &root, const FileSpec &overlay) : + llvm::FileCollector(root.GetPath(), overlay.GetPath()) {} - void AddFile(const llvm::Twine &file); - void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); } + void AddFile(const FileSpec &file) { + std::string path = file.GetPath(); + llvm::FileCollector::AddFile(path); + } /// Write the yaml mapping (for the VFS) to the given file. - std::error_code WriteMapping(const FileSpec &mapping_file); - - /// Copy the files into the root directory. - /// - /// When stop_on_error is true (the default) we abort as soon as one file - /// cannot be copied. This is relatively common, for example when a file was - /// removed after it was added to the mapping. - std::error_code CopyFiles(bool stop_on_error = true); - -protected: - void AddFileImpl(llvm::StringRef src_path); - - bool MarkAsSeen(llvm::StringRef path) { return m_seen.insert(path).second; } - - bool GetRealPath(llvm::StringRef src_path, - llvm::SmallVectorImpl<char> &result); - - void AddFileToMapping(llvm::StringRef virtual_path, - llvm::StringRef real_path) { - m_vfs_writer.addFileMapping(virtual_path, real_path); + std::error_code WriteMapping(const FileSpec &mapping_file) { + std::string path = mapping_file.GetPath(); + return llvm::FileCollector::WriteMapping(path); } - - /// Synchronizes adding files. - std::mutex m_mutex; - - /// The root directory where files are copied. - FileSpec m_root; - - /// The root directory where the VFS overlay lives. - FileSpec m_overlay_root; - - /// Tracks already seen files so they can be skipped. - llvm::StringSet<> m_seen; - - /// The yaml mapping writer. - llvm::vfs::YAMLVFSWriter m_vfs_writer; - - /// Caches real_path calls when resolving symlinks. - llvm::StringMap<std::string> m_symlink_map; }; } // namespace lldb_private
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits