Skip to content

Commit de1720d

Browse files
author
git apple-llvm automerger
committed
Merge commit 'c1aa61938dd2' from apple/stable/20200108 into swift/master
2 parents 3666548 + c1aa619 commit de1720d

File tree

10 files changed

+311
-156
lines changed

10 files changed

+311
-156
lines changed

lldb/include/lldb/Utility/Reproducer.h

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class FileProvider : public Provider<FileProvider> {
9898
return m_collector;
9999
}
100100

101+
void recordInterestingDirectory(const llvm::Twine &dir);
102+
101103
void Keep() override {
102104
auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
103105
// Temporary files that are removed during execution can cause copy errors.

lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp

+127-120
Large diffs are not rendered by default.

lldb/source/Utility/Reproducer.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ void WorkingDirectoryProvider::Keep() {
321321
os << m_cwd << "\n";
322322
}
323323

324+
void FileProvider::recordInterestingDirectory(const llvm::Twine &dir) {
325+
if (m_collector)
326+
m_collector->addDirectory(dir);
327+
}
328+
324329
void ProviderBase::anchor() {}
325330
char CommandProvider::ID = 0;
326331
char FileProvider::ID = 0;
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# REQUIRES: system-darwin
2+
# Ensure that the reproducers captures the whole dSYM bundle.
3+
4+
# RUN: rm -rf %t.repro
5+
# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
6+
# RUN: touch %t.out.dSYM/foo.bar
7+
8+
# RUN: %lldb -x -b --capture --capture-path %t.repro %t.out -o 'b main' -o 'run' -o 'reproducer generate'
9+
10+
# RUN: %lldb -b -o 'reproducer dump -p files -f %t.repro' | FileCheck %s --check-prefix FILES
11+
# FILES: foo.bar

llvm/include/llvm/Support/FileCollector.h

+14-4
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@
1818
#include <mutex>
1919

2020
namespace llvm {
21-
21+
class FileCollectorFileSystem;
2222
/// Collects files into a directory and generates a mapping that can be used by
2323
/// the VFS.
2424
class FileCollector {
2525
public:
2626
FileCollector(std::string Root, std::string OverlayRoot);
2727

2828
void addFile(const Twine &file);
29+
void addDirectory(const Twine &Dir);
2930

3031
/// Write the yaml mapping (for the VFS) to the given file.
31-
std::error_code writeMapping(StringRef mapping_file);
32+
std::error_code writeMapping(StringRef MappingFile);
3233

3334
/// Copy the files into the root directory.
3435
///
@@ -44,7 +45,7 @@ class FileCollector {
4445
std::shared_ptr<FileCollector> Collector);
4546

4647
private:
47-
void addFileImpl(StringRef SrcPath);
48+
friend FileCollectorFileSystem;
4849

4950
bool markAsSeen(StringRef Path) {
5051
if (Path.empty())
@@ -55,10 +56,19 @@ class FileCollector {
5556
bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
5657

5758
void addFileToMapping(StringRef VirtualPath, StringRef RealPath) {
58-
VFSWriter.addFileMapping(VirtualPath, RealPath);
59+
if (sys::fs::is_directory(VirtualPath))
60+
VFSWriter.addDirectoryMapping(VirtualPath, RealPath);
61+
else
62+
VFSWriter.addFileMapping(VirtualPath, RealPath);
5963
}
6064

6165
protected:
66+
void addFileImpl(StringRef SrcPath);
67+
68+
llvm::vfs::directory_iterator
69+
addDirectoryImpl(const llvm::Twine &Dir,
70+
IntrusiveRefCntPtr<vfs::FileSystem> FS, std::error_code &EC);
71+
6272
/// Synchronizes adding files.
6373
std::mutex Mutex;
6474

llvm/include/llvm/Support/VirtualFileSystem.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -506,10 +506,12 @@ getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
506506

507507
struct YAMLVFSEntry {
508508
template <typename T1, typename T2>
509-
YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
510-
: VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
509+
YAMLVFSEntry(T1 &&VPath, T2 &&RPath, bool IsDirectory = false)
510+
: VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)),
511+
IsDirectory(IsDirectory) {}
511512
std::string VPath;
512513
std::string RPath;
514+
bool IsDirectory = false;
513515
};
514516

515517
class VFSFromYamlDirIterImpl;
@@ -781,10 +783,13 @@ class YAMLVFSWriter {
781783
Optional<bool> UseExternalNames;
782784
std::string OverlayDir;
783785

786+
void addEntry(StringRef VirtualPath, StringRef RealPath, bool IsDirectory);
787+
784788
public:
785789
YAMLVFSWriter() = default;
786790

787791
void addFileMapping(StringRef VirtualPath, StringRef RealPath);
792+
void addDirectoryMapping(StringRef VirtualPath, StringRef RealPath);
788793

789794
void setCaseSensitivity(bool CaseSensitive) {
790795
IsCaseSensitive = CaseSensitive;

llvm/lib/Support/FileCollector.cpp

+34-22
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,19 @@ bool FileCollector::getRealPath(StringRef SrcPath,
6161
return true;
6262
}
6363

64-
void FileCollector::addFile(const Twine &file) {
64+
void FileCollector::addFile(const Twine &File) {
6565
std::lock_guard<std::mutex> lock(Mutex);
66-
std::string FileStr = file.str();
66+
std::string FileStr = File.str();
6767
if (markAsSeen(FileStr))
6868
addFileImpl(FileStr);
6969
}
7070

71+
void FileCollector::addDirectory(const Twine &Dir) {
72+
assert(sys::fs::is_directory(Dir));
73+
std::error_code EC;
74+
addDirectoryImpl(Dir, vfs::getRealFileSystem(), EC);
75+
}
76+
7177
void FileCollector::addFileImpl(StringRef SrcPath) {
7278
// We need an absolute src path to append to the root.
7379
SmallString<256> AbsoluteSrc = SrcPath;
@@ -101,6 +107,27 @@ void FileCollector::addFileImpl(StringRef SrcPath) {
101107
addFileToMapping(VirtualPath, DstPath);
102108
}
103109

110+
llvm::vfs::directory_iterator
111+
FileCollector::addDirectoryImpl(const llvm::Twine &Dir,
112+
IntrusiveRefCntPtr<vfs::FileSystem> FS,
113+
std::error_code &EC) {
114+
auto It = FS->dir_begin(Dir, EC);
115+
if (EC)
116+
return It;
117+
addFile(Dir);
118+
for (; !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
119+
if (It->type() == sys::fs::file_type::regular_file ||
120+
It->type() == sys::fs::file_type::directory_file ||
121+
It->type() == sys::fs::file_type::symlink_file) {
122+
addFile(It->path());
123+
}
124+
}
125+
if (EC)
126+
return It;
127+
// Return a new iterator.
128+
return FS->dir_begin(Dir, EC);
129+
}
130+
104131
/// Set the access and modification time for the given file from the given
105132
/// status object.
106133
static std::error_code
@@ -171,15 +198,15 @@ std::error_code FileCollector::copyFiles(bool StopOnError) {
171198
return {};
172199
}
173200

174-
std::error_code FileCollector::writeMapping(StringRef mapping_file) {
201+
std::error_code FileCollector::writeMapping(StringRef MappingFile) {
175202
std::lock_guard<std::mutex> lock(Mutex);
176203

177204
VFSWriter.setOverlayDir(OverlayRoot);
178205
VFSWriter.setCaseSensitivity(isCaseSensitivePath(OverlayRoot));
179206
VFSWriter.setUseExternalNames(false);
180207

181208
std::error_code EC;
182-
raw_fd_ostream os(mapping_file, EC, sys::fs::OF_Text);
209+
raw_fd_ostream os(MappingFile, EC, sys::fs::OF_Text);
183210
if (EC)
184211
return EC;
185212

@@ -188,7 +215,7 @@ std::error_code FileCollector::writeMapping(StringRef mapping_file) {
188215
return {};
189216
}
190217

191-
namespace {
218+
namespace llvm {
192219

193220
class FileCollectorFileSystem : public vfs::FileSystem {
194221
public:
@@ -213,22 +240,7 @@ class FileCollectorFileSystem : public vfs::FileSystem {
213240

214241
llvm::vfs::directory_iterator dir_begin(const llvm::Twine &Dir,
215242
std::error_code &EC) override {
216-
auto It = FS->dir_begin(Dir, EC);
217-
if (EC)
218-
return It;
219-
// Collect everything that's listed in case the user needs it.
220-
Collector->addFile(Dir);
221-
for (; !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
222-
if (It->type() == sys::fs::file_type::regular_file ||
223-
It->type() == sys::fs::file_type::directory_file ||
224-
It->type() == sys::fs::file_type::symlink_file) {
225-
Collector->addFile(It->path());
226-
}
227-
}
228-
if (EC)
229-
return It;
230-
// Return a new iterator.
231-
return FS->dir_begin(Dir, EC);
243+
return Collector->addDirectoryImpl(Dir, FS, EC);
232244
}
233245

234246
std::error_code getRealPath(const Twine &Path,
@@ -259,7 +271,7 @@ class FileCollectorFileSystem : public vfs::FileSystem {
259271
std::shared_ptr<FileCollector> Collector;
260272
};
261273

262-
} // end anonymous namespace
274+
} // namespace llvm
263275

264276
IntrusiveRefCntPtr<vfs::FileSystem>
265277
FileCollector::createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,

llvm/lib/Support/VirtualFileSystem.cpp

+26-8
Original file line numberDiff line numberDiff line change
@@ -1894,11 +1894,21 @@ UniqueID vfs::getNextVirtualUniqueID() {
18941894
return UniqueID(std::numeric_limits<uint64_t>::max(), ID);
18951895
}
18961896

1897-
void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) {
1897+
void YAMLVFSWriter::addEntry(StringRef VirtualPath, StringRef RealPath,
1898+
bool IsDirectory) {
18981899
assert(sys::path::is_absolute(VirtualPath) && "virtual path not absolute");
18991900
assert(sys::path::is_absolute(RealPath) && "real path not absolute");
19001901
assert(!pathHasTraversal(VirtualPath) && "path traversal is not supported");
1901-
Mappings.emplace_back(VirtualPath, RealPath);
1902+
Mappings.emplace_back(VirtualPath, RealPath, IsDirectory);
1903+
}
1904+
1905+
void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) {
1906+
addEntry(VirtualPath, RealPath, /*IsDirectory=*/false);
1907+
}
1908+
1909+
void YAMLVFSWriter::addDirectoryMapping(StringRef VirtualPath,
1910+
StringRef RealPath) {
1911+
addEntry(VirtualPath, RealPath, /*IsDirectory=*/true);
19021912
}
19031913

19041914
namespace {
@@ -1999,7 +2009,10 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries,
19992009

20002010
if (!Entries.empty()) {
20012011
const YAMLVFSEntry &Entry = Entries.front();
2002-
startDirectory(path::parent_path(Entry.VPath));
2012+
bool first_entry_is_directory = Entry.IsDirectory;
2013+
StringRef Dir = first_entry_is_directory ? StringRef(Entry.VPath)
2014+
: path::parent_path(Entry.VPath);
2015+
startDirectory(Dir);
20032016

20042017
StringRef RPath = Entry.RPath;
20052018
if (UseOverlayRelative) {
@@ -2009,13 +2022,18 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries,
20092022
RPath = RPath.slice(OverlayDirLen, RPath.size());
20102023
}
20112024

2012-
writeEntry(path::filename(Entry.VPath), RPath);
2025+
if (!first_entry_is_directory)
2026+
writeEntry(path::filename(Entry.VPath), RPath);
20132027

20142028
for (const auto &Entry : Entries.slice(1)) {
2015-
StringRef Dir = path::parent_path(Entry.VPath);
2016-
if (Dir == DirStack.back())
2017-
OS << ",\n";
2018-
else {
2029+
StringRef Dir = Entry.IsDirectory ? StringRef(Entry.VPath)
2030+
: path::parent_path(Entry.VPath);
2031+
if (Dir == DirStack.back()) {
2032+
if (!first_entry_is_directory) {
2033+
OS << ",\n";
2034+
first_entry_is_directory = false;
2035+
}
2036+
} else {
20192037
while (!DirStack.empty() && !containedIn(DirStack.back(), Dir)) {
20202038
OS << "\n";
20212039
endDirectory();

llvm/unittests/Support/FileCollectorTest.cpp

+35
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,41 @@ TEST(FileCollectorTest, addFile) {
120120
EXPECT_FALSE(FileCollector.hasSeen("/path/to/d"));
121121
}
122122

123+
TEST(FileCollectorTest, addDirectory) {
124+
ScopedDir file_root("file_root", true);
125+
126+
llvm::SmallString<128> aaa = file_root.Path;
127+
llvm::sys::path::append(aaa, "aaa");
128+
ScopedFile a(aaa.str());
129+
130+
llvm::SmallString<128> bbb = file_root.Path;
131+
llvm::sys::path::append(bbb, "bbb");
132+
ScopedFile b(bbb.str());
133+
134+
llvm::SmallString<128> ccc = file_root.Path;
135+
llvm::sys::path::append(ccc, "ccc");
136+
ScopedFile c(ccc.str());
137+
138+
std::string root_fs = std::string(file_root.Path.str());
139+
TestingFileCollector FileCollector(root_fs, root_fs);
140+
141+
FileCollector.addDirectory(file_root.Path);
142+
143+
// Make sure the root is correct.
144+
EXPECT_EQ(FileCollector.Root, root_fs);
145+
146+
// Make sure we've seen all the added files.
147+
EXPECT_TRUE(FileCollector.hasSeen(a.Path));
148+
EXPECT_TRUE(FileCollector.hasSeen(b.Path));
149+
EXPECT_TRUE(FileCollector.hasSeen(c.Path));
150+
151+
// Make sure we've only seen the added files.
152+
llvm::SmallString<128> ddd = file_root.Path;
153+
llvm::sys::path::append(ddd, "ddd");
154+
ScopedFile d(ddd.str());
155+
EXPECT_FALSE(FileCollector.hasSeen(d.Path));
156+
}
157+
123158
TEST(FileCollectorTest, copyFiles) {
124159
ScopedDir file_root("file_root", true);
125160
ScopedFile a(file_root + "/aaa");

llvm/unittests/Support/VirtualFileSystemTest.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -2189,3 +2189,53 @@ TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) {
21892189
Status = FS->status("foo/a");
21902190
ASSERT_TRUE(Status.getError());
21912191
}
2192+
2193+
TEST_F(VFSFromYAMLTest, YAMLVFSWriterTest) {
2194+
ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
2195+
ScopedDir _a(TestDirectory + "/a");
2196+
ScopedFile _ab(TestDirectory + "/a/b", "");
2197+
ScopedDir _c(TestDirectory + "/c");
2198+
ScopedFile _cd(TestDirectory + "/c/d", "");
2199+
ScopedDir _e(TestDirectory + "/e");
2200+
ScopedDir _ef(TestDirectory + "/e/f");
2201+
ScopedDir _g(TestDirectory + "/g");
2202+
ScopedFile _h(TestDirectory + "/h", "");
2203+
2204+
vfs::YAMLVFSWriter VFSWriter;
2205+
VFSWriter.addDirectoryMapping(_a.Path, "//root/a");
2206+
VFSWriter.addFileMapping(_ab.Path, "//root/a/b");
2207+
VFSWriter.addFileMapping(_cd.Path, "//root/c/d");
2208+
VFSWriter.addDirectoryMapping(_e.Path, "//root/e");
2209+
VFSWriter.addDirectoryMapping(_ef.Path, "//root/e/f");
2210+
VFSWriter.addFileMapping(_g.Path, "//root/g");
2211+
VFSWriter.addDirectoryMapping(_h.Path, "//root/h");
2212+
2213+
std::string Buffer;
2214+
raw_string_ostream OS(Buffer);
2215+
VFSWriter.write(OS);
2216+
OS.flush();
2217+
2218+
IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem());
2219+
Lower->addDirectory("//root/");
2220+
Lower->addDirectory("//root/a");
2221+
Lower->addRegularFile("//root/a/b");
2222+
Lower->addDirectory("//root/b");
2223+
Lower->addDirectory("//root/c");
2224+
Lower->addRegularFile("//root/c/d");
2225+
Lower->addDirectory("//root/e");
2226+
Lower->addDirectory("//root/e/f");
2227+
Lower->addDirectory("//root/g");
2228+
Lower->addRegularFile("//root/h");
2229+
2230+
IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLRawString(Buffer, Lower);
2231+
ASSERT_TRUE(FS.get() != nullptr);
2232+
2233+
EXPECT_TRUE(FS->exists(_a.Path));
2234+
EXPECT_TRUE(FS->exists(_ab.Path));
2235+
EXPECT_TRUE(FS->exists(_c.Path));
2236+
EXPECT_TRUE(FS->exists(_cd.Path));
2237+
EXPECT_TRUE(FS->exists(_e.Path));
2238+
EXPECT_TRUE(FS->exists(_ef.Path));
2239+
EXPECT_TRUE(FS->exists(_g.Path));
2240+
EXPECT_TRUE(FS->exists(_h.Path));
2241+
}

0 commit comments

Comments
 (0)