diff --git a/Dockerfile b/Dockerfile index bea40d6..4c39a2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,6 @@ COPY wrappers/uasm-wrapper.sh $TOOLCHAIN_PREFIX/bin # Build everything that uses the llvm monorepo. We need to build the mingw runtime before the compiler-rt/libunwind/libcxxabi/libcxx runtimes. COPY build-llvm.sh strip-llvm.sh install-wrappers.sh build-mingw-w64.sh build-mingw-w64-tools.sh build-compiler-rt.sh build-mingw-w64-libraries.sh build-libcxx.sh build-openmp.sh ./ COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ -COPY patches/llvm-project/*.patch ./patches/llvm-project/ RUN ./build-llvm.sh $TOOLCHAIN_PREFIX && \ ./strip-llvm.sh $TOOLCHAIN_PREFIX && \ ./install-wrappers.sh $TOOLCHAIN_PREFIX && \ diff --git a/Dockerfile.dev b/Dockerfile.dev index a635706..fe384f4 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -44,7 +44,6 @@ ARG FULL_LLVM # Build LLVM COPY build-llvm.sh ./ -COPY patches/llvm-project/*.patch ./patches/llvm-project/ RUN ./build-llvm.sh $TOOLCHAIN_PREFIX # Strip the LLVM install output immediately. (This doesn't reduce the diff --git a/build-llvm.sh b/build-llvm.sh index 6a8ee24..3af5945 100755 --- a/build-llvm.sh +++ b/build-llvm.sh @@ -16,7 +16,7 @@ set -e -: ${LLVM_VERSION:=llvmorg-12.0.0} +: ${LLVM_VERSION:=llvmorg-13.0.0-rc1} ASSERTS=OFF unset HOST BUILDDIR="build" @@ -89,11 +89,6 @@ if [ -n "$SYNC" ] || [ -n "$CHECKOUT" ]; then git fetch --depth 1 origin "$LLVM_VERSION" git checkout FETCH_HEAD fi - if [ "$LLVM_VERSION" = "llvmorg-12.0.0" ]; then - # The bundled patches for std::filesystem apply on the 12.0.0 release, - # but don't try to apply them if a different version was requested. - git am -3 --keep-non-patch ../patches/llvm-project/*.patch - fi cd .. fi diff --git a/patches/llvm-project/0001-libcxx-Implement-the-stat-function-family-on-top-of-.patch b/patches/llvm-project/0001-libcxx-Implement-the-stat-function-family-on-top-of-.patch deleted file mode 100644 index d23165f..0000000 --- a/patches/llvm-project/0001-libcxx-Implement-the-stat-function-family-on-top-of-.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 4655075efa11ee17c28493d13760d51e360f7ddd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 16:59:07 +0200 -Subject: [PATCH 01/25] [libcxx] Implement the stat function family on top of - native windows APIs - -While the windows CRTs (the modern UCRT, and the legacy msvcrt.dll -that mingw still often defaults to) do provide stat functions, they're -a bit lacking - they only provide second precision on the modification -time, lack support for symlinks and a few other details. - -Instead reimplement them using a couple windows native functions, -getting exactly the info we need. (Technically, the implementation -within the CRT calls these functions anyway.) - -If we only need a few fields, we could also do with fewer calls, as a -later optimization. - -Differential Revision: https://reviews.llvm.org/D91141 - -(cherry picked from commit 2ff8662b5d16129ec6d1ee60dcec4f6ff8f717e2) ---- - libcxx/src/CMakeLists.txt | 1 + - libcxx/src/filesystem/filesystem_common.h | 32 ++++ - libcxx/src/filesystem/operations.cpp | 10 +- - libcxx/src/filesystem/posix_compat.h | 187 ++++++++++++++++++++++ - 4 files changed, 226 insertions(+), 4 deletions(-) - create mode 100644 libcxx/src/filesystem/posix_compat.h - -diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt -index 9965104cb5b2..0d95e766100d 100644 ---- a/libcxx/src/CMakeLists.txt -+++ b/libcxx/src/CMakeLists.txt -@@ -91,6 +91,7 @@ if (LIBCXX_ENABLE_FILESYSTEM) - filesystem/filesystem_common.h - filesystem/operations.cpp - filesystem/directory_iterator.cpp -+ filesystem/posix_compat.h - ) - # Filesystem uses __int128_t, which requires a definition of __muloi4 when - # compiled with UBSAN. This definition is not provided by libgcc_s, but is -diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h -index e0fdbccf96b1..8204e9a2e5f8 100644 ---- a/libcxx/src/filesystem/filesystem_common.h -+++ b/libcxx/src/filesystem/filesystem_common.h -@@ -224,9 +224,41 @@ private: - using chrono::duration; - using chrono::duration_cast; - -+#if defined(_LIBCPP_WIN32API) -+// Various C runtime versions (UCRT, or the legacy msvcrt.dll used by -+// some mingw toolchains) provide different stat function implementations, -+// with a number of limitations with respect to what we want from the -+// stat function. Instead provide our own (in the anonymous detail namespace -+// in posix_compat.h) which does exactly what we want, along with our own -+// stat structure and flag macros. -+ -+struct TimeSpec { -+ int64_t tv_sec; -+ int64_t tv_nsec; -+}; -+struct StatT { -+ unsigned st_mode; -+ TimeSpec st_atim; -+ TimeSpec st_mtim; -+ uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber -+ struct FileIdStruct { -+ unsigned char id[16]; // FILE_ID_INFO::FileId -+ bool operator==(const FileIdStruct &other) const { -+ for (int i = 0; i < 16; i++) -+ if (id[i] != other.id[i]) -+ return false; -+ return true; -+ } -+ } st_ino; -+ uint32_t st_nlink; -+ uintmax_t st_size; -+}; -+ -+#else - using TimeSpec = struct timespec; - using TimeVal = struct timeval; - using StatT = struct stat; -+#endif - - template ::value> -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 50a895dc2fae..548a0273ce71 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -17,6 +17,8 @@ - - #include "filesystem_common.h" - -+#include "posix_compat.h" -+ - #if defined(_LIBCPP_WIN32API) - # define WIN32_LEAN_AND_MEAN - # define NOMINMAX -@@ -495,7 +497,7 @@ file_status create_file_status(error_code& m_ec, path const& p, - - file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { - error_code m_ec; -- if (::stat(p.c_str(), &path_stat) == -1) -+ if (detail::stat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); - return create_file_status(m_ec, p, path_stat, ec); - } -@@ -507,7 +509,7 @@ file_status posix_stat(path const& p, error_code* ec) { - - file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { - error_code m_ec; -- if (::lstat(p.c_str(), &path_stat) == -1) -+ if (detail::lstat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); - return create_file_status(m_ec, p, path_stat, ec); - } -@@ -545,7 +547,7 @@ file_status FileDescriptor::refresh_status(error_code& ec) { - m_status = file_status{}; - m_stat = {}; - error_code m_ec; -- if (::fstat(fd, &m_stat) == -1) -+ if (detail::fstat(fd, &m_stat) == -1) - m_ec = capture_errno(); - m_status = create_file_status(m_ec, name, m_stat, &ec); - return m_status; -@@ -1197,7 +1199,7 @@ path __read_symlink(const path& p, error_code* ec) { - auto buff = std::unique_ptr(stack_buff); - #else - StatT sb; -- if (::lstat(p.c_str(), &sb) == -1) { -+ if (detail::lstat(p.c_str(), &sb) == -1) { - return err.report(capture_errno()); - } - const size_t size = sb.st_size + 1; -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -new file mode 100644 -index 000000000000..3eec4634e929 ---- /dev/null -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -0,0 +1,187 @@ -+//===----------------------------------------------------------------------===// -+// -+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -+// See https://llvm.org/LICENSE.txt for license information. -+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -+// -+//===----------------------------------------------------------------------===// -+ -+// -+// POSIX-like portability helper functions. -+// -+// These generally behave like the proper posix functions, with these -+// exceptions: -+// On Windows, they take paths in wchar_t* form, instead of char* form. -+// -+// These are provided within an anonymous namespace within the detail -+// namespace - callers need to include this header and call them as -+// detail::function(), regardless of platform. -+// -+ -+#ifndef POSIX_COMPAT_H -+#define POSIX_COMPAT_H -+ -+#include "filesystem" -+ -+#include "filesystem_common.h" -+ -+#if defined(_LIBCPP_WIN32API) -+# define WIN32_LEAN_AND_MEAN -+# define NOMINMAX -+# include -+# include -+#else -+# include -+# include -+# include -+#endif -+#include -+ -+_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -+ -+namespace detail { -+namespace { -+ -+#if defined(_LIBCPP_WIN32API) -+ -+// Various C runtime header sets provide more or less of these. As we -+// provide our own implementation, undef all potential defines from the -+// C runtime headers and provide a complete set of macros of our own. -+ -+#undef _S_IFMT -+#undef _S_IFDIR -+#undef _S_IFCHR -+#undef _S_IFIFO -+#undef _S_IFREG -+#undef _S_IFBLK -+#undef _S_IFLNK -+#undef _S_IFSOCK -+ -+#define _S_IFMT 0xF000 -+#define _S_IFDIR 0x4000 -+#define _S_IFCHR 0x2000 -+#define _S_IFIFO 0x1000 -+#define _S_IFREG 0x8000 -+#define _S_IFBLK 0x6000 -+#define _S_IFLNK 0xA000 -+#define _S_IFSOCK 0xC000 -+ -+#undef S_ISDIR -+#undef S_ISFIFO -+#undef S_ISCHR -+#undef S_ISREG -+#undef S_ISLNK -+#undef S_ISBLK -+#undef S_ISSOCK -+ -+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) -+#define S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR) -+#define S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) -+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) -+#define S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK) -+#define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) -+#define S_ISSOCK(m) (((m) & _S_IFMT) == _S_IFSOCK) -+ -+ -+// There were 369 years and 89 leap days from the Windows epoch -+// (1601) to the Unix epoch (1970). -+#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60)) -+ -+TimeSpec filetime_to_timespec(LARGE_INTEGER li) { -+ TimeSpec ret; -+ ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS; -+ ret.tv_nsec = (li.QuadPart % 10000000) * 100; -+ return ret; -+} -+ -+int set_errno(int e = GetLastError()) { -+ errno = static_cast(__win_err_to_errc(e)); -+ return -1; -+} -+ -+class WinHandle { -+public: -+ WinHandle(const wchar_t *p, DWORD access, DWORD flags) { -+ h = CreateFileW( -+ p, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, -+ nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | flags, nullptr); -+ } -+ ~WinHandle() { -+ if (h != INVALID_HANDLE_VALUE) -+ CloseHandle(h); -+ } -+ operator HANDLE() const { return h; } -+ operator bool() const { return h != INVALID_HANDLE_VALUE; } -+ -+private: -+ HANDLE h; -+}; -+ -+int stat_handle(HANDLE h, StatT *buf) { -+ FILE_BASIC_INFO basic; -+ if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) -+ return set_errno(); -+ memset(buf, 0, sizeof(*buf)); -+ buf->st_mtim = filetime_to_timespec(basic.LastWriteTime); -+ buf->st_atim = filetime_to_timespec(basic.LastAccessTime); -+ buf->st_mode = 0555; // Read-only -+ if (!(basic.FileAttributes & FILE_ATTRIBUTE_READONLY)) -+ buf->st_mode |= 0222; // Write -+ if (basic.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { -+ buf->st_mode |= _S_IFDIR; -+ } else { -+ buf->st_mode |= _S_IFREG; -+ } -+ if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { -+ FILE_ATTRIBUTE_TAG_INFO tag; -+ if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag, -+ sizeof(tag))) -+ return set_errno(); -+ if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK) -+ buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK; -+ } -+ FILE_STANDARD_INFO standard; -+ if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard, -+ sizeof(standard))) -+ return set_errno(); -+ buf->st_nlink = standard.NumberOfLinks; -+ buf->st_size = standard.EndOfFile.QuadPart; -+ BY_HANDLE_FILE_INFORMATION info; -+ if (!GetFileInformationByHandle(h, &info)) -+ return set_errno(); -+ buf->st_dev = info.dwVolumeSerialNumber; -+ memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4); -+ memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4); -+ return 0; -+} -+ -+int stat_file(const wchar_t *path, StatT *buf, DWORD flags) { -+ WinHandle h(path, FILE_READ_ATTRIBUTES, flags); -+ if (!h) -+ return set_errno(); -+ int ret = stat_handle(h, buf); -+ return ret; -+} -+ -+int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); } -+ -+int lstat(const wchar_t *path, StatT *buf) { -+ return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT); -+} -+ -+int fstat(int fd, StatT *buf) { -+ HANDLE h = reinterpret_cast(_get_osfhandle(fd)); -+ return stat_handle(h, buf); -+} -+#else -+using ::fstat; -+using ::lstat; -+using ::stat; -+#endif -+ -+} // namespace -+} // end namespace detail -+ -+_LIBCPP_END_NAMESPACE_FILESYSTEM -+ -+#endif // POSIX_COMPAT_H --- -2.25.1 - diff --git a/patches/llvm-project/0002-libcxx-Implement-_FilesystemClock-now-and-__last_wri.patch b/patches/llvm-project/0002-libcxx-Implement-_FilesystemClock-now-and-__last_wri.patch deleted file mode 100644 index 9c55f23..0000000 --- a/patches/llvm-project/0002-libcxx-Implement-_FilesystemClock-now-and-__last_wri.patch +++ /dev/null @@ -1,133 +0,0 @@ -From ab432bcd28596265e97eb062a19cbbbdc3d426f5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 22:56:03 +0200 -Subject: [PATCH 02/25] [libcxx] Implement _FilesystemClock::now() and - __last_write_time for windows - -Differential Revision: https://reviews.llvm.org/D91142 - -(cherry picked from commit 592d62352933d34af62334d172c6fc665933e0de) ---- - libcxx/src/filesystem/filesystem_common.h | 6 ++++++ - libcxx/src/filesystem/operations.cpp | 23 +++++++++++++++++++++-- - libcxx/src/filesystem/posix_compat.h | 17 +++++++++++++++++ - 3 files changed, 44 insertions(+), 2 deletions(-) - -diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h -index 8204e9a2e5f8..a4505171c3eb 100644 ---- a/libcxx/src/filesystem/filesystem_common.h -+++ b/libcxx/src/filesystem/filesystem_common.h -@@ -437,7 +437,11 @@ public: - } - }; - -+#if defined(_LIBCPP_WIN32API) -+using fs_time = time_util; -+#else - using fs_time = time_util; -+#endif - - #if defined(__APPLE__) - inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } -@@ -456,6 +460,7 @@ inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } - inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } - #endif - -+#if !defined(_LIBCPP_WIN32API) - inline TimeVal make_timeval(TimeSpec const& ts) { - using namespace chrono; - auto Convert = [](long nsec) { -@@ -498,6 +503,7 @@ bool set_file_times(const path& p, std::array const& TS, - return posix_utimensat(p, TS, ec); - #endif - } -+#endif /* !_LIBCPP_WIN32API */ - - } // namespace - } // end namespace detail -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 548a0273ce71..40a863db69a1 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -42,7 +42,7 @@ - # define _LIBCPP_FILESYSTEM_USE_FSTREAM - #endif - --#if !defined(CLOCK_REALTIME) -+#if !defined(CLOCK_REALTIME) && !defined(_LIBCPP_WIN32API) - # include // for gettimeofday and timeval - #endif - -@@ -567,7 +567,14 @@ const bool _FilesystemClock::is_steady; - - _FilesystemClock::time_point _FilesystemClock::now() noexcept { - typedef chrono::duration __secs; --#if defined(CLOCK_REALTIME) -+#if defined(_LIBCPP_WIN32API) -+ typedef chrono::duration __nsecs; -+ FILETIME time; -+ GetSystemTimeAsFileTime(&time); -+ TimeSpec tp = detail::filetime_to_timespec(time); -+ return time_point(__secs(tp.tv_sec) + -+ chrono::duration_cast(__nsecs(tp.tv_nsec))); -+#elif defined(CLOCK_REALTIME) - typedef chrono::duration __nsecs; - struct timespec tp; - if (0 != clock_gettime(CLOCK_REALTIME, &tp)) -@@ -1121,6 +1128,17 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) { - using detail::fs_time; - ErrorHandler err("last_write_time", ec, &p); - -+#if defined(_LIBCPP_WIN32API) -+ TimeSpec ts; -+ if (!fs_time::convert_to_timespec(ts, new_time)) -+ return err.report(errc::value_too_large); -+ detail::WinHandle h(p.c_str(), FILE_WRITE_ATTRIBUTES, 0); -+ if (!h) -+ return err.report(detail::make_windows_error(GetLastError())); -+ FILETIME last_write = timespec_to_filetime(ts); -+ if (!SetFileTime(h, nullptr, nullptr, &last_write)) -+ return err.report(detail::make_windows_error(GetLastError())); -+#else - error_code m_ec; - array tbuf; - #if !defined(_LIBCPP_USE_UTIMENSAT) -@@ -1142,6 +1160,7 @@ void __last_write_time(const path& p, file_time_type new_time, error_code* ec) { - detail::set_file_times(p, tbuf, m_ec); - if (m_ec) - return err.report(m_ec); -+#endif - } - - void __permissions(const path& p, perms prms, perm_options opts, -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 3eec4634e929..7caf9d28b49d 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -94,6 +94,23 @@ TimeSpec filetime_to_timespec(LARGE_INTEGER li) { - return ret; - } - -+TimeSpec filetime_to_timespec(FILETIME ft) { -+ LARGE_INTEGER li; -+ li.LowPart = ft.dwLowDateTime; -+ li.HighPart = ft.dwHighDateTime; -+ return filetime_to_timespec(li); -+} -+ -+FILETIME timespec_to_filetime(TimeSpec ts) { -+ LARGE_INTEGER li; -+ li.QuadPart = -+ ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000; -+ FILETIME ft; -+ ft.dwLowDateTime = li.LowPart; -+ ft.dwHighDateTime = li.HighPart; -+ return ft; -+} -+ - int set_errno(int e = GetLastError()) { - errno = static_cast(__win_err_to_errc(e)); - return -1; --- -2.25.1 - diff --git a/patches/llvm-project/0003-libcxx-Hook-up-a-number-of-operation-functions-to-th.patch b/patches/llvm-project/0003-libcxx-Hook-up-a-number-of-operation-functions-to-th.patch deleted file mode 100644 index cc0d813..0000000 --- a/patches/llvm-project/0003-libcxx-Hook-up-a-number-of-operation-functions-to-th.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 13bc151ad49587f94a123cdb3e2ba770c1513d9d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Fri, 6 Nov 2020 11:16:30 +0200 -Subject: [PATCH 03/25] [libcxx] Hook up a number of operation functions to - their windows counterparts - -Use the corresponding wchar functions, named "_wfunc" instead of "func", -where feasible, or reimplement functions with native windows APIs. - -Differential Revision: https://reviews.llvm.org/D91143 - -(cherry picked from commit efec3cc6524bc536459b9cb6faca190b1e3804b6) ---- - libcxx/src/filesystem/operations.cpp | 41 ++++++----- - libcxx/src/filesystem/posix_compat.h | 102 +++++++++++++++++++++++++++ - 2 files changed, 124 insertions(+), 19 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 40a863db69a1..ddb4d7588e54 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -405,7 +405,7 @@ struct FileDescriptor { - static FileDescriptor create(const path* p, error_code& ec, Args... args) { - ec.clear(); - int fd; -- if ((fd = ::open(p->c_str(), args...)) == -1) { -+ if ((fd = detail::open(p->c_str(), args...)) == -1) { - ec = capture_errno(); - return FileDescriptor{p}; - } -@@ -431,7 +431,7 @@ struct FileDescriptor { - - void close() noexcept { - if (fd != -1) -- ::close(fd); -+ detail::close(fd); - fd = -1; - } - -@@ -521,7 +521,7 @@ file_status posix_lstat(path const& p, error_code* ec) { - - // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html - bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { -- if (::ftruncate(fd.fd, to_size) == -1) { -+ if (detail::ftruncate(fd.fd, to_size) == -1) { - ec = capture_errno(); - return true; - } -@@ -828,8 +828,8 @@ bool __copy_file(const path& from, const path& to, copy_options options, - ErrorHandler err("copy_file", ec, &to, &from); - - error_code m_ec; -- FileDescriptor from_fd = -- FileDescriptor::create_with_status(&from, m_ec, O_RDONLY | O_NONBLOCK); -+ FileDescriptor from_fd = FileDescriptor::create_with_status( -+ &from, m_ec, O_RDONLY | O_NONBLOCK | O_BINARY); - if (m_ec) - return err.report(m_ec); - -@@ -881,7 +881,7 @@ bool __copy_file(const path& from, const path& to, copy_options options, - - // Don't truncate right away. We may not be opening the file we originally - // looked at; we'll check this later. -- int to_open_flags = O_WRONLY; -+ int to_open_flags = O_WRONLY | O_BINARY; - if (!to_exists) - to_open_flags |= O_CREAT; - FileDescriptor to_fd = FileDescriptor::create_with_status( -@@ -917,10 +917,13 @@ void __copy_symlink(const path& existing_symlink, const path& new_symlink, - if (ec && *ec) { - return; - } -- // NOTE: proposal says you should detect if you should call -- // create_symlink or create_directory_symlink. I don't think this -- // is needed with POSIX -- __create_symlink(real_path, new_symlink, ec); -+#if defined(_LIBCPP_WIN32API) -+ error_code local_ec; -+ if (is_directory(real_path, local_ec)) -+ __create_directory_symlink(real_path, new_symlink, ec); -+ else -+#endif -+ __create_symlink(real_path, new_symlink, ec); - } - - bool __create_directories(const path& p, error_code* ec) { -@@ -953,7 +956,7 @@ bool __create_directories(const path& p, error_code* ec) { - bool __create_directory(const path& p, error_code* ec) { - ErrorHandler err("create_directory", ec, &p); - -- if (::mkdir(p.c_str(), static_cast(perms::all)) == 0) -+ if (detail::mkdir(p.c_str(), static_cast(perms::all)) == 0) - return true; - - if (errno == EEXIST) { -@@ -981,7 +984,7 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { - return err.report(errc::not_a_directory, - "the specified attribute path is invalid"); - -- if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) -+ if (detail::mkdir(p.c_str(), attr_stat.st_mode) == 0) - return true; - - if (errno == EEXIST) { -@@ -1000,19 +1003,19 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) { - void __create_directory_symlink(path const& from, path const& to, - error_code* ec) { - ErrorHandler err("create_directory_symlink", ec, &from, &to); -- if (::symlink(from.c_str(), to.c_str()) != 0) -+ if (detail::symlink_dir(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); - } - - void __create_hard_link(const path& from, const path& to, error_code* ec) { - ErrorHandler err("create_hard_link", ec, &from, &to); -- if (::link(from.c_str(), to.c_str()) == -1) -+ if (detail::link(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); - } - - void __create_symlink(path const& from, path const& to, error_code* ec) { - ErrorHandler err("create_symlink", ec, &from, &to); -- if (::symlink(from.c_str(), to.c_str()) == -1) -+ if (detail::symlink_file(from.c_str(), to.c_str()) == -1) - return err.report(capture_errno()); - } - -@@ -1032,7 +1035,7 @@ path __current_path(error_code* ec) { - - void __current_path(const path& p, error_code* ec) { - ErrorHandler err("current_path", ec, &p); -- if (::chdir(p.c_str()) == -1) -+ if (detail::chdir(p.c_str()) == -1) - err.report(capture_errno()); - } - -@@ -1236,7 +1239,7 @@ path __read_symlink(const path& p, error_code* ec) { - - bool __remove(const path& p, error_code* ec) { - ErrorHandler err("remove", ec, &p); -- if (::remove(p.c_str()) == -1) { -+ if (detail::remove(p.c_str()) == -1) { - if (errno != ENOENT) - err.report(capture_errno()); - return false; -@@ -1285,13 +1288,13 @@ uintmax_t __remove_all(const path& p, error_code* ec) { - - void __rename(const path& from, const path& to, error_code* ec) { - ErrorHandler err("rename", ec, &from, &to); -- if (::rename(from.c_str(), to.c_str()) == -1) -+ if (detail::rename(from.c_str(), to.c_str()) == -1) - err.report(capture_errno()); - } - - void __resize_file(const path& p, uintmax_t size, error_code* ec) { - ErrorHandler err("resize_file", ec, &p); -- if (::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1) -+ if (detail::truncate(p.c_str(), static_cast< ::off_t>(size)) == -1) - return err.report(capture_errno()); - } - -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 7caf9d28b49d..1e70e12cb4d7 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -12,6 +12,8 @@ - // These generally behave like the proper posix functions, with these - // exceptions: - // On Windows, they take paths in wchar_t* form, instead of char* form. -+// The symlink() function is split into two frontends, symlink_file() -+// and symlink_dir(). - // - // These are provided within an anonymous namespace within the detail - // namespace - callers need to include this header and call them as -@@ -82,6 +84,8 @@ namespace { - #define S_ISLNK(m) (((m) & _S_IFMT) == _S_IFLNK) - #define S_ISSOCK(m) (((m) & _S_IFMT) == _S_IFSOCK) - -+#define O_NONBLOCK 0 -+ - - // There were 369 years and 89 leap days from the Windows epoch - // (1601) to the Unix epoch (1970). -@@ -190,10 +194,108 @@ int fstat(int fd, StatT *buf) { - HANDLE h = reinterpret_cast(_get_osfhandle(fd)); - return stat_handle(h, buf); - } -+ -+int mkdir(const wchar_t *path, int permissions) { -+ (void)permissions; -+ return _wmkdir(path); -+} -+ -+int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, -+ bool is_dir) { -+ DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; -+ if (CreateSymbolicLinkW(newname, oldname, -+ flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) -+ return 0; -+ int e = GetLastError(); -+ if (e != ERROR_INVALID_PARAMETER) -+ return set_errno(e); -+ if (CreateSymbolicLinkW(newname, oldname, flags)) -+ return 0; -+ return set_errno(); -+} -+ -+int symlink_file(const wchar_t *oldname, const wchar_t *newname) { -+ return symlink_file_dir(oldname, newname, false); -+} -+ -+int symlink_dir(const wchar_t *oldname, const wchar_t *newname) { -+ return symlink_file_dir(oldname, newname, true); -+} -+ -+int link(const wchar_t *oldname, const wchar_t *newname) { -+ if (CreateHardLinkW(newname, oldname, nullptr)) -+ return 0; -+ return set_errno(); -+} -+ -+int remove(const wchar_t *path) { -+ detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT); -+ if (!h) -+ return set_errno(); -+ FILE_DISPOSITION_INFO info; -+ info.DeleteFile = TRUE; -+ if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info))) -+ return set_errno(); -+ return 0; -+} -+ -+int truncate_handle(HANDLE h, off_t length) { -+ LARGE_INTEGER size_param; -+ size_param.QuadPart = length; -+ if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN)) -+ return set_errno(); -+ if (!SetEndOfFile(h)) -+ return set_errno(); -+ return 0; -+} -+ -+int ftruncate(int fd, off_t length) { -+ HANDLE h = reinterpret_cast(_get_osfhandle(fd)); -+ return truncate_handle(h, length); -+} -+ -+int truncate(const wchar_t *path, off_t length) { -+ detail::WinHandle h(path, GENERIC_WRITE, 0); -+ if (!h) -+ return set_errno(); -+ return truncate_handle(h, length); -+} -+ -+int rename(const wchar_t *from, const wchar_t *to) { -+ if (!(MoveFileExW(from, to, -+ MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | -+ MOVEFILE_WRITE_THROUGH))) -+ return set_errno(); -+ return 0; -+} -+ -+template int open(const wchar_t *filename, Args... args) { -+ return _wopen(filename, args...); -+} -+int close(int fd) { return _close(fd); } -+int chdir(const wchar_t *path) { return _wchdir(path); } - #else -+int symlink_file(const char *oldname, const char *newname) { -+ return ::symlink(oldname, newname); -+} -+int symlink_dir(const char *oldname, const char *newname) { -+ return ::symlink(oldname, newname); -+} -+using ::chdir; -+using ::close; - using ::fstat; -+using ::ftruncate; -+using ::link; - using ::lstat; -+using ::mkdir; -+using ::open; -+using ::remove; -+using ::rename; - using ::stat; -+using ::truncate; -+ -+#define O_BINARY 0 -+ - #endif - - } // namespace --- -2.25.1 - diff --git a/patches/llvm-project/0004-libcxx-Sanitize-paths-before-creating-symlinks-on-wi.patch b/patches/llvm-project/0004-libcxx-Sanitize-paths-before-creating-symlinks-on-wi.patch deleted file mode 100644 index 2fcc797..0000000 --- a/patches/llvm-project/0004-libcxx-Sanitize-paths-before-creating-symlinks-on-wi.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 21ffff20ef2e05f8c99bd120d7b1212d75f14dcd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Mon, 9 Nov 2020 15:20:18 +0200 -Subject: [PATCH 04/25] [libcxx] Sanitize paths before creating symlinks on - windows - -The MS STL does even more cleanup (corresponding to lexically_normal -I think), but this seems to be the very minimum needed for making the -symlinks work when the target path contains non-native paths. - -Differential Revision: https://reviews.llvm.org/D91145 - -(cherry picked from commit f65ba25cf37a57dc87db7af389c9dc637ca7dd8c) ---- - libcxx/src/filesystem/posix_compat.h | 3 +++ - .../create_symlink.pass.cpp | 20 +++++++++++++++++++ - 2 files changed, 23 insertions(+) - -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 1e70e12cb4d7..0dbae1235a00 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -202,6 +202,9 @@ int mkdir(const wchar_t *path, int permissions) { - - int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, - bool is_dir) { -+ path dest(oldname); -+ dest.make_preferred(); -+ oldname = dest.c_str(); - DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0; - if (CreateSymbolicLinkW(newname, oldname, - flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)) -diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp -index 47ec916a169b..3b54cff309b7 100644 ---- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_symlink/create_symlink.pass.cpp -@@ -71,5 +71,25 @@ TEST_CASE(create_symlink_basic) - } - } - -+TEST_CASE(create_symlink_dest_cleanup) -+{ -+ scoped_test_env env; -+ const path dir = env.create_dir("dir"); -+ const path file = env.create_file("file", 42); -+ const path sym = dir / "link"; -+ // The target path has to be normalized to backslashes before creating -+ // the link on windows, otherwise the link isn't dereferencable. -+ const path sym_target = "../file"; -+ path sym_target_normalized = sym_target; -+ sym_target_normalized.make_preferred(); -+ std::error_code ec; -+ fs::create_symlink(sym_target, sym, ec); -+ TEST_REQUIRE(!ec); -+ TEST_CHECK(equivalent(sym, file, ec)); -+ const path ret = fs::read_symlink(sym, ec); -+ TEST_CHECK(!ec); -+ TEST_CHECK(ret.native() == sym_target_normalized.native()); -+} -+ - - TEST_SUITE_END() --- -2.25.1 - diff --git a/patches/llvm-project/0005-libcxx-Implement-the-space-function-for-windows.patch b/patches/llvm-project/0005-libcxx-Implement-the-space-function-for-windows.patch deleted file mode 100644 index b716ba9..0000000 --- a/patches/llvm-project/0005-libcxx-Implement-the-space-function-for-windows.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 51a0f3a5af65c8e8e1618dc5621705471aba2151 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 23:32:13 +0200 -Subject: [PATCH 05/25] [libcxx] Implement the space function for windows - -Differential Revision: https://reviews.llvm.org/D91168 - -(cherry picked from commit a3cc99658d52f79faad26beeea06691b3a50bc95) ---- - libcxx/src/filesystem/operations.cpp | 4 +-- - libcxx/src/filesystem/posix_compat.h | 37 ++++++++++++++++++++++++++++ - 2 files changed, 39 insertions(+), 2 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index ddb4d7588e54..fcb5c2def23c 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1301,8 +1301,8 @@ void __resize_file(const path& p, uintmax_t size, error_code* ec) { - space_info __space(const path& p, error_code* ec) { - ErrorHandler err("space", ec, &p); - space_info si; -- struct statvfs m_svfs = {}; -- if (::statvfs(p.c_str(), &m_svfs) == -1) { -+ detail::StatVFS m_svfs = {}; -+ if (detail::statvfs(p.c_str(), &m_svfs) == -1) { - err.report(capture_errno()); - si.capacity = si.free = si.available = static_cast(-1); - return si; -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 0dbae1235a00..5f868a090693 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -277,6 +277,40 @@ template int open(const wchar_t *filename, Args... args) { - } - int close(int fd) { return _close(fd); } - int chdir(const wchar_t *path) { return _wchdir(path); } -+ -+struct StatVFS { -+ uint64_t f_frsize; -+ uint64_t f_blocks; -+ uint64_t f_bfree; -+ uint64_t f_bavail; -+}; -+ -+int statvfs(const wchar_t *p, StatVFS *buf) { -+ path dir = p; -+ while (true) { -+ error_code local_ec; -+ const file_status st = status(dir, local_ec); -+ if (!exists(st) || is_directory(st)) -+ break; -+ path parent = dir.parent_path(); -+ if (parent == dir) { -+ errno = ENOENT; -+ return -1; -+ } -+ dir = parent; -+ } -+ ULARGE_INTEGER free_bytes_available_to_caller, total_number_of_bytes, -+ total_number_of_free_bytes; -+ if (!GetDiskFreeSpaceExW(dir.c_str(), &free_bytes_available_to_caller, -+ &total_number_of_bytes, &total_number_of_free_bytes)) -+ return set_errno(); -+ buf->f_frsize = 1; -+ buf->f_blocks = total_number_of_bytes.QuadPart; -+ buf->f_bfree = total_number_of_free_bytes.QuadPart; -+ buf->f_bavail = free_bytes_available_to_caller.QuadPart; -+ return 0; -+} -+ - #else - int symlink_file(const char *oldname, const char *newname) { - return ::symlink(oldname, newname); -@@ -295,10 +329,13 @@ using ::open; - using ::remove; - using ::rename; - using ::stat; -+using ::statvfs; - using ::truncate; - - #define O_BINARY 0 - -+using StatVFS = struct statvfs; -+ - #endif - - } // namespace --- -2.25.1 - diff --git a/patches/llvm-project/0006-libcxx-Implement-the-current_path-function-for-windo.patch b/patches/llvm-project/0006-libcxx-Implement-the-current_path-function-for-windo.patch deleted file mode 100644 index 467bcb2..0000000 --- a/patches/llvm-project/0006-libcxx-Implement-the-current_path-function-for-windo.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 0bdb2f73e8ba72de291d1ca95363835ab538bdab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 23:46:12 +0200 -Subject: [PATCH 06/25] [libcxx] Implement the current_path function for - windows - -Differential Revision: https://reviews.llvm.org/D91169 - -(cherry picked from commit 0c71c914faa371ba502a2e1835f763104837cb9f) ---- - libcxx/src/filesystem/operations.cpp | 25 +++++++++++++++++++++---- - libcxx/src/filesystem/posix_compat.h | 2 ++ - 2 files changed, 23 insertions(+), 4 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index fcb5c2def23c..429a58501a49 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1022,15 +1022,32 @@ void __create_symlink(path const& from, path const& to, error_code* ec) { - path __current_path(error_code* ec) { - ErrorHandler err("current_path", ec); - -+#if defined(_LIBCPP_WIN32API) -+ // Common extension outside of POSIX getcwd() spec, without needing to -+ // preallocate a buffer. Also supported by a number of other POSIX libcs. -+ int size = 0; -+ path::value_type* ptr = nullptr; -+ typedef decltype(&::free) Deleter; -+ Deleter deleter = &::free; -+#else - auto size = ::pathconf(".", _PC_PATH_MAX); - _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size"); - -- auto buff = unique_ptr(new char[size + 1]); -- char* ret; -- if ((ret = ::getcwd(buff.get(), static_cast(size))) == nullptr) -+ auto buff = unique_ptr(new path::value_type[size + 1]); -+ path::value_type* ptr = buff.get(); -+ -+ // Preallocated buffer, don't free the buffer in the second unique_ptr -+ // below. -+ struct Deleter { void operator()(void*) const {} }; -+ Deleter deleter; -+#endif -+ -+ unique_ptr hold(detail::getcwd(ptr, size), -+ deleter); -+ if (hold.get() == nullptr) - return err.report(capture_errno(), "call to getcwd failed"); - -- return {buff.get()}; -+ return {hold.get()}; - } - - void __current_path(const path& p, error_code* ec) { -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 5f868a090693..13753fdbb760 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -311,6 +311,7 @@ int statvfs(const wchar_t *p, StatVFS *buf) { - return 0; - } - -+wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); } - #else - int symlink_file(const char *oldname, const char *newname) { - return ::symlink(oldname, newname); -@@ -322,6 +323,7 @@ using ::chdir; - using ::close; - using ::fstat; - using ::ftruncate; -+using ::getcwd; - using ::link; - using ::lstat; - using ::mkdir; --- -2.25.1 - diff --git a/patches/llvm-project/0007-libcxx-Implement-the-canonical-function-for-windows.patch b/patches/llvm-project/0007-libcxx-Implement-the-canonical-function-for-windows.patch deleted file mode 100644 index f5e57d1..0000000 --- a/patches/llvm-project/0007-libcxx-Implement-the-canonical-function-for-windows.patch +++ /dev/null @@ -1,104 +0,0 @@ -From b6ef948856bfde6326ebc2d1fddc24890b4182f9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 23:51:12 +0200 -Subject: [PATCH 07/25] [libcxx] Implement the canonical function for windows - -Differential Revision: https://reviews.llvm.org/D91170 - -(cherry picked from commit 83d705adb2e043e576c9cbaf9709795bc69fe5cf) ---- - libcxx/src/filesystem/operations.cpp | 14 +++++----- - libcxx/src/filesystem/posix_compat.h | 38 ++++++++++++++++++++++++++++ - 2 files changed, 45 insertions(+), 7 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 429a58501a49..fc18de9e5d80 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -636,20 +636,20 @@ path __canonical(path const& orig_p, error_code* ec) { - ErrorHandler err("canonical", ec, &orig_p, &cwd); - - path p = __do_absolute(orig_p, &cwd, ec); --#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112 -- std::unique_ptr -- hold(::realpath(p.c_str(), nullptr), &::free); -+#if (defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112) || defined(_LIBCPP_WIN32API) -+ std::unique_ptr -+ hold(detail::realpath(p.c_str(), nullptr), &::free); - if (hold.get() == nullptr) - return err.report(capture_errno()); - return {hold.get()}; - #else - #if defined(__MVS__) && !defined(PATH_MAX) -- char buff[ _XOPEN_PATH_MAX + 1 ]; -+ path::value_type buff[ _XOPEN_PATH_MAX + 1 ]; - #else -- char buff[PATH_MAX + 1]; -+ path::value_type buff[PATH_MAX + 1]; - #endif -- char* ret; -- if ((ret = ::realpath(p.c_str(), buff)) == nullptr) -+ path::value_type* ret; -+ if ((ret = detail::realpath(p.c_str(), buff)) == nullptr) - return err.report(capture_errno()); - return {ret}; - #endif -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 13753fdbb760..1adce3a779c2 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -312,6 +312,43 @@ int statvfs(const wchar_t *p, StatVFS *buf) { - } - - wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); } -+ -+wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) { -+ // Only expected to be used with us allocating the buffer. -+ _LIBCPP_ASSERT(resolved_name == nullptr, -+ "Windows realpath() assumes a null resolved_name"); -+ -+ WinHandle h(path, FILE_READ_ATTRIBUTES, 0); -+ if (!h) { -+ set_errno(); -+ return nullptr; -+ } -+ size_t buff_size = MAX_PATH + 10; -+ std::unique_ptr buff( -+ static_cast(malloc(buff_size * sizeof(wchar_t))), &::free); -+ DWORD retval = GetFinalPathNameByHandleW( -+ h, buff.get(), buff_size, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); -+ if (retval > buff_size) { -+ buff_size = retval; -+ buff.reset(static_cast(malloc(buff_size * sizeof(wchar_t)))); -+ retval = GetFinalPathNameByHandleW(h, buff.get(), buff_size, -+ FILE_NAME_NORMALIZED | VOLUME_NAME_DOS); -+ } -+ if (!retval) { -+ set_errno(); -+ return nullptr; -+ } -+ wchar_t *ptr = buff.get(); -+ if (!wcsncmp(ptr, L"\\\\?\\", 4)) { -+ if (ptr[5] == ':') { // \\?\X: -> X: -+ memmove(&ptr[0], &ptr[4], (wcslen(&ptr[4]) + 1) * sizeof(wchar_t)); -+ } else if (!wcsncmp(&ptr[4], L"UNC\\", 4)) { // \\?\UNC\server -> \\server -+ wcscpy(&ptr[0], L"\\\\"); -+ memmove(&ptr[2], &ptr[8], (wcslen(&ptr[8]) + 1) * sizeof(wchar_t)); -+ } -+ } -+ return buff.release(); -+} - #else - int symlink_file(const char *oldname, const char *newname) { - return ::symlink(oldname, newname); -@@ -328,6 +365,7 @@ using ::link; - using ::lstat; - using ::mkdir; - using ::open; -+using ::realpath; - using ::remove; - using ::rename; - using ::stat; --- -2.25.1 - diff --git a/patches/llvm-project/0008-libcxx-Implement-the-permissions-function-for-window.patch b/patches/llvm-project/0008-libcxx-Implement-the-permissions-function-for-window.patch deleted file mode 100644 index 1198c2e..0000000 --- a/patches/llvm-project/0008-libcxx-Implement-the-permissions-function-for-window.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 96748da73f57e6b080643d03e41e8a690ee571a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 23:55:10 +0200 -Subject: [PATCH 08/25] [libcxx] Implement the permissions function for windows - -Differential Revision: https://reviews.llvm.org/D91171 - -(cherry picked from commit 40117b700f723a27b90989a429ceb66c0873b161) ---- - libcxx/src/filesystem/operations.cpp | 10 ++---- - libcxx/src/filesystem/posix_compat.h | 54 ++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+), 7 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index fc18de9e5d80..47cd5e23c092 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -455,10 +455,6 @@ perms posix_get_perms(const StatT& st) noexcept { - return static_cast(st.st_mode) & perms::mask; - } - --::mode_t posix_convert_perms(perms prms) { -- return static_cast< ::mode_t>(prms & perms::mask); --} -- - file_status create_file_status(error_code& m_ec, path const& p, - const StatT& path_stat, error_code* ec) { - if (ec) -@@ -530,7 +526,7 @@ bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { - } - - bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { -- if (::fchmod(fd.fd, st.st_mode) == -1) { -+ if (detail::fchmod(fd.fd, st.st_mode) == -1) { - ec = capture_errno(); - return true; - } -@@ -1212,11 +1208,11 @@ void __permissions(const path& p, perms prms, perm_options opts, - else if (remove_perms) - prms = st.permissions() & ~prms; - } -- const auto real_perms = detail::posix_convert_perms(prms); -+ const auto real_perms = static_cast(prms & perms::mask); - - #if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) - const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; -- if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { -+ if (detail::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { - return err.report(capture_errno()); - } - #else -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 1adce3a779c2..af4a3691db33 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -349,6 +349,57 @@ wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) { - } - return buff.release(); - } -+ -+#define AT_FDCWD -1 -+#define AT_SYMLINK_NOFOLLOW 1 -+using ModeT = int; -+ -+int fchmod_handle(HANDLE h, int perms) { -+ FILE_BASIC_INFO basic; -+ if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) -+ return set_errno(); -+ DWORD orig_attributes = basic.FileAttributes; -+ basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; -+ if ((perms & 0222) == 0) -+ basic.FileAttributes |= FILE_ATTRIBUTE_READONLY; -+ if (basic.FileAttributes != orig_attributes && -+ !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic))) -+ return set_errno(); -+ return 0; -+} -+ -+int fchmodat(int fd, const wchar_t *path, int perms, int flag) { -+ DWORD attributes = GetFileAttributesW(path); -+ if (attributes == INVALID_FILE_ATTRIBUTES) -+ return set_errno(); -+ if (attributes & FILE_ATTRIBUTE_REPARSE_POINT && -+ !(flag & AT_SYMLINK_NOFOLLOW)) { -+ // If the file is a symlink, and we are supposed to operate on the target -+ // of the symlink, we need to open a handle to it, without the -+ // FILE_FLAG_OPEN_REPARSE_POINT flag, to open the destination of the -+ // symlink, and operate on it via the handle. -+ detail::WinHandle h(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0); -+ if (!h) -+ return set_errno(); -+ return fchmod_handle(h, perms); -+ } else { -+ // For a non-symlink, or if operating on the symlink itself instead of -+ // its target, we can use SetFileAttributesW, saving a few calls. -+ DWORD orig_attributes = attributes; -+ attributes &= ~FILE_ATTRIBUTE_READONLY; -+ if ((perms & 0222) == 0) -+ attributes |= FILE_ATTRIBUTE_READONLY; -+ if (attributes != orig_attributes && !SetFileAttributesW(path, attributes)) -+ return set_errno(); -+ } -+ return 0; -+} -+ -+int fchmod(int fd, int perms) { -+ HANDLE h = reinterpret_cast(_get_osfhandle(fd)); -+ return fchmod_handle(h, perms); -+} -+ - #else - int symlink_file(const char *oldname, const char *newname) { - return ::symlink(oldname, newname); -@@ -358,6 +409,8 @@ int symlink_dir(const char *oldname, const char *newname) { - } - using ::chdir; - using ::close; -+using ::fchmod; -+using ::fchmodat; - using ::fstat; - using ::ftruncate; - using ::getcwd; -@@ -375,6 +428,7 @@ using ::truncate; - #define O_BINARY 0 - - using StatVFS = struct statvfs; -+using ModeT = ::mode_t; - - #endif - --- -2.25.1 - diff --git a/patches/llvm-project/0009-libcxx-Implement-the-read_symlink-function-for-windo.patch b/patches/llvm-project/0009-libcxx-Implement-the-read_symlink-function-for-windo.patch deleted file mode 100644 index 5c7299b..0000000 --- a/patches/llvm-project/0009-libcxx-Implement-the-read_symlink-function-for-windo.patch +++ /dev/null @@ -1,171 +0,0 @@ -From f28542330202fae54a6fee1bf02a311feef3f60a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 23:51:18 +0200 -Subject: [PATCH 09/25] [libcxx] Implement the read_symlink function for - windows - -Differential Revision: https://reviews.llvm.org/D91172 - -(cherry picked from commit cdc60a3b9aa523b49329a7a5e4c1774d3b9e3db9) ---- - libcxx/src/filesystem/operations.cpp | 16 +++--- - libcxx/src/filesystem/posix_compat.h | 79 ++++++++++++++++++++++++++++ - 2 files changed, 89 insertions(+), 6 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 47cd5e23c092..a5463e48f4d7 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1227,21 +1227,25 @@ void __permissions(const path& p, perms prms, perm_options opts, - path __read_symlink(const path& p, error_code* ec) { - ErrorHandler err("read_symlink", ec, &p); - --#ifdef PATH_MAX -+#if defined(PATH_MAX) || defined(MAX_SYMLINK_SIZE) - struct NullDeleter { void operator()(void*) const {} }; -+#ifdef MAX_SYMLINK_SIZE -+ const size_t size = MAX_SYMLINK_SIZE + 1; -+#else - const size_t size = PATH_MAX + 1; -- char stack_buff[size]; -- auto buff = std::unique_ptr(stack_buff); -+#endif -+ path::value_type stack_buff[size]; -+ auto buff = std::unique_ptr(stack_buff); - #else - StatT sb; - if (detail::lstat(p.c_str(), &sb) == -1) { - return err.report(capture_errno()); - } - const size_t size = sb.st_size + 1; -- auto buff = unique_ptr(new char[size]); -+ auto buff = unique_ptr(new path::value_type[size]); - #endif -- ::ssize_t ret; -- if ((ret = ::readlink(p.c_str(), buff.get(), size)) == -1) -+ detail::SSizeT ret; -+ if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1) - return err.report(capture_errno()); - _LIBCPP_ASSERT(ret > 0, "TODO"); - if (static_cast(ret) >= size) -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index af4a3691db33..8062bd65ce00 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -32,6 +32,7 @@ - # define NOMINMAX - # include - # include -+# include - #else - # include - # include -@@ -39,6 +40,36 @@ - #endif - #include - -+#if defined(_LIBCPP_WIN32API) -+// This struct isn't defined in the normal Windows SDK, but only in the -+// Windows Driver Kit. -+struct LIBCPP_REPARSE_DATA_BUFFER { -+ unsigned long ReparseTag; -+ unsigned short ReparseDataLength; -+ unsigned short Reserved; -+ union { -+ struct { -+ unsigned short SubstituteNameOffset; -+ unsigned short SubstituteNameLength; -+ unsigned short PrintNameOffset; -+ unsigned short PrintNameLength; -+ unsigned long Flags; -+ wchar_t PathBuffer[1]; -+ } SymbolicLinkReparseBuffer; -+ struct { -+ unsigned short SubstituteNameOffset; -+ unsigned short SubstituteNameLength; -+ unsigned short PrintNameOffset; -+ unsigned short PrintNameLength; -+ wchar_t PathBuffer[1]; -+ } MountPointReparseBuffer; -+ struct { -+ unsigned char DataBuffer[1]; -+ } GenericReparseBuffer; -+ }; -+}; -+#endif -+ - _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM - - namespace detail { -@@ -400,6 +431,52 @@ int fchmod(int fd, int perms) { - return fchmod_handle(h, perms); - } - -+#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE -+using SSizeT = ::int64_t; -+ -+SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) { -+ uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; -+ detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT); -+ if (!h) -+ return set_errno(); -+ DWORD out; -+ if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf, sizeof(buf), -+ &out, 0)) -+ return set_errno(); -+ const auto *reparse = reinterpret_cast(buf); -+ size_t path_buf_offset = offsetof(LIBCPP_REPARSE_DATA_BUFFER, -+ SymbolicLinkReparseBuffer.PathBuffer[0]); -+ if (out < path_buf_offset) { -+ errno = EINVAL; -+ return -1; -+ } -+ if (reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) { -+ errno = EINVAL; -+ return -1; -+ } -+ const auto &symlink = reparse->SymbolicLinkReparseBuffer; -+ unsigned short name_offset, name_length; -+ if (symlink.PrintNameLength == 0) { -+ name_offset = symlink.SubstituteNameOffset; -+ name_length = symlink.SubstituteNameLength; -+ } else { -+ name_offset = symlink.PrintNameOffset; -+ name_length = symlink.PrintNameLength; -+ } -+ // name_offset/length are expressed in bytes, not in wchar_t -+ if (path_buf_offset + name_offset + name_length > out) { -+ errno = EINVAL; -+ return -1; -+ } -+ if (name_length / sizeof(wchar_t) > bufsize) { -+ errno = ENOMEM; -+ return -1; -+ } -+ memcpy(ret_buf, &symlink.PathBuffer[name_offset / sizeof(wchar_t)], -+ name_length); -+ return name_length / sizeof(wchar_t); -+} -+ - #else - int symlink_file(const char *oldname, const char *newname) { - return ::symlink(oldname, newname); -@@ -418,6 +495,7 @@ using ::link; - using ::lstat; - using ::mkdir; - using ::open; -+using ::readlink; - using ::realpath; - using ::remove; - using ::rename; -@@ -429,6 +507,7 @@ using ::truncate; - - using StatVFS = struct statvfs; - using ModeT = ::mode_t; -+using SSizeT = ::ssize_t; - - #endif - --- -2.25.1 - diff --git a/patches/llvm-project/0010-libcxx-Use-the-posix-code-for-directory_entry-__do_r.patch b/patches/llvm-project/0010-libcxx-Use-the-posix-code-for-directory_entry-__do_r.patch deleted file mode 100644 index d0bac0e..0000000 --- a/patches/llvm-project/0010-libcxx-Use-the-posix-code-for-directory_entry-__do_r.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 6f225c9fca50bda8911a4909b3cbf0eb28733384 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Fri, 30 Oct 2020 22:24:25 +0200 -Subject: [PATCH 10/25] [libcxx] Use the posix code for - directory_entry::__do_refresh - -This works just fine for windows, as all the functions it calls -are implemented and wrapped for windows. - -Differential Revision: https://reviews.llvm.org/D91173 - -(cherry picked from commit 4d292d531bea6f7a6021f212e59b3826bc7cd913) ---- - libcxx/src/filesystem/operations.cpp | 43 ---------------------------- - 1 file changed, 43 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index a5463e48f4d7..dccec9378531 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1847,7 +1847,6 @@ size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) { - // directory entry definitions - /////////////////////////////////////////////////////////////////////////////// - --#ifndef _LIBCPP_WIN32API - error_code directory_entry::__do_refresh() noexcept { - __data_.__reset(); - error_code failure_ec; -@@ -1901,47 +1900,5 @@ error_code directory_entry::__do_refresh() noexcept { - - return failure_ec; - } --#else --error_code directory_entry::__do_refresh() noexcept { -- __data_.__reset(); -- error_code failure_ec; -- -- file_status st = _VSTD_FS::symlink_status(__p_, failure_ec); -- if (!status_known(st)) { -- __data_.__reset(); -- return failure_ec; -- } -- -- if (!_VSTD_FS::exists(st) || !_VSTD_FS::is_symlink(st)) { -- __data_.__cache_type_ = directory_entry::_RefreshNonSymlink; -- __data_.__type_ = st.type(); -- __data_.__non_sym_perms_ = st.permissions(); -- } else { // we have a symlink -- __data_.__sym_perms_ = st.permissions(); -- // Get the information about the linked entity. -- // Ignore errors from stat, since we don't want errors regarding symlink -- // resolution to be reported to the user. -- error_code ignored_ec; -- st = _VSTD_FS::status(__p_, ignored_ec); -- -- __data_.__type_ = st.type(); -- __data_.__non_sym_perms_ = st.permissions(); -- -- // If we failed to resolve the link, then only partially populate the -- // cache. -- if (!status_known(st)) { -- __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved; -- return error_code{}; -- } -- __data_.__cache_type_ = directory_entry::_RefreshSymlink; -- } -- -- // FIXME: This is currently broken, and the implementation only a placeholder. -- // We need to cache last_write_time, file_size, and hard_link_count here before -- // the implementation actually works. -- -- return failure_ec; --} --#endif - - _LIBCPP_END_NAMESPACE_FILESYSTEM --- -2.25.1 - diff --git a/patches/llvm-project/0011-libcxx-Implement-temp_directory_path-using-GetTempPa.patch b/patches/llvm-project/0011-libcxx-Implement-temp_directory_path-using-GetTempPa.patch deleted file mode 100644 index ca07f4b..0000000 --- a/patches/llvm-project/0011-libcxx-Implement-temp_directory_path-using-GetTempPa.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 3474a416fef709f218ff5897842819d379495cad Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Thu, 29 Oct 2020 12:10:26 +0200 -Subject: [PATCH 11/25] [libcxx] Implement temp_directory_path using - GetTempPath on windows - -This does roughly the same as the manual implementation, but checks -a slightly different set of environment variables and has a more -appropriate fallback if no environment variables are available -(/tmp isn't a very useful fallback on windows). - -Differential Revision: https://reviews.llvm.org/D91175 - -(cherry picked from commit d4f4e723d0b4f09d72880f1679c02d586bf8abfa) ---- - libcxx/src/filesystem/operations.cpp | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index dccec9378531..674f19154e6f 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1347,6 +1347,19 @@ file_status __symlink_status(const path& p, error_code* ec) { - path __temp_directory_path(error_code* ec) { - ErrorHandler err("temp_directory_path", ec); - -+#if defined(_LIBCPP_WIN32API) -+ wchar_t buf[MAX_PATH]; -+ DWORD retval = GetTempPathW(MAX_PATH, buf); -+ if (!retval) -+ return err.report(detail::make_windows_error(GetLastError())); -+ if (retval > MAX_PATH) -+ return err.report(errc::filename_too_long); -+ // GetTempPathW returns a path with a trailing slash, which we -+ // shouldn't include for consistency. -+ if (buf[retval-1] == L'\\') -+ buf[retval-1] = L'\0'; -+ path p(buf); -+#else - const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; - const char* ret = nullptr; - -@@ -1357,6 +1370,7 @@ path __temp_directory_path(error_code* ec) { - ret = "/tmp"; - - path p(ret); -+#endif - error_code m_ec; - file_status st = detail::posix_stat(p, &m_ec); - if (!status_known(st)) --- -2.25.1 - diff --git a/patches/llvm-project/0012-libcxx-Implement-parsing-of-root_name-for-paths-on-w.patch b/patches/llvm-project/0012-libcxx-Implement-parsing-of-root_name-for-paths-on-w.patch deleted file mode 100644 index 625b51f..0000000 --- a/patches/llvm-project/0012-libcxx-Implement-parsing-of-root_name-for-paths-on-w.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 3f12aeb4ae3fd43d98f0c698952713d9fef7bef3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Tue, 3 Nov 2020 23:52:32 +0200 -Subject: [PATCH 12/25] [libcxx] Implement parsing of root_name for paths on - windows - -Differential Revision: https://reviews.llvm.org/D91176 - -(cherry picked from commit 929f0bcc24e246ea02ab57df8009a6fd5751d45c) ---- - libcxx/src/filesystem/operations.cpp | 92 +++++++++++++++++++++++++--- - 1 file changed, 85 insertions(+), 7 deletions(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 674f19154e6f..88a039f85021 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -64,6 +64,10 @@ bool isSeparator(path::value_type C) { - return false; - } - -+bool isDriveLetter(path::value_type C) { -+ return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z'); -+} -+ - namespace parser { - - using string_view_t = path::__string_view; -@@ -120,6 +124,12 @@ public: - - switch (State) { - case PS_BeforeBegin: { -+ PosPtr TkEnd = consumeRootName(Start, End); -+ if (TkEnd) -+ return makeState(PS_InRootName, Start, TkEnd); -+ } -+ _LIBCPP_FALLTHROUGH(); -+ case PS_InRootName: { - PosPtr TkEnd = consumeSeparator(Start, End); - if (TkEnd) - return makeState(PS_InRootDir, Start, TkEnd); -@@ -142,7 +152,6 @@ public: - case PS_InTrailingSep: - return makeState(PS_AtEnd); - -- case PS_InRootName: - case PS_AtEnd: - _LIBCPP_UNREACHABLE(); - } -@@ -160,9 +169,15 @@ public: - if (PosPtr SepEnd = consumeSeparator(RStart, REnd)) { - if (SepEnd == REnd) - return makeState(PS_InRootDir, Path.data(), RStart + 1); -+ PosPtr TkStart = consumeRootName(SepEnd, REnd); -+ if (TkStart == REnd) -+ return makeState(PS_InRootDir, RStart, RStart + 1); - return makeState(PS_InTrailingSep, SepEnd + 1, RStart + 1); - } else { -- PosPtr TkStart = consumeName(RStart, REnd); -+ PosPtr TkStart = consumeRootName(RStart, REnd); -+ if (TkStart == REnd) -+ return makeState(PS_InRootName, TkStart + 1, RStart + 1); -+ TkStart = consumeName(RStart, REnd); - return makeState(PS_InFilenames, TkStart + 1, RStart + 1); - } - } -@@ -173,11 +188,17 @@ public: - PosPtr SepEnd = consumeSeparator(RStart, REnd); - if (SepEnd == REnd) - return makeState(PS_InRootDir, Path.data(), RStart + 1); -- PosPtr TkEnd = consumeName(SepEnd, REnd); -- return makeState(PS_InFilenames, TkEnd + 1, SepEnd + 1); -+ PosPtr TkStart = consumeRootName(SepEnd ? SepEnd : RStart, REnd); -+ if (TkStart == REnd) { -+ if (SepEnd) -+ return makeState(PS_InRootDir, SepEnd + 1, RStart + 1); -+ return makeState(PS_InRootName, TkStart + 1, RStart + 1); -+ } -+ TkStart = consumeName(SepEnd, REnd); -+ return makeState(PS_InFilenames, TkStart + 1, SepEnd + 1); - } - case PS_InRootDir: -- // return makeState(PS_InRootName, Path.data(), RStart + 1); -+ return makeState(PS_InRootName, Path.data(), RStart + 1); - case PS_InRootName: - case PS_BeforeBegin: - _LIBCPP_UNREACHABLE(); -@@ -284,7 +305,7 @@ private: - } - - PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept { -- if (P == End || !isSeparator(*P)) -+ if (P == nullptr || P == End || !isSeparator(*P)) - return nullptr; - const int Inc = P < End ? 1 : -1; - P += Inc; -@@ -293,15 +314,72 @@ private: - return P; - } - -+ // Consume exactly N separators, or return nullptr. -+ PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept { -+ PosPtr Ret = consumeSeparator(P, End); -+ if (Ret == nullptr) -+ return nullptr; -+ if (P < End) { -+ if (Ret == P + N) -+ return Ret; -+ } else { -+ if (Ret == P - N) -+ return Ret; -+ } -+ return nullptr; -+ } -+ - PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { -- if (P == End || isSeparator(*P)) -+ PosPtr Start = P; -+ if (P == nullptr || P == End || isSeparator(*P)) - return nullptr; - const int Inc = P < End ? 1 : -1; - P += Inc; - while (P != End && !isSeparator(*P)) - P += Inc; -+ if (P == End && Inc < 0) { -+ // Iterating backwards and consumed all the rest of the input. -+ // Check if the start of the string would have been considered -+ // a root name. -+ PosPtr RootEnd = consumeRootName(End + 1, Start); -+ if (RootEnd) -+ return RootEnd - 1; -+ } - return P; - } -+ -+ PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept { -+ if (P == End) -+ return nullptr; -+ if (P < End) { -+ if (P + 1 == End || !isDriveLetter(P[0]) || P[1] != ':') -+ return nullptr; -+ return P + 2; -+ } else { -+ if (P - 1 == End || !isDriveLetter(P[-1]) || P[0] != ':') -+ return nullptr; -+ return P - 2; -+ } -+ } -+ -+ PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept { -+ if (P == End) -+ return nullptr; -+ if (P < End) -+ return consumeName(consumeNSeparators(P, End, 2), End); -+ else -+ return consumeNSeparators(consumeName(P, End), End, 2); -+ } -+ -+ PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept { -+#if defined(_LIBCPP_WIN32API) -+ if (PosPtr Ret = consumeDriveLetter(P, End)) -+ return Ret; -+ if (PosPtr Ret = consumeNetworkRoot(P, End)) -+ return Ret; -+#endif -+ return nullptr; -+ } - }; - - string_view_pair separate_filename(string_view_t const& s) { --- -2.25.1 - diff --git a/patches/llvm-project/0013-libcxx-Implement-is_absolute-properly-for-windows.patch b/patches/llvm-project/0013-libcxx-Implement-is_absolute-properly-for-windows.patch deleted file mode 100644 index f5eaefe..0000000 --- a/patches/llvm-project/0013-libcxx-Implement-is_absolute-properly-for-windows.patch +++ /dev/null @@ -1,48 +0,0 @@ -From bd50990c64deae4ce6027767659c75a22822e2f5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Sun, 1 Nov 2020 23:39:03 +0200 -Subject: [PATCH 13/25] [libcxx] Implement is_absolute properly for windows - -Differential Revision: https://reviews.llvm.org/D91177 - -(cherry picked from commit 8a783e68452f646360d9902d2c2bc0e115d7bfa9) ---- - libcxx/include/filesystem | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem -index 92e37e183def..eecf416e851c 100644 ---- a/libcxx/include/filesystem -+++ b/libcxx/include/filesystem -@@ -1341,7 +1341,28 @@ public: - } - - _LIBCPP_INLINE_VISIBILITY bool is_absolute() const { -+#if defined(_LIBCPP_WIN32API) -+ __string_view __root_name_str = __root_name(); -+ __string_view __root_dir = __root_directory(); -+ if (__root_name_str.size() == 2 && __root_name_str[1] == ':') { -+ // A drive letter with no root directory is relative, e.g. x:example. -+ return !__root_dir.empty(); -+ } -+ // If no root name, it's relative, e.g. \example is relative to the current drive -+ if (__root_name_str.empty()) -+ return false; -+ if (__root_name_str.size() < 3) -+ return false; -+ // A server root name, like \\server, is always absolute -+ if (__root_name_str[0] != '/' && __root_name_str[0] != '\\') -+ return false; -+ if (__root_name_str[1] != '/' && __root_name_str[1] != '\\') -+ return false; -+ // Seems to be a server root name -+ return true; -+#else - return has_root_directory(); -+#endif - } - _LIBCPP_INLINE_VISIBILITY bool is_relative() const { return !is_absolute(); } - --- -2.25.1 - diff --git a/patches/llvm-project/0014-libcxx-Implement-append-and-operator-properly-for-wi.patch b/patches/llvm-project/0014-libcxx-Implement-append-and-operator-properly-for-wi.patch deleted file mode 100644 index 7b9e859..0000000 --- a/patches/llvm-project/0014-libcxx-Implement-append-and-operator-properly-for-wi.patch +++ /dev/null @@ -1,174 +0,0 @@ -From bd884f520faaa41618d6e901e1631ff02fab3044 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Wed, 4 Nov 2020 15:59:56 +0200 -Subject: [PATCH 14/25] [libcxx] Implement append and operator/ properly for - windows - -The root_path function has to be changed to return the parsed bit -as-is; otherwise a path like "//net" gets a root path of "//net/", as -the root name, "//net", gets the root directory (an empty string) appended, -forming "//net/". (The same doesn't happen for the root dir "c:" though.) - -Differential Revision: https://reviews.llvm.org/D91178 - -(cherry picked from commit 78d693faecf98718dadfa6e39f291e5999f380c7) ---- - libcxx/include/filesystem | 52 ++++++++++++++++--- - .../path.member/path.append.pass.cpp | 48 +++++++++++++++++ - 2 files changed, 92 insertions(+), 8 deletions(-) - -diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem -index eecf416e851c..201cecc0e8b2 100644 ---- a/libcxx/include/filesystem -+++ b/libcxx/include/filesystem -@@ -1006,14 +1006,44 @@ public: - return *this; - } - --private: -- template -- static bool __source_is_absolute(_ECharT __first_or_null) { -- return __is_separator(__first_or_null); -- } -- - public: - // appends -+#if defined(_LIBCPP_WIN32API) -+ path& operator/=(const path& __p) { -+ auto __p_root_name = __p.__root_name(); -+ auto __p_root_name_size = __p_root_name.size(); -+ if (__p.is_absolute() || -+ (!__p_root_name.empty() && __p_root_name != root_name())) { -+ __pn_ = __p.__pn_; -+ return *this; -+ } -+ if (__p.has_root_directory()) { -+ path __root_name_str = root_name(); -+ __pn_ = __root_name_str.native(); -+ __pn_ += __p.__pn_.substr(__p_root_name_size); -+ return *this; -+ } -+ if (has_filename() || (!has_root_directory() && is_absolute())) -+ __pn_ += preferred_separator; -+ __pn_ += __p.__pn_.substr(__p_root_name_size); -+ return *this; -+ } -+ template -+ _LIBCPP_INLINE_VISIBILITY _EnableIfPathable<_Source> -+ operator/=(const _Source& __src) { -+ return operator/=(path(__src)); -+ } -+ -+ template -+ _EnableIfPathable<_Source> append(const _Source& __src) { -+ return operator/=(path(__src)); -+ } -+ -+ template -+ path& append(_InputIt __first, _InputIt __last) { -+ return operator/=(path(__first, __last)); -+ } -+#else - path& operator/=(const path& __p) { - if (__p.is_absolute()) { - __pn_ = __p.__pn_; -@@ -1038,7 +1068,8 @@ public: - _EnableIfPathable<_Source> append(const _Source& __src) { - using _Traits = __is_pathable<_Source>; - using _CVT = _PathCVT<_SourceChar<_Source> >; -- if (__source_is_absolute(_Traits::__first_or_null(__src))) -+ bool __source_is_absolute = __is_separator(_Traits::__first_or_null(__src)); -+ if (__source_is_absolute) - __pn_.clear(); - else if (has_filename()) - __pn_ += preferred_separator; -@@ -1051,13 +1082,14 @@ public: - typedef typename iterator_traits<_InputIt>::value_type _ItVal; - static_assert(__can_convert_char<_ItVal>::value, "Must convertible"); - using _CVT = _PathCVT<_ItVal>; -- if (__first != __last && __source_is_absolute(*__first)) -+ if (__first != __last && __is_separator(*__first)) - __pn_.clear(); - else if (has_filename()) - __pn_ += preferred_separator; - _CVT::__append_range(__pn_, __first, __last); - return *this; - } -+#endif - - // concatenation - _LIBCPP_INLINE_VISIBILITY -@@ -1295,7 +1327,11 @@ public: - return string_type(__root_directory()); - } - _LIBCPP_INLINE_VISIBILITY path root_path() const { -+#if defined(_LIBCPP_WIN32API) -+ return string_type(__root_path_raw()); -+#else - return root_name().append(string_type(__root_directory())); -+#endif - } - _LIBCPP_INLINE_VISIBILITY path relative_path() const { - return string_type(__relative_path()); -diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -index eabd6f92da3c..ad9d06eb9849 100644 ---- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -@@ -63,6 +63,54 @@ const AppendOperatorTestcase Cases[] = - , {S("/p1"), S("/p2/"), S("/p2/")} - , {S("p1"), S(""), S("p1/")} - , {S("p1/"), S(""), S("p1/")} -+ -+ , {S("//host"), S("foo"), S("//host/foo")} -+ , {S("//host/"), S("foo"), S("//host/foo")} -+ , {S("//host"), S(""), S("//host/")} -+ -+#ifdef _WIN32 -+ , {S("foo"), S("C:/bar"), S("C:/bar")} -+ , {S("foo"), S("C:"), S("C:")} -+ -+ , {S("C:"), S(""), S("C:")} -+ , {S("C:foo"), S("/bar"), S("C:/bar")} -+ , {S("C:foo"), S("bar"), S("C:foo/bar")} -+ , {S("C:/foo"), S("bar"), S("C:/foo/bar")} -+ , {S("C:/foo"), S("/bar"), S("C:/bar")} -+ -+ , {S("C:foo"), S("C:/bar"), S("C:/bar")} -+ , {S("C:foo"), S("C:bar"), S("C:foo/bar")} -+ , {S("C:/foo"), S("C:/bar"), S("C:/bar")} -+ , {S("C:/foo"), S("C:bar"), S("C:/foo/bar")} -+ -+ , {S("C:foo"), S("c:/bar"), S("c:/bar")} -+ , {S("C:foo"), S("c:bar"), S("c:bar")} -+ , {S("C:/foo"), S("c:/bar"), S("c:/bar")} -+ , {S("C:/foo"), S("c:bar"), S("c:bar")} -+ -+ , {S("C:/foo"), S("D:bar"), S("D:bar")} -+#else -+ , {S("foo"), S("C:/bar"), S("foo/C:/bar")} -+ , {S("foo"), S("C:"), S("foo/C:")} -+ -+ , {S("C:"), S(""), S("C:/")} -+ , {S("C:foo"), S("/bar"), S("/bar")} -+ , {S("C:foo"), S("bar"), S("C:foo/bar")} -+ , {S("C:/foo"), S("bar"), S("C:/foo/bar")} -+ , {S("C:/foo"), S("/bar"), S("/bar")} -+ -+ , {S("C:foo"), S("C:/bar"), S("C:foo/C:/bar")} -+ , {S("C:foo"), S("C:bar"), S("C:foo/C:bar")} -+ , {S("C:/foo"), S("C:/bar"), S("C:/foo/C:/bar")} -+ , {S("C:/foo"), S("C:bar"), S("C:/foo/C:bar")} -+ -+ , {S("C:foo"), S("c:/bar"), S("C:foo/c:/bar")} -+ , {S("C:foo"), S("c:bar"), S("C:foo/c:bar")} -+ , {S("C:/foo"), S("c:/bar"), S("C:/foo/c:/bar")} -+ , {S("C:/foo"), S("c:bar"), S("C:/foo/c:bar")} -+ -+ , {S("C:/foo"), S("D:bar"), S("C:/foo/D:bar")} -+#endif - }; - - --- -2.25.1 - diff --git a/patches/llvm-project/0015-libcxx-Have-lexically_normal-return-the-path-with-pr.patch b/patches/llvm-project/0015-libcxx-Have-lexically_normal-return-the-path-with-pr.patch deleted file mode 100644 index df4930c..0000000 --- a/patches/llvm-project/0015-libcxx-Have-lexically_normal-return-the-path-with-pr.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6131abb23fc2990f9a869ef3d9c63bb0fd5ff464 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Thu, 5 Nov 2020 23:09:15 +0200 -Subject: [PATCH 15/25] [libcxx] Have lexically_normal return the path with - preferred separators - -Differential Revision: https://reviews.llvm.org/D91179 - -(cherry picked from commit 513463fd266f059864ce3c0236494cced5de0f56) ---- - libcxx/src/filesystem/operations.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 88a039f85021..a3b93b594a07 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1719,6 +1719,7 @@ path path::lexically_normal() const { - if (NeedTrailingSep) - Result /= PS(""); - -+ Result.make_preferred(); - return Result; - } - --- -2.25.1 - diff --git a/patches/llvm-project/0016-libcxx-Make-generic_-string-return-paths-with-forwar.patch b/patches/llvm-project/0016-libcxx-Make-generic_-string-return-paths-with-forwar.patch deleted file mode 100644 index 3d1e147..0000000 --- a/patches/llvm-project/0016-libcxx-Make-generic_-string-return-paths-with-forwar.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 415ea201cb19775f253dfb0cf8dc561891cff02d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Mon, 9 Nov 2020 11:45:13 +0200 -Subject: [PATCH 16/25] [libcxx] Make generic_*string return paths with forward - slashes on windows - -This matches what MS STL returns; in std::filesystem, forward slashes -are considered generic dir separators that are valid on all platforms. - -Differential Revision: https://reviews.llvm.org/D91181 - -(cherry picked from commit f4f5fb915104887fefa602cfcbd1d4fc8447d46b) ---- - libcxx/include/filesystem | 22 ++++++++++++++++--- - .../path.generic.obs/named_overloads.pass.cpp | 15 +++++++++---- - 2 files changed, 30 insertions(+), 7 deletions(-) - -diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem -index 201cecc0e8b2..19efca2d8fc2 100644 ---- a/libcxx/include/filesystem -+++ b/libcxx/include/filesystem -@@ -1193,7 +1193,12 @@ public: - #if defined(_LIBCPP_WIN32API) - _LIBCPP_INLINE_VISIBILITY _VSTD::wstring wstring() const { return __pn_; } - -- _VSTD::wstring generic_wstring() const { return __pn_; } -+ _VSTD::wstring generic_wstring() const { -+ _VSTD::wstring __s; -+ __s.resize(__pn_.size()); -+ _VSTD::replace_copy(__pn_.begin(), __pn_.end(), __s.begin(), '\\', '/'); -+ return __s; -+ } - - #if !defined(_LIBCPP_HAS_NO_LOCALIZATION) - template , -@@ -1230,13 +1235,24 @@ public: - class _Allocator = allocator<_ECharT> > - basic_string<_ECharT, _Traits, _Allocator> - generic_string(const _Allocator& __a = _Allocator()) const { -- return string<_ECharT, _Traits, _Allocator>(__a); -+ using _Str = basic_string<_ECharT, _Traits, _Allocator>; -+ _Str __s = string<_ECharT, _Traits, _Allocator>(__a); -+ // Note: This (and generic_u8string below) is slightly suboptimal as -+ // it iterates twice over the string; once to convert it to the right -+ // character type, and once to replace path delimiters. -+ _VSTD::replace(__s.begin(), __s.end(), -+ static_cast<_ECharT>('\\'), static_cast<_ECharT>('/')); -+ return __s; - } - - _VSTD::string generic_string() const { return generic_string(); } - _VSTD::u16string generic_u16string() const { return generic_string(); } - _VSTD::u32string generic_u32string() const { return generic_string(); } -- __u8_string generic_u8string() const { return u8string(); } -+ __u8_string generic_u8string() const { -+ __u8_string __s = u8string(); -+ _VSTD::replace(__s.begin(), __s.end(), '\\', '/'); -+ return __s; -+ } - #endif /* !_LIBCPP_HAS_NO_LOCALIZATION */ - #else /* _LIBCPP_WIN32API */ - -diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp -index 58c07e2feb70..d8991592efcf 100644 ---- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.generic.obs/named_overloads.pass.cpp -@@ -32,17 +32,24 @@ - #include "min_allocator.h" - #include "filesystem_test_helper.h" - --MultiStringType longString = MKSTR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); -+MultiStringType input = MKSTR("c:\\foo\\bar"); -+#ifdef _WIN32 -+// On windows, the generic_* accessors return a path with forward slashes -+MultiStringType ref = MKSTR("c:/foo/bar"); -+#else -+// On posix, the input string is returned as-is -+MultiStringType ref = MKSTR("c:\\foo\\bar"); -+#endif - - int main(int, char**) - { - using namespace fs; -- auto const& MS = longString; -- const char* value = longString; -+ auto const& MS = ref; -+ const char* value = input; - const path p(value); - { - std::string s = p.generic_string(); -- assert(s == value); -+ assert(s == (const char*)MS); - } - { - #if TEST_STD_VER > 17 && defined(__cpp_char8_t) --- -2.25.1 - diff --git a/patches/llvm-project/0017-SystemZ-ZOS-Guard-using-declaration-for-fchmodat.patch b/patches/llvm-project/0017-SystemZ-ZOS-Guard-using-declaration-for-fchmodat.patch deleted file mode 100644 index bfafb2a..0000000 --- a/patches/llvm-project/0017-SystemZ-ZOS-Guard-using-declaration-for-fchmodat.patch +++ /dev/null @@ -1,33 +0,0 @@ -From c8c08547b2d1e87391213846c7e17f5426a3dd48 Mon Sep 17 00:00:00 2001 -From: Zbigniew Sarbinowski -Date: Thu, 18 Feb 2021 14:49:46 +0000 -Subject: [PATCH 17/25] [SystemZ][ZOS] Guard using declaration for ::fchmodat - -The use of fchmodat() is beeing guarded but its using declaration is not. Let's use the same guard in both places to avoid compiler errors on platforms where `fchmodat` does not exist. - -Reviewed By: #libc, ldionne - -Differential Revision: https://reviews.llvm.org/D96303 - -(cherry picked from commit 25aa0d12445eed6e278489546d18fcb7a33cfaa6) ---- - libcxx/src/filesystem/posix_compat.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h -index 8062bd65ce00..f5c8ec39df2b 100644 ---- a/libcxx/src/filesystem/posix_compat.h -+++ b/libcxx/src/filesystem/posix_compat.h -@@ -487,7 +487,9 @@ int symlink_dir(const char *oldname, const char *newname) { - using ::chdir; - using ::close; - using ::fchmod; -+#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) - using ::fchmodat; -+#endif - using ::fstat; - using ::ftruncate; - using ::getcwd; --- -2.25.1 - diff --git a/patches/llvm-project/0018-libcxx-Enable-filesystem-by-default-for-mingw-target.patch b/patches/llvm-project/0018-libcxx-Enable-filesystem-by-default-for-mingw-target.patch deleted file mode 100644 index 9e32717..0000000 --- a/patches/llvm-project/0018-libcxx-Enable-filesystem-by-default-for-mingw-target.patch +++ /dev/null @@ -1,38 +0,0 @@ -From ff2e16fe051405232fbd9a09c406767b229d27ec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Thu, 5 Nov 2020 00:13:22 +0200 -Subject: [PATCH 18/25] [libcxx] Enable filesystem by default for mingw targets - -This feature can be built successfully for windows now. However, -the helper functions for __int128_t aren't available in MSVC -configurations, so don't enable it by default there yet. (See -https://reviews.llvm.org/D91139 for discussion on how to proceed -with things in MSVC environments.) - -Differential Revision: https://reviews.llvm.org/D97075 - -(cherry picked from commit 99fc4a65847a7020ae328e42a67e80cc29c1e762) ---- - libcxx/CMakeLists.txt | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt -index 9bf1a02f0908..b8716a34a325 100644 ---- a/libcxx/CMakeLists.txt -+++ b/libcxx/CMakeLists.txt -@@ -90,7 +90,11 @@ option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) - option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON) - option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) - set(ENABLE_FILESYSTEM_DEFAULT ON) --if (WIN32) -+if (WIN32 AND NOT MINGW) -+ # Filesystem is buildable for windows, but it requires __int128 helper -+ # functions, that currently are provided by libgcc or compiler_rt builtins. -+ # These are available in MinGW environments, but not currently in MSVC -+ # environments. - set(ENABLE_FILESYSTEM_DEFAULT OFF) - endif() - option(LIBCXX_ENABLE_FILESYSTEM "Build filesystem as part of the main libc++ library" --- -2.25.1 - diff --git a/patches/llvm-project/0019-libcxx-Explicitly-return-the-expected-error-code-in-.patch b/patches/llvm-project/0019-libcxx-Explicitly-return-the-expected-error-code-in-.patch deleted file mode 100644 index 29c79a6..0000000 --- a/patches/llvm-project/0019-libcxx-Explicitly-return-the-expected-error-code-in-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 69856f3e59b210249020504329e016c691f138e9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Fri, 18 Dec 2020 13:34:35 +0200 -Subject: [PATCH 19/25] [libcxx] Explicitly return the expected error code in - create_directories if the parent isn't a directory - -On windows, going ahead and actually trying to create the directory -doesn't return an error code that maps to -std::errc::not_a_directory in this case. - -This fixes two cases of - TEST_CHECK(ErrorIs(ec, std::errc::not_a_directory)) -in filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp -for windows (in testcases added in 59c72a70121567f7aee347e96b4ac8f3cfe9f4b2). - -Differential Revision: https://reviews.llvm.org/D97090 - -(cherry picked from commit c5e8f024dca9ddf6d14253fe2fcc5c4956de2d3c) ---- - libcxx/src/filesystem/operations.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index a3b93b594a07..bfc6c44d4ce4 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1022,7 +1022,8 @@ bool __create_directories(const path& p, error_code* ec) { - if (ec && *ec) { - return false; - } -- } -+ } else if (not is_directory(parent_st)) -+ return err.report(errc::not_a_directory); - } - return __create_directory(p, ec); - } --- -2.25.1 - diff --git a/patches/llvm-project/0020-libcxx-Avoid-infinite-recursion-in-create_directorie.patch b/patches/llvm-project/0020-libcxx-Avoid-infinite-recursion-in-create_directorie.patch deleted file mode 100644 index aa7a0e7..0000000 --- a/patches/llvm-project/0020-libcxx-Avoid-infinite-recursion-in-create_directorie.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 6c968da9f1e9281055d31f66c292f81de204924d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Sat, 27 Feb 2021 19:12:25 +0200 -Subject: [PATCH 20/25] [libcxx] Avoid infinite recursion in - create_directories, if the root directory doesn't exist - -Differential Revision: https://reviews.llvm.org/D97618 - -(cherry picked from commit 99c7b532946508efcf6cd978d86ee24b2a66d096) ---- - libcxx/src/filesystem/operations.cpp | 2 ++ - .../create_directories.pass.cpp | 14 ++++++++++++++ - 2 files changed, 16 insertions(+) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index bfc6c44d4ce4..7c77660538b5 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -1018,6 +1018,8 @@ bool __create_directories(const path& p, error_code* ec) { - if (not status_known(parent_st)) - return err.report(m_ec); - if (not exists(parent_st)) { -+ if (parent == p) -+ return err.report(errc::invalid_argument); - __create_directories(parent, ec); - if (ec && *ec) { - return false; -diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp -index 9ce450a0e48d..54820cad0f55 100644 ---- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp -@@ -138,4 +138,18 @@ TEST_CASE(dest_final_part_is_file) - TEST_CHECK(!exists(dir)); - } - -+#ifdef _WIN32 -+TEST_CASE(nonexistent_root) -+{ -+ std::error_code ec = GetTestEC(); -+ // If Q:\ doesn't exist, create_directories would try to recurse upwards -+ // to parent_path() until it finds a directory that does exist. As the -+ // whole path is the root name, parent_path() returns itself, and it -+ // would recurse indefinitely, unless the recursion is broken. -+ if (!exists("Q:\\")) -+ TEST_CHECK(fs::create_directories("Q:\\", ec) == false); -+ TEST_CHECK(fs::create_directories("\\\\nonexistentserver", ec) == false); -+} -+#endif -+ - TEST_SUITE_END() --- -2.25.1 - diff --git a/patches/llvm-project/0021-libcxx-Map-ERROR_BAD_PATHNAME-to-errc-no_such_file_o.patch b/patches/llvm-project/0021-libcxx-Map-ERROR_BAD_PATHNAME-to-errc-no_such_file_o.patch deleted file mode 100644 index 00f83fd..0000000 --- a/patches/llvm-project/0021-libcxx-Map-ERROR_BAD_PATHNAME-to-errc-no_such_file_o.patch +++ /dev/null @@ -1,46 +0,0 @@ -From cd87c3f6b36fd6cd991b8e3a3ac85dc208d55ea1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Sat, 27 Feb 2021 16:09:49 +0200 -Subject: [PATCH 21/25] [libcxx] Map ERROR_BAD_PATHNAME to - errc::no_such_file_or_directory on windows - -Opening a path like \\server (without a trailing share name and -path) produces this error, while opening e.g. \\server\share -(for a nonexistent server/share) produces ERROR_BAD_NETPATH (which -already is mapped). - -This happens in some testcases (in fs.op.proximate); as proximate() -calls weakly_canonical() on the inputs, weakly_canonical() checks -whether the path exists or not. When the error code wasn't recognized -(it mapped to errc::invalid_argument), the stat operation wasn't -conclusive and weakly_canonical() errored out. With the proper error -code mapping, this isn't considered an error, just a nonexistent -path, and weakly_canonical() can proceed. - -This roughly matches what MS STL does - it doesn't have -ERROR_BAD_PATHNAME in its error code mapping table, but it -checks for this error code specifically in the return of their -correspondence of the stat function. - -Differential Revision: https://reviews.llvm.org/D97619 - -(cherry picked from commit 29012ce986fcb24175f19317b4e2d119cd8cdbb2) ---- - libcxx/src/filesystem/operations.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 7c77660538b5..360643d4c241 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -411,6 +411,7 @@ errc __win_err_to_errc(int err) { - {ERROR_ACCESS_DENIED, errc::permission_denied}, - {ERROR_ALREADY_EXISTS, errc::file_exists}, - {ERROR_BAD_NETPATH, errc::no_such_file_or_directory}, -+ {ERROR_BAD_PATHNAME, errc::no_such_file_or_directory}, - {ERROR_BAD_UNIT, errc::no_such_device}, - {ERROR_BROKEN_PIPE, errc::broken_pipe}, - {ERROR_BUFFER_OVERFLOW, errc::filename_too_long}, --- -2.25.1 - diff --git a/patches/llvm-project/0022-libcxx-Avoid-intermediate-string-objects-for-substri.patch b/patches/llvm-project/0022-libcxx-Avoid-intermediate-string-objects-for-substri.patch deleted file mode 100644 index 695f7af..0000000 --- a/patches/llvm-project/0022-libcxx-Avoid-intermediate-string-objects-for-substri.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 497842a9ebb0ca1a6f871a07c0f4b4f1c700a798 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Thu, 11 Mar 2021 13:06:08 +0200 -Subject: [PATCH 22/25] [libcxx] Avoid intermediate string objects for - substrings in windows operator/= - -Check that appends with a path object doesn't do allocations, even -on windows. - -Suggested by Marek in D98398. The patch might apply without D98398 -(depending on how much of the diff context has to match), but doesn't -make much sense until after that patch has landed. - -Differential Revision: https://reviews.llvm.org/D98412 - -(cherry picked from commit 49173ca4db21e4d1576c2440b79ebff48c6c4156) ---- - libcxx/include/filesystem | 4 ++-- - .../class.path/path.member/path.append.pass.cpp | 9 +++++++++ - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/libcxx/include/filesystem b/libcxx/include/filesystem -index 19efca2d8fc2..2fc110715559 100644 ---- a/libcxx/include/filesystem -+++ b/libcxx/include/filesystem -@@ -1020,12 +1020,12 @@ public: - if (__p.has_root_directory()) { - path __root_name_str = root_name(); - __pn_ = __root_name_str.native(); -- __pn_ += __p.__pn_.substr(__p_root_name_size); -+ __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); - return *this; - } - if (has_filename() || (!has_root_directory() && is_absolute())) - __pn_ += preferred_separator; -- __pn_ += __p.__pn_.substr(__p_root_name_size); -+ __pn_ += __string_view(__p.__pn_).substr(__p_root_name_size); - return *this; - } - template -diff --git a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -index ad9d06eb9849..834d5e999abb 100644 ---- a/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp -@@ -189,6 +189,15 @@ void doAppendSourceAllocTest(AppendOperatorTestcase const& TC) - } - assert(PathEq(LHS, E)); - } -+ { -+ path LHS(L); PathReserve(LHS, ReserveSize); -+ path RHS(R); -+ { -+ DisableAllocationGuard g; -+ LHS /= RHS; -+ } -+ assert(PathEq(LHS, E)); -+ } - // input iterator - For non-native char types, appends needs to copy the - // iterator range into a contiguous block of memory before it can perform the - // code_cvt conversions. --- -2.25.1 - diff --git a/patches/llvm-project/0023-libcxx-Test-accessing-a-directory-on-windows-that-gi.patch b/patches/llvm-project/0023-libcxx-Test-accessing-a-directory-on-windows-that-gi.patch deleted file mode 100644 index b0f593e..0000000 --- a/patches/llvm-project/0023-libcxx-Test-accessing-a-directory-on-windows-that-gi.patch +++ /dev/null @@ -1,197 +0,0 @@ -From 9a1bb266e38b31c78de03abc2d41cdd3245595d0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Mon, 8 Mar 2021 12:03:30 +0200 -Subject: [PATCH 23/25] [libcxx] Test accessing a directory on windows that - gives "access denied" errors - -Fix handling of skip_permission_denied on windows; after converting -the return value of GetLastError() to a standard error_code, ec.value() -is in the standard errc range, not a native windows error code. This -was missed in 156180727d6c347eda3ba749730707acb8a48093. - -The directory "C:\System Volume Information" does seem to exist and -have these properties on most relevant contempory setups. - -Differential Revision: https://reviews.llvm.org/D98166 - -(cherry picked from commit e69c65d5c45557e140b13237448581d28bbd5846) ---- - libcxx/src/filesystem/directory_iterator.cpp | 3 ++- - .../directory_entry.cons/path.pass.cpp | 18 +++++++++++++ - .../directory_iterator.members/ctor.pass.cpp | 8 ++++++ - .../rec.dir.itr.members/ctor.pass.cpp | 8 ++++++ - .../fs.op.funcs/fs.op.exists/exists.pass.cpp | 14 ++++++++--- - libcxx/test/support/filesystem_test_helper.h | 25 +++++++++++++++++++ - 6 files changed, 72 insertions(+), 4 deletions(-) - -diff --git a/libcxx/src/filesystem/directory_iterator.cpp b/libcxx/src/filesystem/directory_iterator.cpp -index 2721dea5c98f..bb3653076bfc 100644 ---- a/libcxx/src/filesystem/directory_iterator.cpp -+++ b/libcxx/src/filesystem/directory_iterator.cpp -@@ -124,7 +124,8 @@ public: - ec = detail::make_windows_error(GetLastError()); - const bool ignore_permission_denied = - bool(opts & directory_options::skip_permission_denied); -- if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED) -+ if (ignore_permission_denied && -+ ec.value() == static_cast(errc::permission_denied)) - ec.clear(); - return; - } -diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp -index e3759e22b0ba..a118fae4d54b 100644 ---- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp -@@ -148,6 +148,23 @@ TEST_CASE(path_ctor_dne) { - - TEST_CASE(path_ctor_cannot_resolve) { - using namespace fs; -+#ifdef _WIN32 -+ // Windows doesn't support setting perms::none to trigger failures -+ // reading directories; test using a special inaccessible directory -+ // instead. -+ const path dir = GetWindowsInaccessibleDir(); -+ TEST_REQUIRE(!dir.empty()); -+ const path file = dir / "file"; -+ { -+ std::error_code ec = GetTestEC(); -+ directory_entry ent(file, ec); -+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory)); -+ TEST_CHECK(ent.path() == file); -+ } -+ { -+ TEST_CHECK_NO_THROW(directory_entry(file)); -+ } -+#else - scoped_test_env env; - const path dir = env.create_dir("dir"); - const path file = env.create_file("dir/file", 42); -@@ -179,6 +196,7 @@ TEST_CASE(path_ctor_cannot_resolve) { - TEST_CHECK_NO_THROW(directory_entry(sym_in_dir)); - TEST_CHECK_NO_THROW(directory_entry(sym_out_of_dir)); - } -+#endif - } - - TEST_SUITE_END() -diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp -index 48cf72a77b05..fae696613c75 100644 ---- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp -@@ -87,6 +87,13 @@ TEST_CASE(test_construction_from_bad_path) - TEST_CASE(access_denied_test_case) - { - using namespace fs; -+#ifdef _WIN32 -+ // Windows doesn't support setting perms::none to trigger failures -+ // reading directories; test using a special inaccessible directory -+ // instead. -+ const path testDir = GetWindowsInaccessibleDir(); -+ TEST_REQUIRE(!testDir.empty()); -+#else - scoped_test_env env; - path const testDir = env.make_env_path("dir1"); - path const testFile = testDir / "testFile"; -@@ -100,6 +107,7 @@ TEST_CASE(access_denied_test_case) - } - // Change the permissions so we can no longer iterate - permissions(testDir, perms::none); -+#endif - - // Check that the construction fails when skip_permissions_denied is - // not given. -diff --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp -index ddffaca39335..53ca5737ba31 100644 ---- a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp -@@ -88,6 +88,13 @@ TEST_CASE(test_construction_from_bad_path) - TEST_CASE(access_denied_test_case) - { - using namespace fs; -+#ifdef _WIN32 -+ // Windows doesn't support setting perms::none to trigger failures -+ // reading directories; test using a special inaccessible directory -+ // instead. -+ const path testDir = GetWindowsInaccessibleDir(); -+ TEST_REQUIRE(!testDir.empty()); -+#else - scoped_test_env env; - path const testDir = env.make_env_path("dir1"); - path const testFile = testDir / "testFile"; -@@ -102,6 +109,7 @@ TEST_CASE(access_denied_test_case) - - // Change the permissions so we can no longer iterate - permissions(testDir, perms::none); -+#endif - - // Check that the construction fails when skip_permissions_denied is - // not given. -diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp -index 581d9fe041a9..1b7131bbadff 100644 ---- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp -+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp -@@ -73,16 +73,24 @@ TEST_CASE(test_exist_not_found) - - TEST_CASE(test_exists_fails) - { -+#ifdef _WIN32 -+ // Windows doesn't support setting perms::none to trigger failures -+ // reading directories; test using a special inaccessible directory -+ // instead. -+ const path p = GetWindowsInaccessibleDir(); -+ TEST_REQUIRE(!p.empty()); -+#else - scoped_test_env env; - const path dir = env.create_dir("dir"); -- const path file = env.create_file("dir/file", 42); -+ const path p = env.create_file("dir/file", 42); - permissions(dir, perms::none); -+#endif - - std::error_code ec; -- TEST_CHECK(exists(file, ec) == false); -+ TEST_CHECK(exists(p, ec) == false); - TEST_CHECK(ec); - -- TEST_CHECK_THROW(filesystem_error, exists(file)); -+ TEST_CHECK_THROW(filesystem_error, exists(p)); - } - - TEST_CASE(test_name_too_long) { -diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h -index eeee3e935b8a..92c017f610fe 100644 ---- a/libcxx/test/support/filesystem_test_helper.h -+++ b/libcxx/test/support/filesystem_test_helper.h -@@ -690,4 +690,29 @@ struct ExceptionChecker { - - }; - -+inline fs::path GetWindowsInaccessibleDir() { -+ // Only makes sense on windows, but the code can be compiled for -+ // any platform. -+ const fs::path dir("C:\\System Volume Information"); -+ std::error_code ec; -+ const fs::path root("C:\\"); -+ fs::directory_iterator it(root, ec); -+ if (ec) -+ return fs::path(); -+ const fs::directory_iterator endIt{}; -+ while (it != endIt) { -+ const fs::directory_entry &ent = *it; -+ if (ent == dir) { -+ // Basic sanity checks on the directory_entry -+ if (!ent.exists()) -+ return fs::path(); -+ if (!ent.is_directory()) -+ return fs::path(); -+ return ent; -+ } -+ ++it; -+ } -+ return fs::path(); -+} -+ - #endif /* FILESYSTEM_TEST_HELPER_HPP */ --- -2.25.1 - diff --git a/patches/llvm-project/0024-libc-Improve-src-filesystem-s-formatting-of-paths.patch b/patches/llvm-project/0024-libc-Improve-src-filesystem-s-formatting-of-paths.patch deleted file mode 100644 index f08cd88..0000000 --- a/patches/llvm-project/0024-libc-Improve-src-filesystem-s-formatting-of-paths.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 7a94808f488301270f4a55ff7a17a8ebff3d388c Mon Sep 17 00:00:00 2001 -From: Arthur O'Dwyer -Date: Fri, 5 Mar 2021 20:13:35 -0500 -Subject: [PATCH 24/25] [libc++] Improve src/filesystem's formatting of paths. - -This is my attempt to merge D98077 (bugfix the format strings for -Windows paths, which use wchar_t not char) -and D96986 (replace C++ variadic templates with C-style varargs so that -`__attribute__((format(printf)))` can be applied, for better safety) -and D98065 (remove an unused function overload). - -The one intentional functional change here is in `__create_what`. -It now prints path1 and path2 in square-brackets _and_ double-quotes, -rather than just square-brackets. Prior to this patch, it would -print either path double-quoted if-and-only-if it was the empty -string. Now the double-quotes are always present. I doubt anybody's -code is relying on the current format, right? - -Differential Revision: https://reviews.llvm.org/D98097 ---- - libcxx/include/__config | 7 + - libcxx/src/filesystem/directory_iterator.cpp | 7 +- - libcxx/src/filesystem/filesystem_common.h | 146 ++++++++++--------- - libcxx/src/filesystem/operations.cpp | 25 ++-- - libcxx/test/support/filesystem_test_helper.h | 4 +- - 5 files changed, 101 insertions(+), 88 deletions(-) - -diff --git a/libcxx/include/__config b/libcxx/include/__config -index a3838c89e8e1..89838ca76c8c 100644 ---- a/libcxx/include/__config -+++ b/libcxx/include/__config -@@ -1445,6 +1445,13 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container( - # define _LIBCPP_INIT_PRIORITY_MAX - #endif - -+#if defined(__GNUC__) || defined(__clang__) -+#define _LIBCPP_FORMAT_PRINTF(a, b) \ -+ __attribute__((__format__(__printf__, a, b))) -+#else -+#define _LIBCPP_FORMAT_PRINTF(a, b) -+#endif -+ - #endif // __cplusplus - - #endif // _LIBCPP_CONFIG -diff --git a/libcxx/src/filesystem/directory_iterator.cpp b/libcxx/src/filesystem/directory_iterator.cpp -index bb3653076bfc..7b83ba9ff123 100644 ---- a/libcxx/src/filesystem/directory_iterator.cpp -+++ b/libcxx/src/filesystem/directory_iterator.cpp -@@ -273,7 +273,7 @@ directory_iterator& directory_iterator::__increment(error_code* ec) { - path root = move(__imp_->__root_); - __imp_.reset(); - if (m_ec) -- err.report(m_ec, "at root \"%s\"", root); -+ err.report(m_ec, "at root " PATH_CSTR_FMT, root.c_str()); - } - return *this; - } -@@ -360,7 +360,7 @@ void recursive_directory_iterator::__advance(error_code* ec) { - if (m_ec) { - path root = move(stack.top().__root_); - __imp_.reset(); -- err.report(m_ec, "at root \"%s\"", root); -+ err.report(m_ec, "at root " PATH_CSTR_FMT, root.c_str()); - } else { - __imp_.reset(); - } -@@ -405,7 +405,8 @@ bool recursive_directory_iterator::__try_recursion(error_code* ec) { - } else { - path at_ent = move(curr_it.__entry_.__p_); - __imp_.reset(); -- err.report(m_ec, "attempting recursion into \"%s\"", at_ent); -+ err.report(m_ec, "attempting recursion into " PATH_CSTR_FMT, -+ at_ent.c_str()); - } - } - return false; -diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h -index a4505171c3eb..df50a7de1059 100644 ---- a/libcxx/src/filesystem/filesystem_common.h -+++ b/libcxx/src/filesystem/filesystem_common.h -@@ -42,8 +42,10 @@ - - #if defined(_LIBCPP_WIN32API) - #define PS(x) (L##x) -+#define PATH_CSTR_FMT "\"%ls\"" - #else - #define PS(x) (x) -+#define PATH_CSTR_FMT "\"%s\"" - #endif - - _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -@@ -57,68 +59,47 @@ errc __win_err_to_errc(int err); - - namespace { - --static string format_string_imp(const char* msg, ...) { -- // we might need a second shot at this, so pre-emptivly make a copy -- struct GuardVAList { -- va_list& target; -- bool active = true; -- GuardVAList(va_list& tgt) : target(tgt), active(true) {} -- void clear() { -- if (active) -- va_end(target); -- active = false; -- } -- ~GuardVAList() { -- if (active) -- va_end(target); -- } -- }; -- va_list args; -- va_start(args, msg); -- GuardVAList args_guard(args); -- -- va_list args_cp; -- va_copy(args_cp, args); -- GuardVAList args_copy_guard(args_cp); -- -- std::string result; -- -- array local_buff; -- size_t size_with_null = local_buff.size(); -- auto ret = ::vsnprintf(local_buff.data(), size_with_null, msg, args_cp); -- -- args_copy_guard.clear(); -- -- // handle empty expansion -- if (ret == 0) -- return result; -- if (static_cast(ret) < size_with_null) { -- result.assign(local_buff.data(), static_cast(ret)); -- return result; -+static _LIBCPP_FORMAT_PRINTF(1, 0) string -+format_string_impl(const char* msg, va_list ap) { -+ array buf; -+ -+ va_list apcopy; -+ va_copy(apcopy, ap); -+ int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy); -+ va_end(apcopy); -+ -+ string result; -+ if (static_cast(ret) < buf.size()) { -+ result.assign(buf.data(), static_cast(ret)); -+ } else { -+ // we did not provide a long enough buffer on our first attempt. The -+ // return value is the number of bytes (excluding the null byte) that are -+ // needed for formatting. -+ size_t size_with_null = static_cast(ret) + 1; -+ result.__resize_default_init(size_with_null - 1); -+ ret = ::vsnprintf(&result[0], size_with_null, msg, ap); -+ _LIBCPP_ASSERT(static_cast(ret) == (size_with_null - 1), "TODO"); - } -- -- // we did not provide a long enough buffer on our first attempt. The -- // return value is the number of bytes (excluding the null byte) that are -- // needed for formatting. -- size_with_null = static_cast(ret) + 1; -- result.__resize_default_init(size_with_null - 1); -- ret = ::vsnprintf(&result[0], size_with_null, msg, args); -- _LIBCPP_ASSERT(static_cast(ret) == (size_with_null - 1), "TODO"); -- - return result; - } - --const path::value_type* unwrap(path::string_type const& s) { return s.c_str(); } --const path::value_type* unwrap(path const& p) { return p.native().c_str(); } --template --Arg const& unwrap(Arg const& a) { -- static_assert(!is_class::value, "cannot pass class here"); -- return a; --} -- --template --string format_string(const char* fmt, Args const&... args) { -- return format_string_imp(fmt, unwrap(args)...); -+static _LIBCPP_FORMAT_PRINTF(1, 2) string -+format_string(const char* msg, ...) { -+ string ret; -+ va_list ap; -+ va_start(ap, msg); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ try { -+#endif // _LIBCPP_NO_EXCEPTIONS -+ ret = format_string_impl(msg, ap); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ } catch (...) { -+ va_end(ap); -+ throw; -+ } -+#endif // _LIBCPP_NO_EXCEPTIONS -+ va_end(ap); -+ return ret; - } - - error_code capture_errno() { -@@ -190,14 +171,14 @@ struct ErrorHandler { - _LIBCPP_UNREACHABLE(); - } - -- template -- T report(const error_code& ec, const char* msg, Args const&... args) const { -+ _LIBCPP_FORMAT_PRINTF(3, 0) -+ void report_impl(const error_code& ec, const char* msg, va_list ap) const { - if (ec_) { - *ec_ = ec; -- return error_value(); -+ return; - } - string what = -- string("in ") + func_name_ + ": " + format_string(msg, args...); -+ string("in ") + func_name_ + ": " + format_string_impl(msg, ap); - switch (bool(p1_) + bool(p2_)) { - case 0: - __throw_filesystem_error(what, ec); -@@ -209,11 +190,44 @@ struct ErrorHandler { - _LIBCPP_UNREACHABLE(); - } - -- T report(errc const& err) const { return report(make_error_code(err)); } -+ _LIBCPP_FORMAT_PRINTF(3, 4) -+ T report(const error_code& ec, const char* msg, ...) const { -+ va_list ap; -+ va_start(ap, msg); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ try { -+#endif // _LIBCPP_NO_EXCEPTIONS -+ report_impl(ec, msg, ap); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ } catch (...) { -+ va_end(ap); -+ throw; -+ } -+#endif // _LIBCPP_NO_EXCEPTIONS -+ va_end(ap); -+ return error_value(); -+ } -+ -+ T report(errc const& err) const { -+ return report(make_error_code(err)); -+ } - -- template -- T report(errc const& err, const char* msg, Args const&... args) const { -- return report(make_error_code(err), msg, args...); -+ _LIBCPP_FORMAT_PRINTF(3, 4) -+ T report(errc const& err, const char* msg, ...) const { -+ va_list ap; -+ va_start(ap, msg); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ try { -+#endif // _LIBCPP_NO_EXCEPTIONS -+ report_impl(make_error_code(err), msg, ap); -+#ifndef _LIBCPP_NO_EXCEPTIONS -+ } catch (...) { -+ va_end(ap); -+ throw; -+ } -+#endif // _LIBCPP_NO_EXCEPTIONS -+ va_end(ap); -+ return error_value(); - } - - private: -diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp -index 360643d4c241..0cc4bad34c72 100644 ---- a/libcxx/src/filesystem/operations.cpp -+++ b/libcxx/src/filesystem/operations.cpp -@@ -666,27 +666,20 @@ _FilesystemClock::time_point _FilesystemClock::now() noexcept { - - filesystem_error::~filesystem_error() {} - --#if defined(_LIBCPP_WIN32API) --#define PS_FMT "%ls" --#else --#define PS_FMT "%s" --#endif -- - void filesystem_error::__create_what(int __num_paths) { - const char* derived_what = system_error::what(); - __storage_->__what_ = [&]() -> string { -- const path::value_type* p1 = path1().native().empty() ? PS("\"\"") : path1().c_str(); -- const path::value_type* p2 = path2().native().empty() ? PS("\"\"") : path2().c_str(); - switch (__num_paths) { -- default: -+ case 0: - return detail::format_string("filesystem error: %s", derived_what); - case 1: -- return detail::format_string("filesystem error: %s [" PS_FMT "]", derived_what, -- p1); -+ return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "]", -+ derived_what, path1().c_str()); - case 2: -- return detail::format_string("filesystem error: %s [" PS_FMT "] [" PS_FMT "]", -- derived_what, p1, p2); -+ return detail::format_string("filesystem error: %s [" PATH_CSTR_FMT "] [" PATH_CSTR_FMT "]", -+ derived_what, path1().c_str(), path2().c_str()); - } -+ _LIBCPP_UNREACHABLE(); - }(); - } - -@@ -1456,11 +1449,11 @@ path __temp_directory_path(error_code* ec) { - error_code m_ec; - file_status st = detail::posix_stat(p, &m_ec); - if (!status_known(st)) -- return err.report(m_ec, "cannot access path \"" PS_FMT "\"", p); -+ return err.report(m_ec, "cannot access path " PATH_CSTR_FMT, p.c_str()); - - if (!exists(st) || !is_directory(st)) -- return err.report(errc::not_a_directory, "path \"" PS_FMT "\" is not a directory", -- p); -+ return err.report(errc::not_a_directory, -+ "path " PATH_CSTR_FMT " is not a directory", p.c_str()); - - return p; - } -diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h -index 92c017f610fe..9d4062a987eb 100644 ---- a/libcxx/test/support/filesystem_test_helper.h -+++ b/libcxx/test/support/filesystem_test_helper.h -@@ -653,9 +653,7 @@ struct ExceptionChecker { - additional_msg = opt_message + ": "; - } - auto transform_path = [](const fs::path& p) { -- if (p.native().empty()) -- return std::string("\"\""); -- return p.string(); -+ return "\"" + p.string() + "\""; - }; - std::string format = [&]() -> std::string { - switch (num_paths) { --- -2.25.1 - diff --git a/patches/llvm-project/0025-libcxx-Make-the-visibility-attributes-consistent-for.patch b/patches/llvm-project/0025-libcxx-Make-the-visibility-attributes-consistent-for.patch deleted file mode 100644 index c83ab99..0000000 --- a/patches/llvm-project/0025-libcxx-Make-the-visibility-attributes-consistent-for.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 138e1609764e2226938df8cd6176303b41e4f325 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Martin=20Storsj=C3=B6?= -Date: Tue, 18 May 2021 14:45:08 +0000 -Subject: [PATCH 25/25] [libcxx] Make the visibility attributes consistent for - __narrow_to_utf8/__widen_from_utf8 - -Use the same visiblity attributes as for all other template -specializations in the same file; declare the specialization itself -using _LIBCPP_TYPE_VIS, and don't use _LIBCPP_EXPORTED_FROM_ABI on -the destructor. Methods that are excluded from the ABI are marked -with _LIBCPP_INLINE_VISIBILITY. - -This makes the vtable exported from DLL builds of libc++. Practically, -it doesn't make any difference for the CI configuration, but it -can make a difference in mingw setups. - -Differential Revision: https://reviews.llvm.org/D102717 - -(cherry picked from commit 3a6be27978aa3e83e9dc2ff2402b2569ce0686fd) ---- - libcxx/include/__locale | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/libcxx/include/__locale b/libcxx/include/__locale -index 77e5faab2676..c2800e88e8d2 100644 ---- a/libcxx/include/__locale -+++ b/libcxx/include/__locale -@@ -1484,14 +1484,14 @@ struct __narrow_to_utf8<8> - - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - template <> --struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<16> -+struct _LIBCPP_TYPE_VIS __narrow_to_utf8<16> - : public codecvt - { - _LIBCPP_INLINE_VISIBILITY - __narrow_to_utf8() : codecvt(1) {} - _LIBCPP_SUPPRESS_DEPRECATED_POP - -- _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); -+ ~__narrow_to_utf8(); - - template - _LIBCPP_INLINE_VISIBILITY -@@ -1520,14 +1520,14 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP - - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - template <> --struct _LIBCPP_TEMPLATE_VIS __narrow_to_utf8<32> -+struct _LIBCPP_TYPE_VIS __narrow_to_utf8<32> - : public codecvt - { - _LIBCPP_INLINE_VISIBILITY - __narrow_to_utf8() : codecvt(1) {} - _LIBCPP_SUPPRESS_DEPRECATED_POP - -- _LIBCPP_EXPORTED_FROM_ABI ~__narrow_to_utf8(); -+ ~__narrow_to_utf8(); - - template - _LIBCPP_INLINE_VISIBILITY -@@ -1578,14 +1578,14 @@ struct __widen_from_utf8<8> - - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - template <> --struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<16> -+struct _LIBCPP_TYPE_VIS __widen_from_utf8<16> - : public codecvt - { - _LIBCPP_INLINE_VISIBILITY - __widen_from_utf8() : codecvt(1) {} - _LIBCPP_SUPPRESS_DEPRECATED_POP - -- _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); -+ ~__widen_from_utf8(); - - template - _LIBCPP_INLINE_VISIBILITY -@@ -1614,14 +1614,14 @@ _LIBCPP_SUPPRESS_DEPRECATED_POP - - _LIBCPP_SUPPRESS_DEPRECATED_PUSH - template <> --struct _LIBCPP_TEMPLATE_VIS __widen_from_utf8<32> -+struct _LIBCPP_TYPE_VIS __widen_from_utf8<32> - : public codecvt - { - _LIBCPP_INLINE_VISIBILITY - __widen_from_utf8() : codecvt(1) {} - _LIBCPP_SUPPRESS_DEPRECATED_POP - -- _LIBCPP_EXPORTED_FROM_ABI ~__widen_from_utf8(); -+ ~__widen_from_utf8(); - - template - _LIBCPP_INLINE_VISIBILITY --- -2.25.1 -