Author: Richard Howell Date: 2022-01-19T10:13:06-08:00 New Revision: 4f61749e16f63b0c9ebd9bdd1f8bf4f570a31692
URL: https://github.com/llvm/llvm-project/commit/4f61749e16f63b0c9ebd9bdd1f8bf4f570a31692 DIFF: https://github.com/llvm/llvm-project/commit/4f61749e16f63b0c9ebd9bdd1f8bf4f570a31692.diff LOG: [clang] support relative roots to vfs overlays This diff adds support for relative roots to VFS overlays. The directory root will be made absolute from the current working directory and will be used to determine the path style to use. This supports the use of VFS overlays with remote build systems that might use a different working directory for each compilation. Reviewed By: benlangmuir Differential Revision: https://reviews.llvm.org/D116174 Added: clang/test/VFS/Inputs/vfsoverlay-root-relative.yaml clang/test/VFS/vfsoverlay-relative-root.c Modified: llvm/include/llvm/Support/VirtualFileSystem.h llvm/lib/Support/VirtualFileSystem.cpp llvm/unittests/Support/VirtualFileSystemTest.cpp Removed: ################################################################################ diff --git a/clang/test/VFS/Inputs/vfsoverlay-root-relative.yaml b/clang/test/VFS/Inputs/vfsoverlay-root-relative.yaml new file mode 100644 index 000000000000..9ed7ec59d11e --- /dev/null +++ b/clang/test/VFS/Inputs/vfsoverlay-root-relative.yaml @@ -0,0 +1,17 @@ +{ + 'version': 0, + 'fallthrough': true, + 'overlay-relative': true, + 'roots': [ + { 'name': 'virtual', + 'type': 'directory', + 'contents': [ + { + 'external-contents': 'actual_header.h', + 'type': 'file', + 'name': 'virtual_header.h', + } + ] + } + ] +} diff --git a/clang/test/VFS/vfsoverlay-relative-root.c b/clang/test/VFS/vfsoverlay-relative-root.c new file mode 100644 index 000000000000..30a7a79eceae --- /dev/null +++ b/clang/test/VFS/vfsoverlay-relative-root.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -Werror -ivfsoverlay %S/Inputs/vfsoverlay-root-relative.yaml -I virtual -fsyntax-only %s + +#include "virtual_header.h" diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h index 78bcdbf3e932..9b5ff8f20ae2 100644 --- a/llvm/include/llvm/Support/VirtualFileSystem.h +++ b/llvm/include/llvm/Support/VirtualFileSystem.h @@ -547,6 +547,9 @@ class RedirectingFileSystemParser; /// } /// \endverbatim /// +/// The roots may be absolute or relative. If relative they will be made +/// absolute against the current working directory. +/// /// All configuration options are optional. /// 'case-sensitive': <boolean, default=(true for Posix, false for Windows)> /// 'use-external-names': <boolean, default=true> diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index bec4e8dbe06c..7b752b557f8e 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -1649,10 +1649,19 @@ class llvm::vfs::RedirectingFileSystemParser { sys::path::Style::windows_backslash)) { path_style = sys::path::Style::windows_backslash; } else { - assert(NameValueNode && "Name presence should be checked earlier"); - error(NameValueNode, + // Relative VFS root entries are made absolute to the current working + // directory, then we can determine the path style from that. + auto EC = sys::fs::make_absolute(Name); + if (EC) { + assert(NameValueNode && "Name presence should be checked earlier"); + error( + NameValueNode, "entry with relative path at the root level is not discoverable"); - return nullptr; + return nullptr; + } + path_style = sys::path::is_absolute(Name, sys::path::Style::posix) + ? sys::path::Style::posix + : sys::path::Style::windows_backslash; } } diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp index be32971908ea..caae58f74f63 100644 --- a/llvm/unittests/Support/VirtualFileSystemTest.cpp +++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -2164,6 +2164,11 @@ TEST_F(VFSFromYAMLTest, RecursiveDirectoryIterationLevel) { TEST_F(VFSFromYAMLTest, RelativePaths) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + std::error_code EC; + SmallString<128> CWD; + EC = llvm::sys::fs::current_path(CWD); + ASSERT_FALSE(EC); + // Filename at root level without a parent directory. IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString( "{ 'roots': [\n" @@ -2172,16 +2177,26 @@ TEST_F(VFSFromYAMLTest, RelativePaths) { " }\n" "] }", Lower); - EXPECT_EQ(nullptr, FS.get()); + ASSERT_TRUE(FS.get() != nullptr); + SmallString<128> ExpectedPathNotInDir("file-not-in-directory.h"); + llvm::sys::fs::make_absolute(ExpectedPathNotInDir); + checkContents(FS->dir_begin(CWD, EC), {ExpectedPathNotInDir}); // Relative file path. FS = getFromYAMLString("{ 'roots': [\n" - " { 'type': 'file', 'name': 'relative/file/path.h',\n" + " { 'type': 'file', 'name': 'relative/path.h',\n" " 'external-contents': '//root/external/file'\n" " }\n" "] }", Lower); - EXPECT_EQ(nullptr, FS.get()); + ASSERT_TRUE(FS.get() != nullptr); + SmallString<128> Parent("relative"); + llvm::sys::fs::make_absolute(Parent); + auto I = FS->dir_begin(Parent, EC); + ASSERT_FALSE(EC); + // Convert to POSIX path for comparison of windows paths + ASSERT_EQ("relative/path.h", + getPosixPath(std::string(I->path().substr(CWD.size() + 1)))); // Relative directory path. FS = getFromYAMLString( @@ -2191,9 +2206,14 @@ TEST_F(VFSFromYAMLTest, RelativePaths) { " }\n" "] }", Lower); - EXPECT_EQ(nullptr, FS.get()); + ASSERT_TRUE(FS.get() != nullptr); + SmallString<128> Root("relative/directory"); + llvm::sys::fs::make_absolute(Root); + I = FS->dir_begin(Root, EC); + ASSERT_FALSE(EC); + ASSERT_EQ("path.h", std::string(I->path().substr(Root.size() + 1))); - EXPECT_EQ(3, NumDiagnostics); + EXPECT_EQ(0, NumDiagnostics); } TEST_F(VFSFromYAMLTest, NonFallthroughDirectoryIteration) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits