From ecf7d15d49de4f6810c3215c3df520983746a96c Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 10 May 2016 18:43:00 +0000 Subject: [VFS] Reconstruct the VFS overlay tree for more accurate lookup The way we currently build the internal VFS overlay representation leads to inefficient path search and might yield wrong answers when asked for recursive or regular directory iteration. Currently, when reading an YAML file, each YAML root entry is placed inside a new root in the filesystem overlay. In the crash reproducer, a simple "@import Foundation" currently maps to 43 roots, and when looking up paths, we traverse a directory tree for each of these different roots, until we find a match (or don't). This has two consequences: - It's slow. - Directory iteration gives incomplete results since it only return results within one root - since contents of the same directory can be declared inside different roots, the result isn't accurate. This is in part fault of the way we currently write out the YAML file when emitting the crash reproducer - we could generate only one root and that would make it fast and correct again. However, we should not rely on how the client writes the YAML, but provide a good internal representation regardless. This patch builds a proper virtual directory tree out of the YAML representation, allowing faster search and proper iteration. Besides the crash reproducer, this potentially benefits other VFS clients. llvm-svn: 269100 --- clang/unittests/Basic/VirtualFileSystemTest.cpp | 31 ++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'clang/unittests/Basic/VirtualFileSystemTest.cpp') diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp index d2f4a7d..e56ec0a 100644 --- a/clang/unittests/Basic/VirtualFileSystemTest.cpp +++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp @@ -1022,9 +1022,14 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) { Lower->addDirectory("//root/"); Lower->addDirectory("//root/foo"); Lower->addDirectory("//root/foo/bar"); + Lower->addDirectory("//root/zab"); + Lower->addDirectory("//root/baz"); Lower->addRegularFile("//root/foo/bar/a"); Lower->addRegularFile("//root/foo/bar/b"); Lower->addRegularFile("//root/file3"); + Lower->addRegularFile("//root/zab/a"); + Lower->addRegularFile("//root/zab/b"); + Lower->addRegularFile("//root/baz/c"); IntrusiveRefCntPtr FS = getFromYAMLString("{ 'use-external-names': false,\n" " 'roots': [\n" @@ -1042,6 +1047,26 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) { " 'external-contents': '//root/foo/bar/b'\n" " }\n" " ]\n" + "},\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '//root/baz',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'x',\n" + " 'external-contents': '//root/zab/a'\n" + " }\n" + " ]\n" + "},\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '//root/baz',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'y',\n" + " 'external-contents': '//root/zab/b'\n" + " }\n" + " ]\n" "}\n" "]\n" "}", @@ -1054,8 +1079,12 @@ TEST_F(VFSFromYAMLTest, DirectoryIteration) { std::error_code EC; checkContents(O->dir_begin("//root/", EC), - {"//root/file1", "//root/file2", "//root/file3", "//root/foo"}); + {"//root/file1", "//root/file2", "//root/baz", "//root/file3", + "//root/foo", "//root/zab"}); checkContents(O->dir_begin("//root/foo/bar", EC), {"//root/foo/bar/a", "//root/foo/bar/b"}); + + checkContents(O->dir_begin("//root/baz", EC), + {"//root/baz/x", "//root/baz/y", "//root/baz/c"}); } -- cgit v1.1