From 86814bf658a64ac11e548f0a133c9a7d9ca3f831 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 24 Jul 2019 22:59:20 +0000 Subject: [PATCH] [Support] move FileCollector from LLDB to llvm/Support The file collector class is useful for creating reproducers, not just for LLDB, but for other tools as well in LLVM/Clang. Differential Revision: https://reviews.llvm.org/D65237 llvm-svn: 366956 --- lldb/include/lldb/Utility/FileCollector.h | 62 ++++-------------- lldb/source/Utility/CMakeLists.txt | 1 - lldb/unittests/Utility/CMakeLists.txt | 1 - llvm/include/llvm/Support/FileCollector.h | 74 ++++++++++++++++++++++ llvm/lib/Support/CMakeLists.txt | 1 + .../Utility => llvm/lib/Support}/FileCollector.cpp | 21 +++--- llvm/unittests/Support/CMakeLists.txt | 1 + .../unittests/Support}/FileCollectorTest.cpp | 29 ++++----- 8 files changed, 110 insertions(+), 80 deletions(-) create mode 100644 llvm/include/llvm/Support/FileCollector.h rename {lldb/source/Utility => llvm/lib/Support}/FileCollector.cpp (91%) rename {lldb/unittests/Utility => llvm/unittests/Support}/FileCollectorTest.cpp (89%) diff --git a/lldb/include/lldb/Utility/FileCollector.h b/lldb/include/lldb/Utility/FileCollector.h index a892067..96d03a8 100644 --- a/lldb/include/lldb/Utility/FileCollector.h +++ b/lldb/include/lldb/Utility/FileCollector.h @@ -11,65 +11,29 @@ #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 +#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); - - void AddFile(const llvm::Twine &file); - void AddFile(const FileSpec &file) { return AddFile(file.GetPath()); } - - /// 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; } + FileCollector(const FileSpec &root, const FileSpec &overlay) : + llvm::FileCollector(root.GetPath(), overlay.GetPath()) {} - bool GetRealPath(llvm::StringRef src_path, - llvm::SmallVectorImpl &result); + using llvm::FileCollector::AddFile; - void AddFileToMapping(llvm::StringRef virtual_path, - llvm::StringRef real_path) { - m_vfs_writer.addFileMapping(virtual_path, real_path); + void AddFile(const FileSpec &file) { + std::string path = file.GetPath(); + llvm::FileCollector::AddFile(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 m_symlink_map; + /// Write the yaml mapping (for the VFS) to the given file. + std::error_code WriteMapping(const FileSpec &mapping_file) { + std::string path = mapping_file.GetPath(); + return llvm::FileCollector::WriteMapping(path); + } }; } // namespace lldb_private diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt index 03254c3..110b04e 100644 --- a/lldb/source/Utility/CMakeLists.txt +++ b/lldb/source/Utility/CMakeLists.txt @@ -23,7 +23,6 @@ add_lldb_library(lldbUtility DataEncoder.cpp DataExtractor.cpp Environment.cpp - FileCollector.cpp Event.cpp FileSpec.cpp IOObject.cpp diff --git a/lldb/unittests/Utility/CMakeLists.txt b/lldb/unittests/Utility/CMakeLists.txt index ad73fdf4..9db5cc1 100644 --- a/lldb/unittests/Utility/CMakeLists.txt +++ b/lldb/unittests/Utility/CMakeLists.txt @@ -10,7 +10,6 @@ add_lldb_unittest(UtilityTests DataExtractorTest.cpp EnvironmentTest.cpp EventTest.cpp - FileCollectorTest.cpp FileSpecTest.cpp FlagsTest.cpp JSONTest.cpp diff --git a/llvm/include/llvm/Support/FileCollector.h b/llvm/include/llvm/Support/FileCollector.h new file mode 100644 index 0000000..bf0aa59 --- /dev/null +++ b/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 + +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); + +private: + void AddFileImpl(StringRef src_path); + + bool MarkAsSeen(StringRef path) { return m_seen.insert(path).second; } + + bool GetRealPath(StringRef src_path, + SmallVectorImpl &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 m_symlink_map; +}; + +} // end namespace llvm + +#endif // LLVM_SUPPORT_FILE_COLLECTOR_H diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 7dfa97c..1ce131c 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -89,6 +89,7 @@ add_llvm_library(LLVMSupport Error.cpp ErrorHandling.cpp FileCheck.cpp + FileCollector.cpp FileUtilities.cpp FileOutputBuffer.cpp FoldingSet.cpp diff --git a/lldb/source/Utility/FileCollector.cpp b/llvm/lib/Support/FileCollector.cpp similarity index 91% rename from lldb/source/Utility/FileCollector.cpp rename to llvm/lib/Support/FileCollector.cpp index ed93591..05bea66 100644 --- a/lldb/source/Utility/FileCollector.cpp +++ b/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 @@ static bool IsCaseSensitivePath(StringRef path) { 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::AddFile(const Twine &file) { } 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 @@ void FileCollector::AddFileImpl(StringRef src_path) { 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 @@ std::error_code FileCollector::CopyFiles(bool stop_on_error) { return {}; } -std::error_code FileCollector::WriteMapping(const FileSpec &mapping_file) { +std::error_code FileCollector::WriteMapping(StringRef mapping_file) { std::lock_guard 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; diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt index da2b501..1765904 100644 --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -30,6 +30,7 @@ add_llvm_unittest(SupportTests ErrorOrTest.cpp ErrorTest.cpp FileCheckTest.cpp + FileCollectorTest.cpp FileOutputBufferTest.cpp FormatVariadicTest.cpp GlobPatternTest.cpp diff --git a/lldb/unittests/Utility/FileCollectorTest.cpp b/llvm/unittests/Support/FileCollectorTest.cpp similarity index 89% rename from lldb/unittests/Utility/FileCollectorTest.cpp rename to llvm/unittests/Support/FileCollectorTest.cpp index 348b4cc..38c5773 100644 --- a/lldb/unittests/Utility/FileCollectorTest.cpp +++ b/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 @@ public: 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 @@ struct ScopedFile { 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 @@ TEST(FileCollectorTest, CopyFiles) { // 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 @@ TEST(FileCollectorTest, Symlinks) { // 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. -- 2.7.4