[VFS] Emit an error when entry at root level uses a relative path.

Entries with only a filename prevent us from building a file system tree and
cause the assertion

> Assertion failed: (NewParentE && "Parent entry must exist"), function uniqueOverlayTree, file clang/lib/Basic/VirtualFileSystem.cpp, line 1303.

Entries with a relative path are simply not discoverable during header search.

rdar://problem/28990865

Reviewers: bruno, benlangmuir

Reviewed By: bruno

Subscribers: dexonsmith, cfe-commits

Differential Revision: https://reviews.llvm.org/D49518

llvm-svn: 339164
diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp
index a9b39b5..22fbeac 100644
--- a/clang/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp
@@ -1468,3 +1468,35 @@
   }
   EXPECT_EQ(I, E);
 }
+
+TEST_F(VFSFromYAMLTest, RelativePaths) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  // Filename at root level without a parent directory.
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'file', 'name': 'file-not-in-directory.h',\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  }\n"
+      "] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // Relative file path.
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'file', 'name': 'relative/file/path.h',\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  }\n"
+      "] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // Relative directory path.
+  FS = getFromYAMLString(
+       "{ 'roots': [\n"
+       "  { 'type': 'directory', 'name': 'relative/directory/path.h',\n"
+       "    'contents': []\n"
+       "  }\n"
+       "] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  EXPECT_EQ(3, NumDiagnostics);
+}