From 32b2897af6101e843f8fa90750e0de2a8a84d1cd Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Sat, 14 May 2016 00:00:18 +0000 Subject: [PATCH] [VFS] Add level() method to vfs::recursive_directory_iterator Unlike sys::fs::recursive_directory_iterator, vfs::recursive_directory_iterator does not implement the level() method, which tells how deep in the directory tree the current iterator is. This is needed in the vfs::recursive_directory_iterator so that future improvements to the crash reproducer will be able to properly access header for umbrellas when looking into the VFS. rdar://problem/25880368 llvm-svn: 269520 --- clang/include/clang/Basic/VirtualFileSystem.h | 5 +++ .../unittests/Basic/VirtualFileSystemTest.cpp | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/clang/include/clang/Basic/VirtualFileSystem.h b/clang/include/clang/Basic/VirtualFileSystem.h index 9b95158987e0..6c7127f28020 100644 --- a/clang/include/clang/Basic/VirtualFileSystem.h +++ b/clang/include/clang/Basic/VirtualFileSystem.h @@ -176,6 +176,11 @@ public: bool operator!=(const recursive_directory_iterator &RHS) const { return !(*this == RHS); } + /// \brief Gets the current level. Starting path is at level 0. + int level() const { + assert(State->size() && "Cannot get level without any iteration state"); + return State->size()-1; + } }; /// \brief The virtual file system interface. diff --git a/clang/unittests/Basic/VirtualFileSystemTest.cpp b/clang/unittests/Basic/VirtualFileSystemTest.cpp index a33f2b1f7c2d..3b26488a7fd9 100644 --- a/clang/unittests/Basic/VirtualFileSystemTest.cpp +++ b/clang/unittests/Basic/VirtualFileSystemTest.cpp @@ -1122,3 +1122,45 @@ TEST_F(VFSFromYAMLTest, DirectoryIterationSameDirMultipleEntries) { checkContents(O->dir_begin("//root/baz/", EC), {"//root/baz/x", "//root/baz/y"}); } + +TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { + + IntrusiveRefCntPtr Lower(new DummyFileSystem()); + Lower->addDirectory("//root/a"); + Lower->addDirectory("//root/a/b"); + Lower->addDirectory("//root/a/b/c"); + Lower->addRegularFile("//root/a/b/c/file"); + IntrusiveRefCntPtr FS = getFromYAMLString( + "{ 'use-external-names': false,\n" + " 'roots': [\n" + "{\n" + " 'type': 'directory',\n" + " 'name': '//root/a/b/c/',\n" + " 'contents': [ {\n" + " 'type': 'file',\n" + " 'name': 'file',\n" + " 'external-contents': '//root/a/b/c/file'\n" + " }\n" + " ]\n" + "},\n" + "]\n" + "}", + Lower); + ASSERT_TRUE(FS.get() != nullptr); + + IntrusiveRefCntPtr O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(FS); + + std::error_code EC; + + // Test recursive_directory_iterator level() + vfs::recursive_directory_iterator I = vfs::recursive_directory_iterator( + *O, "//root", EC), E; + ASSERT_FALSE(EC); + for (int l = 0; I != E; I.increment(EC), ++l) { + ASSERT_FALSE(EC); + EXPECT_EQ(I.level(), l); + } + EXPECT_EQ(I, E); +}