diff options
Diffstat (limited to 'build/build-clang/llvmorg-16-init-14750-ga903ecb4a26d.patch')
-rw-r--r-- | build/build-clang/llvmorg-16-init-14750-ga903ecb4a26d.patch | 458 |
1 files changed, 458 insertions, 0 deletions
diff --git a/build/build-clang/llvmorg-16-init-14750-ga903ecb4a26d.patch b/build/build-clang/llvmorg-16-init-14750-ga903ecb4a26d.patch new file mode 100644 index 0000000000..2144459099 --- /dev/null +++ b/build/build-clang/llvmorg-16-init-14750-ga903ecb4a26d.patch @@ -0,0 +1,458 @@ +From f8f064133b8ed9cd8cead1ee416b7c44729184ae Mon Sep 17 00:00:00 2001 +From: Haowei Wu <haowei@google.com> +Date: Fri, 4 Nov 2022 16:40:10 -0700 +Subject: [PATCH] [vfs] Allow root paths relative to the vfsoverlay YAML file + +This change adds 'root-relative' option in vfsoverlay YAML file format +so the root patchs can be relative to the YAML file directory instead of +the current working directory. + +Differential Revision: https://reviews.llvm.org/D137473 +--- + .../VFS/Inputs/root-relative-overlay.yaml | 11 +++ + clang/test/VFS/relative-path.c | 7 ++ + llvm/include/llvm/Support/VirtualFileSystem.h | 56 ++++++++++-- + llvm/lib/Support/VirtualFileSystem.cpp | 85 ++++++++++++++++--- + .../Support/VirtualFileSystemTest.cpp | 75 ++++++++++++++-- + 5 files changed, 207 insertions(+), 27 deletions(-) + create mode 100644 clang/test/VFS/Inputs/root-relative-overlay.yaml + +diff --git a/clang/test/VFS/Inputs/root-relative-overlay.yaml b/clang/test/VFS/Inputs/root-relative-overlay.yaml +new file mode 100644 +index 000000000000..931c1b4b73c5 +--- /dev/null ++++ b/clang/test/VFS/Inputs/root-relative-overlay.yaml +@@ -0,0 +1,11 @@ ++{ ++ 'version': 0, ++ 'case-sensitive': false, ++ 'overlay-relative': OVERLAY_DIR, ++ 'root-relative': 'overlay-dir', ++ 'roots': [ ++ { 'name': 'not_real.h', 'type': 'file', ++ 'external-contents': 'EXTERNAL_DIR/actual_header.h' ++ }, ++ ] ++} +diff --git a/clang/test/VFS/relative-path.c b/clang/test/VFS/relative-path.c +index ab207d096848..ba5451136a0c 100644 +--- a/clang/test/VFS/relative-path.c ++++ b/clang/test/VFS/relative-path.c +@@ -3,6 +3,13 @@ + // RUN: sed -e "s@INPUT_DIR@%{/S:regex_replacement}/Inputs@g" -e "s@OUT_DIR@%{/t:regex_replacement}@g" %S/Inputs/vfsoverlay.yaml > %t.yaml + // RUN: %clang_cc1 -Werror -I . -ivfsoverlay %t.yaml -fsyntax-only %s + ++// RUN: cp %S/Inputs/actual_header.h %t/actual_header.h ++// RUN: sed -e "s@OVERLAY_DIR@true@g" -e "s@EXTERNAL_DIR@.@g" %S/Inputs/root-relative-overlay.yaml > %t/root-relative-overlay.yaml ++// RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t/root-relative-overlay.yaml -fsyntax-only %s ++ ++// RUN: sed -e "s@OVERLAY_DIR@false@g" -e "s@EXTERNAL_DIR@%{/t:regex_replacement}@g" %S/Inputs/root-relative-overlay.yaml > %t/root-relative-overlay2.yaml ++// RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t/root-relative-overlay2.yaml -fsyntax-only %s ++ + #include "not_real.h" + + void foo(void) { +diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h +index 6844a406f38c..671b610c93e3 100644 +--- a/llvm/include/llvm/Support/VirtualFileSystem.h ++++ b/llvm/include/llvm/Support/VirtualFileSystem.h +@@ -651,17 +651,28 @@ class RedirectingFileSystemParser; + /// \endverbatim + /// + /// The roots may be absolute or relative. If relative they will be made +-/// absolute against the current working directory. ++/// absolute against either current working directory or the directory where ++/// the Overlay YAML file is located, depending on the 'root-relative' ++/// configuration. + /// + /// All configuration options are optional. + /// 'case-sensitive': <boolean, default=(true for Posix, false for Windows)> + /// 'use-external-names': <boolean, default=true> ++/// 'root-relative': <string, one of 'cwd' or 'overlay-dir', default='cwd'> + /// 'overlay-relative': <boolean, default=false> + /// 'fallthrough': <boolean, default=true, deprecated - use 'redirecting-with' + /// instead> + /// 'redirecting-with': <string, one of 'fallthrough', 'fallback', or + /// 'redirect-only', default='fallthrough'> + /// ++/// To clarify, 'root-relative' option will prepend the current working ++/// directory, or the overlay directory to the 'roots->name' field only if ++/// 'roots->name' is a relative path. On the other hand, when 'overlay-relative' ++/// is set to 'true', external paths will always be prepended with the overlay ++/// directory, even if external paths are not relative paths. The ++/// 'root-relative' option has no interaction with the 'overlay-relative' ++/// option. ++/// + /// Virtual directories that list their contents are represented as + /// \verbatim + /// { +@@ -745,6 +756,15 @@ public: + RedirectOnly + }; + ++ /// The type of relative path used by Roots. ++ enum class RootRelativeKind { ++ /// The roots are relative to the current working directory. ++ CWD, ++ /// The roots are relative to the directory where the Overlay YAML file ++ // locates. ++ OverlayDir ++ }; ++ + /// A single file or directory in the VFS. + class Entry { + EntryKind Kind; +@@ -890,6 +910,21 @@ private: + ErrorOr<Status> getExternalStatus(const Twine &CanonicalPath, + const Twine &OriginalPath) const; + ++ /// Make \a Path an absolute path. ++ /// ++ /// Makes \a Path absolute using the \a WorkingDir if it is not already. ++ /// ++ /// /absolute/path => /absolute/path ++ /// relative/../path => <WorkingDir>/relative/../path ++ /// ++ /// \param WorkingDir A path that will be used as the base Dir if \a Path ++ /// is not already absolute. ++ /// \param Path A path that is modified to be an absolute path. ++ /// \returns success if \a path has been made absolute, otherwise a ++ /// platform-specific error_code. ++ std::error_code makeAbsolute(StringRef WorkingDir, ++ SmallVectorImpl<char> &Path) const; ++ + // In a RedirectingFileSystem, keys can be specified in Posix or Windows + // style (or even a mixture of both), so this comparison helper allows + // slashes (representing a root) to match backslashes (and vice versa). Note +@@ -910,10 +945,11 @@ private: + /// The file system to use for external references. + IntrusiveRefCntPtr<FileSystem> ExternalFS; + +- /// If IsRelativeOverlay is set, this represents the directory +- /// path that should be prefixed to each 'external-contents' entry +- /// when reading from YAML files. +- std::string ExternalContentsPrefixDir; ++ /// This represents the directory path that the YAML file is located. ++ /// This will be prefixed to each 'external-contents' if IsRelativeOverlay ++ /// is set. This will also be prefixed to each 'roots->name' if RootRelative ++ /// is set to RootRelativeKind::OverlayDir and the path is relative. ++ std::string OverlayFileDir; + + /// @name Configuration + /// @{ +@@ -923,7 +959,7 @@ private: + /// Currently, case-insensitive matching only works correctly with ASCII. + bool CaseSensitive = is_style_posix(sys::path::Style::native); + +- /// IsRelativeOverlay marks whether a ExternalContentsPrefixDir path must ++ /// IsRelativeOverlay marks whether a OverlayFileDir path must + /// be prefixed in every 'external-contents' when reading from YAML files. + bool IsRelativeOverlay = false; + +@@ -934,6 +970,10 @@ private: + /// Determines the lookups to perform, as well as their order. See + /// \c RedirectKind for details. + RedirectKind Redirection = RedirectKind::Fallthrough; ++ ++ /// Determine the prefix directory if the roots are relative paths. See ++ /// \c RootRelativeKind for details. ++ RootRelativeKind RootRelative = RootRelativeKind::CWD; + /// @} + + RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS); +@@ -984,9 +1024,9 @@ public: + + directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; + +- void setExternalContentsPrefixDir(StringRef PrefixDir); ++ void setOverlayFileDir(StringRef PrefixDir); + +- StringRef getExternalContentsPrefixDir() const; ++ StringRef getOverlayFileDir() const; + + /// Sets the redirection kind to \c Fallthrough if true or \c RedirectOnly + /// otherwise. Will removed in the future, use \c setRedirection instead. +diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp +index 97d63fff1069..656d565fb692 100644 +--- a/llvm/lib/Support/VirtualFileSystem.cpp ++++ b/llvm/lib/Support/VirtualFileSystem.cpp +@@ -1350,32 +1350,51 @@ std::error_code RedirectingFileSystem::makeAbsolute(SmallVectorImpl<char> &Path) + if (llvm::sys::path::is_absolute(Path, llvm::sys::path::Style::posix) || + llvm::sys::path::is_absolute(Path, + llvm::sys::path::Style::windows_backslash)) ++ // This covers windows absolute path with forward slash as well, as the ++ // forward slashes are treated as path seperation in llvm::path ++ // regardless of what path::Style is used. + return {}; + + auto WorkingDir = getCurrentWorkingDirectory(); + if (!WorkingDir) + return WorkingDir.getError(); + ++ return makeAbsolute(WorkingDir.get(), Path); ++} ++ ++std::error_code ++RedirectingFileSystem::makeAbsolute(StringRef WorkingDir, ++ SmallVectorImpl<char> &Path) const { + // We can't use sys::fs::make_absolute because that assumes the path style + // is native and there is no way to override that. Since we know WorkingDir + // is absolute, we can use it to determine which style we actually have and + // append Path ourselves. ++ if (!WorkingDir.empty() && ++ !sys::path::is_absolute(WorkingDir, sys::path::Style::posix) && ++ !sys::path::is_absolute(WorkingDir, ++ sys::path::Style::windows_backslash)) { ++ return std::error_code(); ++ } + sys::path::Style style = sys::path::Style::windows_backslash; +- if (sys::path::is_absolute(WorkingDir.get(), sys::path::Style::posix)) { ++ if (sys::path::is_absolute(WorkingDir, sys::path::Style::posix)) { + style = sys::path::Style::posix; + } else { + // Distinguish between windows_backslash and windows_slash; getExistingStyle + // returns posix for a path with windows_slash. +- if (getExistingStyle(WorkingDir.get()) != +- sys::path::Style::windows_backslash) ++ if (getExistingStyle(WorkingDir) != sys::path::Style::windows_backslash) + style = sys::path::Style::windows_slash; + } + +- std::string Result = WorkingDir.get(); ++ std::string Result = std::string(WorkingDir); + StringRef Dir(Result); + if (!Dir.endswith(sys::path::get_separator(style))) { + Result += sys::path::get_separator(style); + } ++ // backslashes '\' are legit path charactors under POSIX. Windows APIs ++ // like CreateFile accepts forward slashes '/' as path ++ // separator (even when mixed with backslashes). Therefore, ++ // `Path` should be directly appended to `WorkingDir` without converting ++ // path separator. + Result.append(Path.data(), Path.size()); + Path.assign(Result.begin(), Result.end()); + +@@ -1482,12 +1501,12 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, + return Combined; + } + +-void RedirectingFileSystem::setExternalContentsPrefixDir(StringRef PrefixDir) { +- ExternalContentsPrefixDir = PrefixDir.str(); ++void RedirectingFileSystem::setOverlayFileDir(StringRef Dir) { ++ OverlayFileDir = Dir.str(); + } + +-StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const { +- return ExternalContentsPrefixDir; ++StringRef RedirectingFileSystem::getOverlayFileDir() const { ++ return OverlayFileDir; + } + + void RedirectingFileSystem::setFallthrough(bool Fallthrough) { +@@ -1621,6 +1640,20 @@ class llvm::vfs::RedirectingFileSystemParser { + return None; + } + ++ Optional<RedirectingFileSystem::RootRelativeKind> ++ parseRootRelativeKind(yaml::Node *N) { ++ SmallString<12> Storage; ++ StringRef Value; ++ if (!parseScalarString(N, Value, Storage)) ++ return None; ++ if (Value.equals_insensitive("cwd")) { ++ return RedirectingFileSystem::RootRelativeKind::CWD; ++ } else if (Value.equals_insensitive("overlay-dir")) { ++ return RedirectingFileSystem::RootRelativeKind::OverlayDir; ++ } ++ return None; ++ } ++ + struct KeyStatus { + bool Required; + bool Seen = false; +@@ -1828,7 +1861,7 @@ private: + + SmallString<256> FullPath; + if (FS->IsRelativeOverlay) { +- FullPath = FS->getExternalContentsPrefixDir(); ++ FullPath = FS->getOverlayFileDir(); + assert(!FullPath.empty() && + "External contents prefix directory must exist"); + llvm::sys::path::append(FullPath, Value); +@@ -1885,9 +1918,19 @@ private: + sys::path::Style::windows_backslash)) { + path_style = sys::path::Style::windows_backslash; + } else { +- // 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); ++ // Relative VFS root entries are made absolute to either the overlay ++ // directory, or the current working directory, then we can determine ++ // the path style from that. ++ std::error_code EC; ++ if (FS->RootRelative == ++ RedirectingFileSystem::RootRelativeKind::OverlayDir) { ++ StringRef FullPath = FS->getOverlayFileDir(); ++ assert(!FullPath.empty() && "Overlay file directory must exist"); ++ EC = FS->makeAbsolute(FullPath, Name); ++ Name = canonicalize(Name); ++ } else { ++ EC = sys::fs::make_absolute(Name); ++ } + if (EC) { + assert(NameValueNode && "Name presence should be checked earlier"); + error( +@@ -1899,6 +1942,12 @@ private: + ? sys::path::Style::posix + : sys::path::Style::windows_backslash; + } ++ // is::path::is_absolute(Name, sys::path::Style::windows_backslash) will ++ // return true even if `Name` is using forward slashes. Distinguish ++ // between windows_backslash and windows_slash. ++ if (path_style == sys::path::Style::windows_backslash && ++ getExistingStyle(Name) != sys::path::Style::windows_backslash) ++ path_style = sys::path::Style::windows_slash; + } + + // Remove trailing slash(es), being careful not to remove the root path +@@ -1962,6 +2011,7 @@ public: + KeyStatusPair("version", true), + KeyStatusPair("case-sensitive", false), + KeyStatusPair("use-external-names", false), ++ KeyStatusPair("root-relative", false), + KeyStatusPair("overlay-relative", false), + KeyStatusPair("fallthrough", false), + KeyStatusPair("redirecting-with", false), +@@ -2051,6 +2101,13 @@ public: + error(I.getValue(), "expected valid redirect kind"); + return false; + } ++ } else if (Key == "root-relative") { ++ if (auto Kind = parseRootRelativeKind(I.getValue())) { ++ FS->RootRelative = *Kind; ++ } else { ++ error(I.getValue(), "expected valid root-relative kind"); ++ return false; ++ } + } else { + llvm_unreachable("key missing from Keys"); + } +@@ -2100,13 +2157,13 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, + // Example: + // -ivfsoverlay dummy.cache/vfs/vfs.yaml + // yields: +- // FS->ExternalContentsPrefixDir => /<absolute_path_to>/dummy.cache/vfs ++ // FS->OverlayFileDir => /<absolute_path_to>/dummy.cache/vfs + // + SmallString<256> OverlayAbsDir = sys::path::parent_path(YAMLFilePath); + std::error_code EC = llvm::sys::fs::make_absolute(OverlayAbsDir); + assert(!EC && "Overlay dir final path must be absolute"); + (void)EC; +- FS->setExternalContentsPrefixDir(OverlayAbsDir); ++ FS->setOverlayFileDir(OverlayAbsDir); + } + + if (!P.parse(Root, FS.get())) +diff --git a/llvm/unittests/Support/VirtualFileSystemTest.cpp b/llvm/unittests/Support/VirtualFileSystemTest.cpp +index 1e300eec711d..6cefd1d02ba3 100644 +--- a/llvm/unittests/Support/VirtualFileSystemTest.cpp ++++ b/llvm/unittests/Support/VirtualFileSystemTest.cpp +@@ -1452,18 +1452,20 @@ public: + + std::unique_ptr<vfs::FileSystem> + getFromYAMLRawString(StringRef Content, +- IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) { ++ IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS, ++ StringRef YAMLFilePath = "") { + std::unique_ptr<MemoryBuffer> Buffer = MemoryBuffer::getMemBuffer(Content); +- return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, "", this, +- ExternalFS); ++ return getVFSFromYAML(std::move(Buffer), CountingDiagHandler, YAMLFilePath, ++ this, ExternalFS); + } + + std::unique_ptr<vfs::FileSystem> getFromYAMLString( + StringRef Content, +- IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) { ++ IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem(), ++ StringRef YAMLFilePath = "") { + std::string VersionPlusContent("{\n 'version':0,\n"); + VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos); +- return getFromYAMLRawString(VersionPlusContent, ExternalFS); ++ return getFromYAMLRawString(VersionPlusContent, ExternalFS, YAMLFilePath); + } + + // This is intended as a "XFAIL" for windows hosts. +@@ -1849,6 +1851,69 @@ TEST_F(VFSFromYAMLTest, ReturnsExternalPathVFSHit) { + EXPECT_EQ(0, NumDiagnostics); + } + ++TEST_F(VFSFromYAMLTest, RootRelativeTest) { ++ IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); ++ Lower->addDirectory("//root/foo/bar"); ++ Lower->addRegularFile("//root/foo/bar/a"); ++ IntrusiveRefCntPtr<vfs::FileSystem> FS = ++ getFromYAMLString("{\n" ++ " 'case-sensitive': false,\n" ++ " 'root-relative': 'overlay-dir',\n" ++ " 'roots': [\n" ++ " { 'name': 'b', 'type': 'file',\n" ++ " 'external-contents': '//root/foo/bar/a'\n" ++ " }\n" ++ " ]\n" ++ "}", ++ Lower, "//root/foo/bar/overlay"); ++ ++ ASSERT_NE(FS.get(), nullptr); ++ ErrorOr<vfs::Status> S = FS->status("//root/foo/bar/b"); ++ ASSERT_FALSE(S.getError()); ++ EXPECT_EQ("//root/foo/bar/a", S->getName()); ++ ++ // On Windows, with overlay-relative set to true, the relative ++ // path in external-contents field will be prepend by OverlayDir ++ // with native path separator, regardless of the actual path separator ++ // used in YAMLFilePath field. ++#ifndef _WIN32 ++ FS = getFromYAMLString("{\n" ++ " 'case-sensitive': false,\n" ++ " 'overlay-relative': true,\n" ++ " 'root-relative': 'overlay-dir',\n" ++ " 'roots': [\n" ++ " { 'name': 'b', 'type': 'file',\n" ++ " 'external-contents': 'a'\n" ++ " }\n" ++ " ]\n" ++ "}", ++ Lower, "//root/foo/bar/overlay"); ++ ASSERT_NE(FS.get(), nullptr); ++ S = FS->status("//root/foo/bar/b"); ++ ASSERT_FALSE(S.getError()); ++ EXPECT_EQ("//root/foo/bar/a", S->getName()); ++#else ++ IntrusiveRefCntPtr<DummyFileSystem> LowerWindows(new DummyFileSystem()); ++ LowerWindows->addDirectory("\\\\root\\foo\\bar"); ++ LowerWindows->addRegularFile("\\\\root\\foo\\bar\\a"); ++ FS = getFromYAMLString("{\n" ++ " 'case-sensitive': false,\n" ++ " 'overlay-relative': true,\n" ++ " 'root-relative': 'overlay-dir',\n" ++ " 'roots': [\n" ++ " { 'name': 'b', 'type': 'file',\n" ++ " 'external-contents': 'a'\n" ++ " }\n" ++ " ]\n" ++ "}", ++ LowerWindows, "\\\\root\\foo\\bar\\overlay"); ++ ASSERT_NE(FS.get(), nullptr); ++ S = FS->status("\\\\root\\foo\\bar\\b"); ++ ASSERT_FALSE(S.getError()); ++ EXPECT_EQ("\\\\root\\foo\\bar\\a", S->getName()); ++#endif ++} ++ + TEST_F(VFSFromYAMLTest, ReturnsInternalPathVFSHit) { + IntrusiveRefCntPtr<vfs::InMemoryFileSystem> BaseFS( + new vfs::InMemoryFileSystem); +-- +2.38.1.1.g6d9df9d320 + |