mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 07:01:03 +08:00
[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
This commit is contained in:
@@ -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 <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()); }
|
||||
using llvm::FileCollector::AddFile;
|
||||
|
||||
/// 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);
|
||||
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<std::string> 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
|
||||
|
||||
@@ -23,7 +23,6 @@ add_lldb_library(lldbUtility
|
||||
DataEncoder.cpp
|
||||
DataExtractor.cpp
|
||||
Environment.cpp
|
||||
FileCollector.cpp
|
||||
Event.cpp
|
||||
FileSpec.cpp
|
||||
IOObject.cpp
|
||||
|
||||
@@ -10,7 +10,6 @@ add_lldb_unittest(UtilityTests
|
||||
DataExtractorTest.cpp
|
||||
EnvironmentTest.cpp
|
||||
EventTest.cpp
|
||||
FileCollectorTest.cpp
|
||||
FileSpecTest.cpp
|
||||
FlagsTest.cpp
|
||||
JSONTest.cpp
|
||||
|
||||
74
llvm/include/llvm/Support/FileCollector.h
Normal file
74
llvm/include/llvm/Support/FileCollector.h
Normal file
@@ -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);
|
||||
|
||||
private:
|
||||
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
|
||||
@@ -89,6 +89,7 @@ add_llvm_library(LLVMSupport
|
||||
Error.cpp
|
||||
ErrorHandling.cpp
|
||||
FileCheck.cpp
|
||||
FileCollector.cpp
|
||||
FileUtilities.cpp
|
||||
FileOutputBuffer.cpp
|
||||
FoldingSet.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<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;
|
||||
|
||||
@@ -30,6 +30,7 @@ add_llvm_unittest(SupportTests
|
||||
ErrorOrTest.cpp
|
||||
ErrorTest.cpp
|
||||
FileCheckTest.cpp
|
||||
FileCollectorTest.cpp
|
||||
FileOutputBufferTest.cpp
|
||||
FormatVariadicTest.cpp
|
||||
GlobPatternTest.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.
|
||||
Reference in New Issue
Block a user