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 @@ -2017,7 +2017,10 @@ if (!Entries.empty()) { const YAMLVFSEntry &Entry = Entries.front(); - startDirectory(path::parent_path(Entry.VPath)); + bool first_entry_is_directory = fs::is_directory(Entry.VPath); + StringRef Dir = + first_entry_is_directory ? Entry.VPath : path::parent_path(Entry.VPath); + startDirectory(Dir); StringRef RPath = Entry.RPath; if (UseOverlayRelative) { @@ -2027,13 +2030,19 @@ RPath = RPath.slice(OverlayDirLen, RPath.size()); } - writeEntry(path::filename(Entry.VPath), RPath); + if (!first_entry_is_directory) + writeEntry(path::filename(Entry.VPath), RPath); for (const auto &Entry : Entries.slice(1)) { - StringRef Dir = path::parent_path(Entry.VPath); - if (Dir == DirStack.back()) - OS << ",\n"; - else { + StringRef Dir = fs::is_directory(Entry.VPath) + ? Entry.VPath + : path::parent_path(Entry.VPath); + if (Dir == DirStack.back()) { + if (!first_entry_is_directory) { + OS << ",\n"; + first_entry_is_directory = false; + } + } else { while (!DirStack.empty() && !containedIn(DirStack.back(), Dir)) { OS << "\n"; endDirectory(); 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 @@ -2200,12 +2200,6 @@ ScopedDir _g(TestDirectory + "/g"); ScopedFile _h(TestDirectory + "/h", ""); - // This test exposes a bug/shortcoming in the YAMLVFSWriter. Below we call - // addFileMapping for _a and _e, which causes _ab and _ef not to exists in - // the deserialized file system, because _a and _e got emitted as regular - // files. The counter example is _c, if we only call addFileMapping for _cd, - // things work as expected. - vfs::YAMLVFSWriter VFSWriter; VFSWriter.addFileMapping(_a.Path, "//root/a"); VFSWriter.addFileMapping(_ab.Path, "//root/a/b"); @@ -2236,11 +2230,11 @@ ASSERT_TRUE(FS.get() != nullptr); EXPECT_TRUE(FS->exists(_a.Path)); - EXPECT_FALSE(FS->exists(_ab.Path)); // FIXME: See explanation above. + EXPECT_TRUE(FS->exists(_ab.Path)); EXPECT_TRUE(FS->exists(_c.Path)); EXPECT_TRUE(FS->exists(_cd.Path)); EXPECT_TRUE(FS->exists(_e.Path)); - EXPECT_FALSE(FS->exists(_ef.Path)); // FIXME: See explanation above. + EXPECT_TRUE(FS->exists(_ef.Path)); EXPECT_TRUE(FS->exists(_g.Path)); EXPECT_TRUE(FS->exists(_h.Path)); }