aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/libcxx/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/libcxx/src')
-rw-r--r--contrib/llvm-project/libcxx/src/atomic.cpp8
-rw-r--r--contrib/llvm-project/libcxx/src/barrier.cpp12
-rw-r--r--contrib/llvm-project/libcxx/src/chrono.cpp155
-rw-r--r--contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp10
-rw-r--r--contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp63
-rw-r--r--contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h134
-rw-r--r--contrib/llvm-project/libcxx/src/filesystem/operations.cpp398
-rw-r--r--contrib/llvm-project/libcxx/src/include/config_elast.h4
-rw-r--r--contrib/llvm-project/libcxx/src/include/refstring.h25
-rw-r--r--contrib/llvm-project/libcxx/src/ios.cpp16
-rw-r--r--contrib/llvm-project/libcxx/src/ios.instantiations.cpp43
-rw-r--r--contrib/llvm-project/libcxx/src/iostream.cpp2
-rw-r--r--contrib/llvm-project/libcxx/src/locale.cpp210
-rw-r--r--contrib/llvm-project/libcxx/src/memory.cpp4
-rw-r--r--contrib/llvm-project/libcxx/src/new.cpp32
-rw-r--r--contrib/llvm-project/libcxx/src/optional.cpp1
-rw-r--r--contrib/llvm-project/libcxx/src/random.cpp21
-rw-r--r--contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp4
-rw-r--r--contrib/llvm-project/libcxx/src/thread.cpp18
19 files changed, 816 insertions, 344 deletions
diff --git a/contrib/llvm-project/libcxx/src/atomic.cpp b/contrib/llvm-project/libcxx/src/atomic.cpp
index 65d4837bb4a7..9ae1fb5199bf 100644
--- a/contrib/llvm-project/libcxx/src/atomic.cpp
+++ b/contrib/llvm-project/libcxx/src/atomic.cpp
@@ -13,14 +13,18 @@
#include <atomic>
#include <functional>
-#include <iostream>
-
#ifdef __linux__
#include <unistd.h>
#include <linux/futex.h>
#include <sys/syscall.h>
+// libc++ uses SYS_futex as a universal syscall name. However, on 32 bit architectures
+// with a 64 bit time_t, we need to specify SYS_futex_time64.
+#if !defined(SYS_futex) && defined(SYS_futex_time64)
+# define SYS_futex SYS_futex_time64
+#endif
+
#else // <- Add other operating systems here
// Baseline needs no new headers
diff --git a/contrib/llvm-project/libcxx/src/barrier.cpp b/contrib/llvm-project/libcxx/src/barrier.cpp
index c5e33cbba3bd..9ee476993b81 100644
--- a/contrib/llvm-project/libcxx/src/barrier.cpp
+++ b/contrib/llvm-project/libcxx/src/barrier.cpp
@@ -26,21 +26,15 @@ public:
} __tickets[64];
};
- ptrdiff_t& __expected;
- unique_ptr<char[]> __state_allocation;
- __state_t* __state;
+ ptrdiff_t& __expected;
+ unique_ptr<__state_t[]> __state;
_LIBCPP_HIDDEN
__barrier_algorithm_base(ptrdiff_t& __expected)
: __expected(__expected)
{
size_t const __count = (__expected + 1) >> 1;
- size_t const __size = sizeof(__state_t) * __count;
- size_t __allocation_size = __size + alignof(__state_t);
- __state_allocation = unique_ptr<char[]>(new char[__allocation_size]);
- void* __allocation = __state_allocation.get();
- void* const __state_ = align(alignof(__state_t), __size, __allocation, __allocation_size);
- __state = new (__state_) __barrier_algorithm_base::__state_t[__count];
+ __state = unique_ptr<__state_t[]>(new __state_t[__count]);
}
_LIBCPP_HIDDEN
bool __arrive(__barrier_phase_t __old_phase)
diff --git a/contrib/llvm-project/libcxx/src/chrono.cpp b/contrib/llvm-project/libcxx/src/chrono.cpp
index f0a5d50ddf77..085fbfde26c1 100644
--- a/contrib/llvm-project/libcxx/src/chrono.cpp
+++ b/contrib/llvm-project/libcxx/src/chrono.cpp
@@ -13,11 +13,15 @@
#include "include/apple_availability.h"
#if __has_include(<unistd.h>)
-#include <unistd.h>
+# include <unistd.h>
+#endif
+
+#if __has_include(<sys/time.h>)
+# include <sys/time.h> // for gettimeofday and timeval
#endif
#if !defined(__APPLE__) && _POSIX_TIMERS > 0
-#define _LIBCPP_USE_CLOCK_GETTIME
+# define _LIBCPP_USE_CLOCK_GETTIME
#endif
#if defined(_LIBCPP_WIN32API)
@@ -27,12 +31,12 @@
# if _WIN32_WINNT >= _WIN32_WINNT_WIN8
# include <winapifamily.h>
# endif
-#else
-# if !defined(CLOCK_REALTIME)
-# include <sys/time.h> // for gettimeofday and timeval
-# endif // !defined(CLOCK_REALTIME)
#endif // defined(_LIBCPP_WIN32API)
+#if __has_include(<mach/mach_time.h>)
+# include <mach/mach_time.h>
+#endif
+
#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
# pragma comment(lib, "rt")
#endif
@@ -42,14 +46,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
namespace chrono
{
+//
// system_clock
+//
-const bool system_clock::is_steady;
-
-system_clock::time_point
-system_clock::now() _NOEXCEPT
-{
#if defined(_LIBCPP_WIN32API)
+
+static system_clock::time_point __libcpp_system_clock_now() {
// FILETIME is in 100ns units
using filetime_duration =
_VSTD::chrono::duration<__int64,
@@ -60,31 +63,42 @@ system_clock::now() _NOEXCEPT
static _LIBCPP_CONSTEXPR const seconds nt_to_unix_epoch{11644473600};
FILETIME ft;
-#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#if _WIN32_WINNT >= _WIN32_WINNT_WIN8 && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
GetSystemTimePreciseAsFileTime(&ft);
#else
GetSystemTimeAsFileTime(&ft);
#endif
-#else
- GetSystemTimeAsFileTime(&ft);
-#endif
filetime_duration d{(static_cast<__int64>(ft.dwHighDateTime) << 32) |
static_cast<__int64>(ft.dwLowDateTime)};
- return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
-#else
-#if defined(CLOCK_REALTIME)
+ return system_clock::time_point(duration_cast<system_clock::duration>(d - nt_to_unix_epoch));
+}
+
+#elif defined(CLOCK_REALTIME) && defined(_LIBCPP_USE_CLOCK_GETTIME)
+
+static system_clock::time_point __libcpp_system_clock_now() {
struct timespec tp;
if (0 != clock_gettime(CLOCK_REALTIME, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
- return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
+ return system_clock::time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
+}
+
#else
+
+static system_clock::time_point __libcpp_system_clock_now() {
timeval tv;
gettimeofday(&tv, 0);
- return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
-#endif // CLOCK_REALTIME
+ return system_clock::time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
+}
+
#endif
+
+const bool system_clock::is_steady;
+
+system_clock::time_point
+system_clock::now() _NOEXCEPT
+{
+ return __libcpp_system_clock_now();
}
time_t
@@ -99,35 +113,85 @@ system_clock::from_time_t(time_t t) _NOEXCEPT
return system_clock::time_point(seconds(t));
}
-#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
+//
// steady_clock
//
// Warning: If this is not truly steady, then it is non-conforming. It is
// better for it to not exist and have the rest of libc++ use system_clock
// instead.
+//
-const bool steady_clock::is_steady;
+#ifndef _LIBCPP_HAS_NO_MONOTONIC_CLOCK
#if defined(__APPLE__)
-#if !defined(CLOCK_MONOTONIC_RAW)
-# error "Building libc++ on Apple platforms requires CLOCK_MONOTONIC_RAW"
+// TODO(ldionne):
+// This old implementation of steady_clock is retained until Chrome drops supports
+// for macOS < 10.12. The issue is that they link libc++ statically into their
+// application, which means that libc++ must support being built for such deployment
+// targets. See https://llvm.org/D74489 for details.
+#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101200) || \
+ (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+ (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 100000) || \
+ (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 30000)
+# define _LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME
#endif
+#if defined(_LIBCPP_USE_OLD_MACH_ABSOLUTE_TIME)
+
+// mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
+// nanoseconds since the computer booted up. MachInfo.numer and MachInfo.denom
+// are run time constants supplied by the OS. This clock has no relationship
+// to the Gregorian calendar. It's main use is as a high resolution timer.
+
+// MachInfo.numer / MachInfo.denom is often 1 on the latest equipment. Specialize
+// for that case as an optimization.
+
+static steady_clock::rep steady_simplified() {
+ return static_cast<steady_clock::rep>(mach_absolute_time());
+}
+static double compute_steady_factor() {
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ return static_cast<double>(MachInfo.numer) / MachInfo.denom;
+}
+
+static steady_clock::rep steady_full() {
+ static const double factor = compute_steady_factor();
+ return static_cast<steady_clock::rep>(mach_absolute_time() * factor);
+}
+
+typedef steady_clock::rep (*FP)();
+
+static FP init_steady_clock() {
+ mach_timebase_info_data_t MachInfo;
+ mach_timebase_info(&MachInfo);
+ if (MachInfo.numer == MachInfo.denom)
+ return &steady_simplified;
+ return &steady_full;
+}
+
+static steady_clock::time_point __libcpp_steady_clock_now() {
+ static FP fp = init_steady_clock();
+ return steady_clock::time_point(steady_clock::duration(fp()));
+}
+
+#else // vvvvv default behavior for Apple platforms vvvvv
+
// On Apple platforms, only CLOCK_UPTIME_RAW, CLOCK_MONOTONIC_RAW or
// mach_absolute_time are able to time functions in the nanosecond range.
// Furthermore, only CLOCK_MONOTONIC_RAW is truly monotonic, because it
// also counts cycles when the system is asleep. Thus, it is the only
// acceptable implementation of steady_clock.
-steady_clock::time_point
-steady_clock::now() _NOEXCEPT
-{
+static steady_clock::time_point __libcpp_steady_clock_now() {
struct timespec tp;
if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC_RAW) failed");
- return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+ return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
+#endif
+
#elif defined(_LIBCPP_WIN32API)
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
@@ -138,36 +202,43 @@ steady_clock::now() _NOEXCEPT
static LARGE_INTEGER
__QueryPerformanceFrequency()
{
- LARGE_INTEGER val;
- (void) QueryPerformanceFrequency(&val);
- return val;
+ LARGE_INTEGER val;
+ (void) QueryPerformanceFrequency(&val);
+ return val;
}
-steady_clock::time_point
-steady_clock::now() _NOEXCEPT
-{
+static steady_clock::time_point __libcpp_steady_clock_now() {
static const LARGE_INTEGER freq = __QueryPerformanceFrequency();
LARGE_INTEGER counter;
(void) QueryPerformanceCounter(&counter);
- return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
+ auto seconds = counter.QuadPart / freq.QuadPart;
+ auto fractions = counter.QuadPart % freq.QuadPart;
+ auto dur = seconds * nano::den + fractions * nano::den / freq.QuadPart;
+ return steady_clock::time_point(steady_clock::duration(dur));
}
#elif defined(CLOCK_MONOTONIC)
-steady_clock::time_point
-steady_clock::now() _NOEXCEPT
-{
+static steady_clock::time_point __libcpp_steady_clock_now() {
struct timespec tp;
if (0 != clock_gettime(CLOCK_MONOTONIC, &tp))
__throw_system_error(errno, "clock_gettime(CLOCK_MONOTONIC) failed");
- return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+ return steady_clock::time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
}
#else
-# error "Monotonic clock not implemented"
+# error "Monotonic clock not implemented on this platform"
#endif
+const bool steady_clock::is_steady;
+
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
+ return __libcpp_steady_clock_now();
+}
+
#endif // !_LIBCPP_HAS_NO_MONOTONIC_CLOCK
}
diff --git a/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp b/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp
index 68c5bc99cc72..1304ef3df78f 100644
--- a/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp
+++ b/contrib/llvm-project/libcxx/src/experimental/memory_resource.cpp
@@ -76,16 +76,6 @@ union ResourceInitHelper {
~ResourceInitHelper() {}
};
-// Detect if the init_priority attribute is supported.
-#if (defined(_LIBCPP_COMPILER_GCC) && defined(__APPLE__)) \
- || defined(_LIBCPP_COMPILER_MSVC)
-// GCC on Apple doesn't support the init priority attribute,
-// and MSVC doesn't support any GCC attributes.
-# define _LIBCPP_INIT_PRIORITY_MAX
-#else
-# define _LIBCPP_INIT_PRIORITY_MAX __attribute__((init_priority(101)))
-#endif
-
// When compiled in C++14 this initialization should be a constant expression.
// Only in C++11 is "init_priority" needed to ensure initialization order.
#if _LIBCPP_STD_VER > 11
diff --git a/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp b/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp
index e8941b3494b3..2721dea5c98f 100644
--- a/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp
+++ b/contrib/llvm-project/libcxx/src/filesystem/directory_iterator.cpp
@@ -10,6 +10,7 @@
#include "__config"
#if defined(_LIBCPP_WIN32API)
#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
#include <windows.h>
#else
#include <dirent.h>
@@ -72,16 +73,20 @@ static pair<string_view, file_type> posix_readdir(DIR* dir_stream,
}
}
#else
+// defined(_LIBCPP_WIN32API)
-static file_type get_file_type(const WIN32_FIND_DATA& data) {
- //auto attrs = data.dwFileAttributes;
- // FIXME(EricWF)
- return file_type::unknown;
+static file_type get_file_type(const WIN32_FIND_DATAW& data) {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
+ data.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
+ return file_type::symlink;
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return file_type::directory;
+ return file_type::regular;
}
-static uintmax_t get_file_size(const WIN32_FIND_DATA& data) {
- return (data.nFileSizeHigh * (MAXDWORD + 1)) + data.nFileSizeLow;
+static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) {
+ return (static_cast<uint64_t>(data.nFileSizeHigh) << 32) + data.nFileSizeLow;
}
-static file_time_type get_write_time(const WIN32_FIND_DATA& data) {
+static file_time_type get_write_time(const WIN32_FIND_DATAW& data) {
ULARGE_INTEGER tmp;
const FILETIME& time = data.ftLastWriteTime;
tmp.u.LowPart = time.dwLowDateTime;
@@ -110,15 +115,21 @@ public:
__dir_stream(const path& root, directory_options opts, error_code& ec)
: __stream_(INVALID_HANDLE_VALUE), __root_(root) {
- __stream_ = ::FindFirstFile(root.c_str(), &__data_);
+ if (root.native().empty()) {
+ ec = make_error_code(errc::no_such_file_or_directory);
+ return;
+ }
+ __stream_ = ::FindFirstFileW((root / "*").c_str(), &__data_);
if (__stream_ == INVALID_HANDLE_VALUE) {
- ec = error_code(::GetLastError(), generic_category());
+ 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)
ec.clear();
return;
}
+ if (!assign())
+ advance(ec);
}
~__dir_stream() noexcept {
@@ -130,35 +141,39 @@ public:
bool good() const noexcept { return __stream_ != INVALID_HANDLE_VALUE; }
bool advance(error_code& ec) {
- while (::FindNextFile(__stream_, &__data_)) {
- if (!strcmp(__data_.cFileName, ".") || strcmp(__data_.cFileName, ".."))
- continue;
- // FIXME: Cache more of this
- //directory_entry::__cached_data cdata;
- //cdata.__type_ = get_file_type(__data_);
- //cdata.__size_ = get_file_size(__data_);
- //cdata.__write_time_ = get_write_time(__data_);
- __entry_.__assign_iter_entry(
- __root_ / __data_.cFileName,
- directory_entry::__create_iter_result(detail::get_file_type(__data)));
- return true;
+ while (::FindNextFileW(__stream_, &__data_)) {
+ if (assign())
+ return true;
}
- ec = error_code(::GetLastError(), generic_category());
close();
return false;
}
+ bool assign() {
+ if (!wcscmp(__data_.cFileName, L".") || !wcscmp(__data_.cFileName, L".."))
+ return false;
+ // FIXME: Cache more of this
+ //directory_entry::__cached_data cdata;
+ //cdata.__type_ = get_file_type(__data_);
+ //cdata.__size_ = get_file_size(__data_);
+ //cdata.__write_time_ = get_write_time(__data_);
+ __entry_.__assign_iter_entry(
+ __root_ / __data_.cFileName,
+ directory_entry::__create_iter_result(detail::get_file_type(__data_)));
+ return true;
+ }
+
private:
error_code close() noexcept {
error_code ec;
if (!::FindClose(__stream_))
- ec = error_code(::GetLastError(), generic_category());
+ ec = detail::make_windows_error(GetLastError());
__stream_ = INVALID_HANDLE_VALUE;
return ec;
}
HANDLE __stream_{INVALID_HANDLE_VALUE};
- WIN32_FIND_DATA __data_;
+ WIN32_FIND_DATAW __data_;
public:
path __root_;
diff --git a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h
index fe5c42f5e6d0..e0fdbccf96b1 100644
--- a/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h
+++ b/contrib/llvm-project/libcxx/src/filesystem/filesystem_common.h
@@ -13,14 +13,17 @@
#include "filesystem"
#include "array"
#include "chrono"
-#include "cstdlib"
#include "climits"
-
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/time.h> // for ::utimes as used in __last_write_time
-#include <fcntl.h> /* values for fchmodat */
+#include "cstdlib"
+#include "ctime"
+
+#if !defined(_LIBCPP_WIN32API)
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/statvfs.h>
+# include <sys/time.h> // for ::utimes as used in __last_write_time
+# include <fcntl.h> /* values for fchmodat */
+#endif
#include "../include/apple_availability.h"
@@ -37,9 +40,21 @@
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
+#if defined(_LIBCPP_WIN32API)
+#define PS(x) (L##x)
+#else
+#define PS(x) (x)
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace detail {
+
+#if defined(_LIBCPP_WIN32API)
+// Non anonymous, to allow access from two translation units.
+errc __win_err_to_errc(int err);
+#endif
+
namespace {
static string format_string_imp(const char* msg, ...) {
@@ -47,7 +62,7 @@ static string format_string_imp(const char* msg, ...) {
struct GuardVAList {
va_list& target;
bool active = true;
- GuardVAList(va_list& target) : target(target), active(true) {}
+ GuardVAList(va_list& tgt) : target(tgt), active(true) {}
void clear() {
if (active)
va_end(target);
@@ -93,8 +108,8 @@ static string format_string_imp(const char* msg, ...) {
return result;
}
-const char* unwrap(string const& s) { return s.c_str(); }
-const char* unwrap(path const& p) { return p.native().c_str(); }
+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 <class Arg>
Arg const& unwrap(Arg const& a) {
static_assert(!is_class<Arg>::value, "cannot pass class here");
@@ -111,6 +126,12 @@ error_code capture_errno() {
return error_code(errno, generic_category());
}
+#if defined(_LIBCPP_WIN32API)
+error_code make_windows_error(int err) {
+ return make_error_code(__win_err_to_errc(err));
+}
+#endif
+
template <class T>
T error_value();
template <>
@@ -119,6 +140,12 @@ template <>
bool error_value<bool>() {
return false;
}
+#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__
+template <>
+size_t error_value<size_t>() {
+ return size_t(-1);
+}
+#endif
template <>
uintmax_t error_value<uintmax_t>() {
return uintmax_t(-1);
@@ -134,50 +161,50 @@ path error_value<path>() {
template <class T>
struct ErrorHandler {
- const char* func_name;
- error_code* ec = nullptr;
- const path* p1 = nullptr;
- const path* p2 = nullptr;
+ const char* func_name_;
+ error_code* ec_ = nullptr;
+ const path* p1_ = nullptr;
+ const path* p2_ = nullptr;
ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr,
const path* p2 = nullptr)
- : func_name(fname), ec(ec), p1(p1), p2(p2) {
- if (ec)
- ec->clear();
+ : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) {
+ if (ec_)
+ ec_->clear();
}
- T report(const error_code& m_ec) const {
- if (ec) {
- *ec = m_ec;
+ T report(const error_code& ec) const {
+ if (ec_) {
+ *ec_ = ec;
return error_value<T>();
}
- string what = string("in ") + func_name;
- switch (bool(p1) + bool(p2)) {
+ string what = string("in ") + func_name_;
+ switch (bool(p1_) + bool(p2_)) {
case 0:
- __throw_filesystem_error(what, m_ec);
+ __throw_filesystem_error(what, ec);
case 1:
- __throw_filesystem_error(what, *p1, m_ec);
+ __throw_filesystem_error(what, *p1_, ec);
case 2:
- __throw_filesystem_error(what, *p1, *p2, m_ec);
+ __throw_filesystem_error(what, *p1_, *p2_, ec);
}
_LIBCPP_UNREACHABLE();
}
template <class... Args>
- T report(const error_code& m_ec, const char* msg, Args const&... args) const {
- if (ec) {
- *ec = m_ec;
+ T report(const error_code& ec, const char* msg, Args const&... args) const {
+ if (ec_) {
+ *ec_ = ec;
return error_value<T>();
}
string what =
- string("in ") + func_name + ": " + format_string(msg, args...);
- switch (bool(p1) + bool(p2)) {
+ string("in ") + func_name_ + ": " + format_string(msg, args...);
+ switch (bool(p1_) + bool(p2_)) {
case 0:
- __throw_filesystem_error(what, m_ec);
+ __throw_filesystem_error(what, ec);
case 1:
- __throw_filesystem_error(what, *p1, m_ec);
+ __throw_filesystem_error(what, *p1_, ec);
case 2:
- __throw_filesystem_error(what, *p1, *p2, m_ec);
+ __throw_filesystem_error(what, *p1_, *p2_, ec);
}
_LIBCPP_UNREACHABLE();
}
@@ -197,8 +224,9 @@ private:
using chrono::duration;
using chrono::duration_cast;
-using TimeSpec = struct ::timespec;
-using StatT = struct ::stat;
+using TimeSpec = struct timespec;
+using TimeVal = struct timeval;
+using StatT = struct stat;
template <class FileTimeT, class TimeT,
bool IsFloat = is_floating_point<typename FileTimeT::rep>::value>
@@ -380,26 +408,38 @@ public:
using fs_time = time_util<file_time_type, time_t, TimeSpec>;
#if defined(__APPLE__)
-TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
-TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; }
+inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; }
+#elif defined(__MVS__)
+inline TimeSpec extract_mtime(StatT const& st) {
+ TimeSpec TS = {st.st_mtime, 0};
+ return TS;
+}
+inline TimeSpec extract_atime(StatT const& st) {
+ TimeSpec TS = {st.st_atime, 0};
+ return TS;
+}
#else
-TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
-TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
+inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; }
+inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
#endif
-// allow the utimes implementation to compile even it we're not going
-// to use it.
-
-bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
- error_code& ec) {
+inline TimeVal make_timeval(TimeSpec const& ts) {
using namespace chrono;
auto Convert = [](long nsec) {
- using int_type = decltype(std::declval< ::timeval>().tv_usec);
+ using int_type = decltype(std::declval<TimeVal>().tv_usec);
auto dur = duration_cast<microseconds>(nanoseconds(nsec)).count();
return static_cast<int_type>(dur);
};
- struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)},
- {TS[1].tv_sec, Convert(TS[1].tv_nsec)}};
+ TimeVal TV = {};
+ TV.tv_sec = ts.tv_sec;
+ TV.tv_usec = Convert(ts.tv_nsec);
+ return TV;
+}
+
+inline bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
+ TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])};
if (::utimes(p.c_str(), ConvertedTS) == -1) {
ec = capture_errno();
return true;
diff --git a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp
index 5c98671feeed..50a895dc2fae 100644
--- a/contrib/llvm-project/libcxx/src/filesystem/operations.cpp
+++ b/contrib/llvm-project/libcxx/src/filesystem/operations.cpp
@@ -9,8 +9,6 @@
#include "filesystem"
#include "array"
#include "iterator"
-#include "fstream"
-#include "random" /* for unique_path */
#include "string_view"
#include "type_traits"
#include "vector"
@@ -19,40 +17,51 @@
#include "filesystem_common.h"
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
+#if defined(_LIBCPP_WIN32API)
+# define WIN32_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#else
+# include <unistd.h>
+# include <sys/stat.h>
+# include <sys/statvfs.h>
+#endif
#include <time.h>
#include <fcntl.h> /* values for fchmodat */
-#if defined(__linux__)
-#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
-#include <sys/sendfile.h>
-#define _LIBCPP_USE_SENDFILE
-#endif
+#if __has_include(<sys/sendfile.h>)
+# include <sys/sendfile.h>
+# define _LIBCPP_FILESYSTEM_USE_SENDFILE
#elif defined(__APPLE__) || __has_include(<copyfile.h>)
-#include <copyfile.h>
-#define _LIBCPP_USE_COPYFILE
+# include <copyfile.h>
+# define _LIBCPP_FILESYSTEM_USE_COPYFILE
+#else
+# include "fstream"
+# define _LIBCPP_FILESYSTEM_USE_FSTREAM
#endif
#if !defined(CLOCK_REALTIME)
-#include <sys/time.h> // for gettimeofday and timeval
-#endif // !defined(CLOCK_REALTIME)
-
-#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
-#pragma comment(lib, "rt")
+# include <sys/time.h> // for gettimeofday and timeval
#endif
-#if defined(_LIBCPP_COMPILER_GCC)
-#if _GNUC_VER < 500
-#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
-#endif
+#if defined(__ELF__) && defined(_LIBCPP_LINK_RT_LIB)
+# pragma comment(lib, "rt")
#endif
_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
namespace {
+
+bool isSeparator(path::value_type C) {
+ if (C == '/')
+ return true;
+#if defined(_LIBCPP_WIN32API)
+ if (C == '\\')
+ return true;
+#endif
+ return false;
+}
+
namespace parser {
using string_view_t = path::__string_view;
@@ -179,11 +188,14 @@ public:
switch (State) {
case PS_BeforeBegin:
case PS_AtEnd:
- return "";
+ return PS("");
case PS_InRootDir:
- return "/";
+ if (RawEntry[0] == '\\')
+ return PS("\\");
+ else
+ return PS("/");
case PS_InTrailingSep:
- return "";
+ return PS("");
case PS_InRootName:
case PS_InFilenames:
return RawEntry;
@@ -270,29 +282,29 @@ private:
}
PosPtr consumeSeparator(PosPtr P, PosPtr End) const noexcept {
- if (P == End || *P != '/')
+ if (P == End || !isSeparator(*P))
return nullptr;
const int Inc = P < End ? 1 : -1;
P += Inc;
- while (P != End && *P == '/')
+ while (P != End && isSeparator(*P))
P += Inc;
return P;
}
PosPtr consumeName(PosPtr P, PosPtr End) const noexcept {
- if (P == End || *P == '/')
+ if (P == End || isSeparator(*P))
return nullptr;
const int Inc = P < End ? 1 : -1;
P += Inc;
- while (P != End && *P != '/')
+ while (P != End && !isSeparator(*P))
P += Inc;
return P;
}
};
string_view_pair separate_filename(string_view_t const& s) {
- if (s == "." || s == ".." || s.empty())
- return string_view_pair{s, ""};
+ if (s == PS(".") || s == PS("..") || s.empty())
+ return string_view_pair{s, PS("")};
auto pos = s.find_last_of('.');
if (pos == string_view_t::npos || pos == 0)
return string_view_pair{s, string_view_t{}};
@@ -308,6 +320,73 @@ string_view_t createView(PosPtr S, PosPtr E) noexcept {
// POSIX HELPERS
+#if defined(_LIBCPP_WIN32API)
+namespace detail {
+
+errc __win_err_to_errc(int err) {
+ constexpr struct {
+ DWORD win;
+ errc errc;
+ } win_error_mapping[] = {
+ {ERROR_ACCESS_DENIED, errc::permission_denied},
+ {ERROR_ALREADY_EXISTS, errc::file_exists},
+ {ERROR_BAD_NETPATH, 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},
+ {ERROR_BUSY, errc::device_or_resource_busy},
+ {ERROR_BUSY_DRIVE, errc::device_or_resource_busy},
+ {ERROR_CANNOT_MAKE, errc::permission_denied},
+ {ERROR_CANTOPEN, errc::io_error},
+ {ERROR_CANTREAD, errc::io_error},
+ {ERROR_CANTWRITE, errc::io_error},
+ {ERROR_CURRENT_DIRECTORY, errc::permission_denied},
+ {ERROR_DEV_NOT_EXIST, errc::no_such_device},
+ {ERROR_DEVICE_IN_USE, errc::device_or_resource_busy},
+ {ERROR_DIR_NOT_EMPTY, errc::directory_not_empty},
+ {ERROR_DIRECTORY, errc::invalid_argument},
+ {ERROR_DISK_FULL, errc::no_space_on_device},
+ {ERROR_FILE_EXISTS, errc::file_exists},
+ {ERROR_FILE_NOT_FOUND, errc::no_such_file_or_directory},
+ {ERROR_HANDLE_DISK_FULL, errc::no_space_on_device},
+ {ERROR_INVALID_ACCESS, errc::permission_denied},
+ {ERROR_INVALID_DRIVE, errc::no_such_device},
+ {ERROR_INVALID_FUNCTION, errc::function_not_supported},
+ {ERROR_INVALID_HANDLE, errc::invalid_argument},
+ {ERROR_INVALID_NAME, errc::no_such_file_or_directory},
+ {ERROR_INVALID_PARAMETER, errc::invalid_argument},
+ {ERROR_LOCK_VIOLATION, errc::no_lock_available},
+ {ERROR_LOCKED, errc::no_lock_available},
+ {ERROR_NEGATIVE_SEEK, errc::invalid_argument},
+ {ERROR_NOACCESS, errc::permission_denied},
+ {ERROR_NOT_ENOUGH_MEMORY, errc::not_enough_memory},
+ {ERROR_NOT_READY, errc::resource_unavailable_try_again},
+ {ERROR_NOT_SAME_DEVICE, errc::cross_device_link},
+ {ERROR_NOT_SUPPORTED, errc::not_supported},
+ {ERROR_OPEN_FAILED, errc::io_error},
+ {ERROR_OPEN_FILES, errc::device_or_resource_busy},
+ {ERROR_OPERATION_ABORTED, errc::operation_canceled},
+ {ERROR_OUTOFMEMORY, errc::not_enough_memory},
+ {ERROR_PATH_NOT_FOUND, errc::no_such_file_or_directory},
+ {ERROR_READ_FAULT, errc::io_error},
+ {ERROR_REPARSE_TAG_INVALID, errc::invalid_argument},
+ {ERROR_RETRY, errc::resource_unavailable_try_again},
+ {ERROR_SEEK, errc::io_error},
+ {ERROR_SHARING_VIOLATION, errc::permission_denied},
+ {ERROR_TOO_MANY_OPEN_FILES, errc::too_many_files_open},
+ {ERROR_WRITE_FAULT, errc::io_error},
+ {ERROR_WRITE_PROTECT, errc::permission_denied},
+ };
+
+ for (const auto &pair : win_error_mapping)
+ if (pair.win == static_cast<DWORD>(err))
+ return pair.errc;
+ return errc::invalid_argument;
+}
+
+} // namespace detail
+#endif
+
namespace detail {
namespace {
@@ -503,19 +582,25 @@ _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 char* p1 = path1().native().empty() ? "\"\"" : path1().c_str();
- const char* p2 = path2().native().empty() ? "\"\"" : path2().c_str();
+ 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:
return detail::format_string("filesystem error: %s", derived_what);
case 1:
- return detail::format_string("filesystem error: %s [%s]", derived_what,
+ return detail::format_string("filesystem error: %s [" PS_FMT "]", derived_what,
p1);
case 2:
- return detail::format_string("filesystem error: %s [%s] [%s]",
+ return detail::format_string("filesystem error: %s [" PS_FMT "] [" PS_FMT "]",
derived_what, p1, p2);
}
}();
@@ -542,14 +627,18 @@ path __canonical(path const& orig_p, error_code* ec) {
ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
path p = __do_absolute(orig_p, &cwd, ec);
-#if _POSIX_VERSION >= 200112
+#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112
std::unique_ptr<char, decltype(&::free)>
hold(::realpath(p.c_str(), nullptr), &::free);
if (hold.get() == nullptr)
return err.report(capture_errno());
return {hold.get()};
#else
- char buff[PATH_MAX + 1];
+ #if defined(__MVS__) && !defined(PATH_MAX)
+ char buff[ _XOPEN_PATH_MAX + 1 ];
+ #else
+ char buff[PATH_MAX + 1];
+ #endif
char* ret;
if ((ret = ::realpath(p.c_str(), buff)) == nullptr)
return err.report(capture_errno());
@@ -646,96 +735,83 @@ void __copy(const path& from, const path& to, copy_options options,
namespace detail {
namespace {
-#ifdef _LIBCPP_USE_SENDFILE
-bool copy_file_impl_sendfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
- error_code& ec) {
-
- size_t count = read_fd.get_stat().st_size;
- do {
- ssize_t res;
- if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) {
- ec = capture_errno();
- return false;
- }
- count -= res;
- } while (count > 0);
-
- ec.clear();
+#if defined(_LIBCPP_FILESYSTEM_USE_SENDFILE)
+ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) {
+ size_t count = read_fd.get_stat().st_size;
+ do {
+ ssize_t res;
+ if ((res = ::sendfile(write_fd.fd, read_fd.fd, nullptr, count)) == -1) {
+ ec = capture_errno();
+ return false;
+ }
+ count -= res;
+ } while (count > 0);
- return true;
-}
-#elif defined(_LIBCPP_USE_COPYFILE)
-bool copy_file_impl_copyfile(FileDescriptor& read_fd, FileDescriptor& write_fd,
- error_code& ec) {
- struct CopyFileState {
- copyfile_state_t state;
- CopyFileState() { state = copyfile_state_alloc(); }
- ~CopyFileState() { copyfile_state_free(state); }
-
- private:
- CopyFileState(CopyFileState const&) = delete;
- CopyFileState& operator=(CopyFileState const&) = delete;
- };
+ ec.clear();
- CopyFileState cfs;
- if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) {
- ec = capture_errno();
- return false;
+ return true;
}
+#elif defined(_LIBCPP_FILESYSTEM_USE_COPYFILE)
+ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) {
+ struct CopyFileState {
+ copyfile_state_t state;
+ CopyFileState() { state = copyfile_state_alloc(); }
+ ~CopyFileState() { copyfile_state_free(state); }
- ec.clear();
- return true;
-}
-#endif
+ private:
+ CopyFileState(CopyFileState const&) = delete;
+ CopyFileState& operator=(CopyFileState const&) = delete;
+ };
-// Note: This function isn't guarded by ifdef's even though it may be unused
-// in order to assure it still compiles.
-__attribute__((unused)) bool copy_file_impl_default(FileDescriptor& read_fd,
- FileDescriptor& write_fd,
- error_code& ec) {
- ifstream in;
- in.__open(read_fd.fd, ios::binary);
- if (!in.is_open()) {
- // This assumes that __open didn't reset the error code.
- ec = capture_errno();
- return false;
- }
- ofstream out;
- out.__open(write_fd.fd, ios::binary);
- if (!out.is_open()) {
- ec = capture_errno();
- return false;
- }
+ CopyFileState cfs;
+ if (fcopyfile(read_fd.fd, write_fd.fd, cfs.state, COPYFILE_DATA) < 0) {
+ ec = capture_errno();
+ return false;
+ }
- if (in.good() && out.good()) {
- using InIt = istreambuf_iterator<char>;
- using OutIt = ostreambuf_iterator<char>;
- InIt bin(in);
- InIt ein;
- OutIt bout(out);
- copy(bin, ein, bout);
- }
- if (out.fail() || in.fail()) {
- ec = make_error_code(errc::io_error);
- return false;
+ ec.clear();
+ return true;
}
+#elif defined(_LIBCPP_FILESYSTEM_USE_FSTREAM)
+ bool copy_file_impl(FileDescriptor& read_fd, FileDescriptor& write_fd, error_code& ec) {
+ ifstream in;
+ in.__open(read_fd.fd, ios::binary);
+ if (!in.is_open()) {
+ // This assumes that __open didn't reset the error code.
+ ec = capture_errno();
+ return false;
+ }
+ read_fd.fd = -1;
+ ofstream out;
+ out.__open(write_fd.fd, ios::binary);
+ if (!out.is_open()) {
+ ec = capture_errno();
+ return false;
+ }
+ write_fd.fd = -1;
+
+ if (in.good() && out.good()) {
+ using InIt = istreambuf_iterator<char>;
+ using OutIt = ostreambuf_iterator<char>;
+ InIt bin(in);
+ InIt ein;
+ OutIt bout(out);
+ copy(bin, ein, bout);
+ }
+ if (out.fail() || in.fail()) {
+ ec = make_error_code(errc::io_error);
+ return false;
+ }
- ec.clear();
- return true;
-}
-
-bool copy_file_impl(FileDescriptor& from, FileDescriptor& to, error_code& ec) {
-#if defined(_LIBCPP_USE_SENDFILE)
- return copy_file_impl_sendfile(from, to, ec);
-#elif defined(_LIBCPP_USE_COPYFILE)
- return copy_file_impl_copyfile(from, to, ec);
+ ec.clear();
+ return true;
+ }
#else
- return copy_file_impl_default(from, to, ec);
-#endif
-}
+# error "Unknown implementation for copy_file_impl"
+#endif // copy_file_impl implementation
-} // namespace
-} // namespace detail
+} // end anonymous namespace
+} // end namespace detail
bool __copy_file(const path& from, const path& to, copy_options options,
error_code* ec) {
@@ -870,8 +946,17 @@ bool __create_directory(const path& p, error_code* ec) {
if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0)
return true;
- if (errno != EEXIST)
+
+ if (errno == EEXIST) {
+ error_code mec = capture_errno();
+ error_code ignored_ec;
+ const file_status st = status(p, ignored_ec);
+ if (!is_directory(st)) {
+ err.report(mec);
+ }
+ } else {
err.report(capture_errno());
+ }
return false;
}
@@ -889,8 +974,17 @@ bool __create_directory(path const& p, path const& attributes, error_code* ec) {
if (::mkdir(p.c_str(), attr_stat.st_mode) == 0)
return true;
- if (errno != EEXIST)
+
+ if (errno == EEXIST) {
+ error_code mec = capture_errno();
+ error_code ignored_ec;
+ const file_status st = status(p, ignored_ec);
+ if (!is_directory(st)) {
+ err.report(mec);
+ }
+ } else {
err.report(capture_errno());
+ }
return false;
}
@@ -1225,10 +1319,10 @@ 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 \"%s\"", p);
+ return err.report(m_ec, "cannot access path \"" PS_FMT "\"", p);
if (!exists(st) || !is_directory(st))
- return err.report(errc::not_a_directory, "path \"%s\" is not a directory",
+ return err.report(errc::not_a_directory, "path \"" PS_FMT "\" is not a directory",
p);
return p;
@@ -1284,7 +1378,7 @@ path& path::replace_extension(path const& replacement) {
}
if (!replacement.empty()) {
if (replacement.native()[0] != '.') {
- __pn_ += ".";
+ __pn_ += PS(".");
}
__pn_.append(replacement.__pn_);
}
@@ -1314,7 +1408,7 @@ string_view_t path::__root_path_raw() const {
auto PP = PathParser::CreateBegin(__pn_);
if (PP.State == PathParser::PS_InRootName) {
auto NextCh = PP.peek();
- if (NextCh && *NextCh == '/') {
+ if (NextCh && isSeparator(*NextCh)) {
++PP;
return createView(__pn_.data(), &PP.RawEntry.back());
}
@@ -1406,12 +1500,16 @@ enum PathPartKind : unsigned char {
static PathPartKind ClassifyPathPart(string_view_t Part) {
if (Part.empty())
return PK_TrailingSep;
- if (Part == ".")
+ if (Part == PS("."))
return PK_Dot;
- if (Part == "..")
+ if (Part == PS(".."))
return PK_DotDot;
- if (Part == "/")
+ if (Part == PS("/"))
+ return PK_RootSep;
+#if defined(_LIBCPP_WIN32API)
+ if (Part == PS("\\"))
return PK_RootSep;
+#endif
return PK_Filename;
}
@@ -1459,7 +1557,7 @@ path path::lexically_normal() const {
NewPathSize -= Parts.back().first.size();
Parts.pop_back();
} else if (LastKind != PK_RootSep)
- AddPart(PK_DotDot, "..");
+ AddPart(PK_DotDot, PS(".."));
MaybeNeedTrailingSep = LastKind == PK_Filename;
break;
}
@@ -1474,7 +1572,7 @@ path path::lexically_normal() const {
}
// [fs.path.generic]p6.8: If the path is empty, add a dot.
if (Parts.empty())
- return ".";
+ return PS(".");
// [fs.path.generic]p6.7: If the last filename is dot-dot, remove any
// trailing directory-separator.
@@ -1486,7 +1584,7 @@ path path::lexically_normal() const {
Result /= PK.first;
if (NeedTrailingSep)
- Result /= "";
+ Result /= PS("");
return Result;
}
@@ -1495,9 +1593,9 @@ static int DetermineLexicalElementCount(PathParser PP) {
int Count = 0;
for (; PP; ++PP) {
auto Elem = *PP;
- if (Elem == "..")
+ if (Elem == PS(".."))
--Count;
- else if (Elem != "." && Elem != "")
+ else if (Elem != PS(".") && Elem != PS(""))
++Count;
}
return Count;
@@ -1544,15 +1642,15 @@ path path::lexically_relative(const path& base) const {
return {};
// if n == 0 and (a == end() || a->empty()), returns path("."); otherwise
- if (ElemCount == 0 && (PP.atEnd() || *PP == ""))
- return ".";
+ if (ElemCount == 0 && (PP.atEnd() || *PP == PS("")))
+ return PS(".");
// return a path constructed with 'n' dot-dot elements, followed by the the
// elements of '*this' after the mismatch.
path Result;
// FIXME: Reserve enough room in Result that it won't have to re-allocate.
while (ElemCount--)
- Result /= "..";
+ Result /= PS("..");
for (; PP; ++PP)
Result /= *PP;
return Result;
@@ -1565,7 +1663,7 @@ static int CompareRootName(PathParser *LHS, PathParser *RHS) {
return 0;
auto GetRootName = [](PathParser *Parser) -> string_view_t {
- return Parser->inRootName() ? **Parser : "";
+ return Parser->inRootName() ? **Parser : PS("");
};
int res = GetRootName(LHS).compare(GetRootName(RHS));
ConsumeRootName(LHS);
@@ -1674,6 +1772,36 @@ path::iterator& path::iterator::__decrement() {
return *this;
}
+#if defined(_LIBCPP_WIN32API)
+////////////////////////////////////////////////////////////////////////////
+// Windows path conversions
+size_t __wide_to_char(const wstring &str, char *out, size_t outlen) {
+ if (str.empty())
+ return 0;
+ ErrorHandler<size_t> err("__wide_to_char", nullptr);
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ BOOL used_default = FALSE;
+ int ret = WideCharToMultiByte(codepage, 0, str.data(), str.size(), out,
+ outlen, nullptr, &used_default);
+ if (ret <= 0 || used_default)
+ return err.report(errc::illegal_byte_sequence);
+ return ret;
+}
+
+size_t __char_to_wide(const string &str, wchar_t *out, size_t outlen) {
+ if (str.empty())
+ return 0;
+ ErrorHandler<size_t> err("__char_to_wide", nullptr);
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ int ret = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str.data(),
+ str.size(), out, outlen);
+ if (ret <= 0)
+ return err.report(errc::illegal_byte_sequence);
+ return ret;
+}
+#endif
+
+
///////////////////////////////////////////////////////////////////////////////
// directory entry definitions
///////////////////////////////////////////////////////////////////////////////
diff --git a/contrib/llvm-project/libcxx/src/include/config_elast.h b/contrib/llvm-project/libcxx/src/include/config_elast.h
index 501cbc4ffeba..3113f9fb5cd1 100644
--- a/contrib/llvm-project/libcxx/src/include/config_elast.h
+++ b/contrib/llvm-project/libcxx/src/include/config_elast.h
@@ -17,10 +17,14 @@
#include <errno.h>
#endif
+// Note: _LIBCPP_ELAST needs to be defined only on platforms
+// where strerror/strerror_r can't handle out-of-range errno values.
#if defined(ELAST)
#define _LIBCPP_ELAST ELAST
#elif defined(_NEWLIB_VERSION)
#define _LIBCPP_ELAST __ELASTERROR
+#elif defined(__NuttX__)
+// No _LIBCPP_ELAST needed on NuttX
#elif defined(__Fuchsia__)
// No _LIBCPP_ELAST needed on Fuchsia
#elif defined(__wasi__)
diff --git a/contrib/llvm-project/libcxx/src/include/refstring.h b/contrib/llvm-project/libcxx/src/include/refstring.h
index e464b79ba89c..cefd7caf0f20 100644
--- a/contrib/llvm-project/libcxx/src/include/refstring.h
+++ b/contrib/llvm-project/libcxx/src/include/refstring.h
@@ -13,12 +13,25 @@
#include <stdexcept>
#include <cstddef>
#include <cstring>
-#ifdef __APPLE__
-#include <dlfcn.h>
-#include <mach-o/dyld.h>
-#endif
#include "atomic_support.h"
+// MacOS and iOS used to ship with libstdc++, and still support old applications
+// linking against libstdc++. The libc++ and libstdc++ exceptions are supposed
+// to be ABI compatible, such that they can be thrown from one library and caught
+// in the other.
+//
+// For that reason, we must look for libstdc++ in the same process and if found,
+// check the string stored in the exception object to see if it is the GCC empty
+// string singleton before manipulating the reference count. This is done so that
+// if an exception is created with a zero-length string in libstdc++, libc++abi
+// won't try to delete the memory.
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) || \
+ defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+# define _LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE
+# include <dlfcn.h>
+# include <mach-o/dyld.h>
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
namespace __refstring_imp { namespace {
@@ -40,7 +53,7 @@ inline char * data_from_rep(_Rep_base *rep) noexcept {
return data + sizeof(*rep);
}
-#if defined(__APPLE__)
+#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
inline
const char* compute_gcc_empty_string_storage() _NOEXCEPT
{
@@ -115,7 +128,7 @@ __libcpp_refstring::~__libcpp_refstring() {
inline
bool __libcpp_refstring::__uses_refcount() const {
-#ifdef __APPLE__
+#if defined(_LIBCPP_CHECK_FOR_GCC_EMPTY_STRING_STORAGE)
return __imp_ != get_gcc_empty_string_storage();
#else
return true;
diff --git a/contrib/llvm-project/libcxx/src/ios.cpp b/contrib/llvm-project/libcxx/src/ios.cpp
index 2dc84be82873..3a9296465777 100644
--- a/contrib/llvm-project/libcxx/src/ios.cpp
+++ b/contrib/llvm-project/libcxx/src/ios.cpp
@@ -15,30 +15,14 @@
#include "__locale"
#include "algorithm"
#include "include/config_elast.h"
-#include "istream"
#include "limits"
#include "memory"
#include "new"
-#include "streambuf"
#include "string"
#include "__undef_macros"
_LIBCPP_BEGIN_NAMESPACE_STD
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>;
-
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>;
-
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>;
-
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>;
-
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>;
-
class _LIBCPP_HIDDEN __iostream_category
: public __do_message
{
diff --git a/contrib/llvm-project/libcxx/src/ios.instantiations.cpp b/contrib/llvm-project/libcxx/src/ios.instantiations.cpp
new file mode 100644
index 000000000000..1a23687d128d
--- /dev/null
+++ b/contrib/llvm-project/libcxx/src/ios.instantiations.cpp
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "__config"
+#include "fstream"
+#include "ios"
+#include "istream"
+#include "ostream"
+#include "sstream"
+#include "streambuf"
+
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+// Original explicit instantiations provided in the library
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ios<wchar_t>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_streambuf<wchar_t>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istream<wchar_t>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostream<wchar_t>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_iostream<char>;
+
+// Additional instantiations added later. Whether programs rely on these being
+// available is protected by _LIBCPP_ABI_ENABLE_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1.
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringbuf<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_stringstream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ostringstream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_istringstream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ifstream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_ofstream<char>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS basic_filebuf<char>;
+
+// Add more here if needed...
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/src/iostream.cpp b/contrib/llvm-project/libcxx/src/iostream.cpp
index ad1920abc657..ea95534c7667 100644
--- a/contrib/llvm-project/libcxx/src/iostream.cpp
+++ b/contrib/llvm-project/libcxx/src/iostream.cpp
@@ -77,7 +77,7 @@ __asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_t
#endif
;
-_LIBCPP_HIDDEN ios_base::Init __start_std_streams;
+_LIBCPP_HIDDEN ios_base::Init __start_std_streams _LIBCPP_INIT_PRIORITY_MAX;
// On Windows the TLS storage for locales needs to be initialized before we create
// the standard streams, otherwise it may not be alive during program termination
diff --git a/contrib/llvm-project/libcxx/src/locale.cpp b/contrib/llvm-project/libcxx/src/locale.cpp
index b9180880e494..a0209d0ce8cf 100644
--- a/contrib/llvm-project/libcxx/src/locale.cpp
+++ b/contrib/llvm-project/libcxx/src/locale.cpp
@@ -29,8 +29,8 @@
#include "cwctype"
#include "__sso_allocator"
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include "support/win32/locale_win32.h"
-#elif !defined(__BIONIC__)
+#include "__support/win32/locale_win32.h"
+#elif !defined(__BIONIC__) && !defined(__NuttX__)
#include <langinfo.h>
#endif
#include <stdlib.h>
@@ -158,7 +158,7 @@ const locale::category locale::all;
class _LIBCPP_HIDDEN locale::__imp
: public facet
{
- enum {N = 28};
+ enum {N = 30};
#if defined(_LIBCPP_COMPILER_MSVC)
// FIXME: MSVC doesn't support aligned parameters by value.
// I can't get the __sso_allocator to work here
@@ -202,8 +202,14 @@ locale::__imp::__imp(size_t refs)
install(&make<_VSTD::ctype<wchar_t> >(1u));
install(&make<codecvt<char, char, mbstate_t> >(1u));
install(&make<codecvt<wchar_t, char, mbstate_t> >(1u));
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
install(&make<codecvt<char16_t, char, mbstate_t> >(1u));
install(&make<codecvt<char32_t, char, mbstate_t> >(1u));
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ install(&make<codecvt<char16_t, char8_t, mbstate_t> >(1u));
+ install(&make<codecvt<char32_t, char8_t, mbstate_t> >(1u));
+#endif
install(&make<numpunct<char> >(1u));
install(&make<numpunct<wchar_t> >(1u));
install(&make<num_get<char> >(1u));
@@ -245,8 +251,14 @@ locale::__imp::__imp(const string& name, size_t refs)
install(new ctype_byname<wchar_t>(name_));
install(new codecvt_byname<char, char, mbstate_t>(name_));
install(new codecvt_byname<wchar_t, char, mbstate_t>(name_));
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
install(new codecvt_byname<char16_t, char, mbstate_t>(name_));
install(new codecvt_byname<char32_t, char, mbstate_t>(name_));
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name_));
+ install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name_));
+#endif
install(new numpunct_byname<char>(name_));
install(new numpunct_byname<wchar_t>(name_));
install(new moneypunct_byname<char, false>(name_));
@@ -315,8 +327,14 @@ locale::__imp::__imp(const __imp& other, const string& name, locale::category c)
install(new ctype_byname<wchar_t>(name));
install(new codecvt_byname<char, char, mbstate_t>(name));
install(new codecvt_byname<wchar_t, char, mbstate_t>(name));
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
install(new codecvt_byname<char16_t, char, mbstate_t>(name));
install(new codecvt_byname<char32_t, char, mbstate_t>(name));
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ install(new codecvt_byname<char16_t, char8_t, mbstate_t>(name));
+ install(new codecvt_byname<char32_t, char8_t, mbstate_t>(name));
+#endif
}
if (c & locale::monetary)
{
@@ -385,8 +403,14 @@ locale::__imp::__imp(const __imp& other, const __imp& one, locale::category c)
install_from<_VSTD::ctype<char> >(one);
install_from<_VSTD::ctype<wchar_t> >(one);
install_from<_VSTD::codecvt<char, char, mbstate_t> >(one);
+_LIBCPP_SUPPRESS_DEPRECATED_PUSH
install_from<_VSTD::codecvt<char16_t, char, mbstate_t> >(one);
install_from<_VSTD::codecvt<char32_t, char, mbstate_t> >(one);
+_LIBCPP_SUPPRESS_DEPRECATED_POP
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+ install_from<_VSTD::codecvt<char16_t, char8_t, mbstate_t> >(one);
+ install_from<_VSTD::codecvt<char32_t, char8_t, mbstate_t> >(one);
+#endif
install_from<_VSTD::codecvt<wchar_t, char, mbstate_t> >(one);
}
if (c & locale::monetary)
@@ -1149,7 +1173,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT
{
return _LIBCPP_GET_C_LOCALE->__ctype_toupper;
}
-#elif __NetBSD__
+#elif defined(__NetBSD__)
const short*
ctype<char>::__classic_lower_table() _NOEXCEPT
{
@@ -3171,6 +3195,87 @@ codecvt<char16_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
return 4;
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+
+// template <> class codecvt<char16_t, char8_t, mbstate_t>
+
+locale::id codecvt<char16_t, char8_t, mbstate_t>::id;
+
+codecvt<char16_t, char8_t, mbstate_t>::~codecvt()
+{
+}
+
+codecvt<char16_t, char8_t, mbstate_t>::result
+codecvt<char16_t, char8_t, mbstate_t>::do_out(state_type&,
+ const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
+ extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
+{
+ const uint16_t* _frm = reinterpret_cast<const uint16_t*>(frm);
+ const uint16_t* _frm_end = reinterpret_cast<const uint16_t*>(frm_end);
+ const uint16_t* _frm_nxt = _frm;
+ uint8_t* _to = reinterpret_cast<uint8_t*>(to);
+ uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
+ uint8_t* _to_nxt = _to;
+ result r = utf16_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
+ frm_nxt = frm + (_frm_nxt - _frm);
+ to_nxt = to + (_to_nxt - _to);
+ return r;
+}
+
+codecvt<char16_t, char8_t, mbstate_t>::result
+codecvt<char16_t, char8_t, mbstate_t>::do_in(state_type&,
+ const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
+ intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
+{
+ const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
+ const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
+ const uint8_t* _frm_nxt = _frm;
+ uint16_t* _to = reinterpret_cast<uint16_t*>(to);
+ uint16_t* _to_end = reinterpret_cast<uint16_t*>(to_end);
+ uint16_t* _to_nxt = _to;
+ result r = utf8_to_utf16(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
+ frm_nxt = frm + (_frm_nxt - _frm);
+ to_nxt = to + (_to_nxt - _to);
+ return r;
+}
+
+codecvt<char16_t, char8_t, mbstate_t>::result
+codecvt<char16_t, char8_t, mbstate_t>::do_unshift(state_type&,
+ extern_type* to, extern_type*, extern_type*& to_nxt) const
+{
+ to_nxt = to;
+ return noconv;
+}
+
+int
+codecvt<char16_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT
+{
+ return 0;
+}
+
+bool
+codecvt<char16_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT
+{
+ return false;
+}
+
+int
+codecvt<char16_t, char8_t, mbstate_t>::do_length(state_type&,
+ const extern_type* frm, const extern_type* frm_end, size_t mx) const
+{
+ const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
+ const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
+ return utf8_to_utf16_length(_frm, _frm_end, mx);
+}
+
+int
+codecvt<char16_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT
+{
+ return 4;
+}
+
+#endif
+
// template <> class codecvt<char32_t, char, mbstate_t>
locale::id codecvt<char32_t, char, mbstate_t>::id;
@@ -3248,6 +3353,87 @@ codecvt<char32_t, char, mbstate_t>::do_max_length() const _NOEXCEPT
return 4;
}
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+
+// template <> class codecvt<char32_t, char8_t, mbstate_t>
+
+locale::id codecvt<char32_t, char8_t, mbstate_t>::id;
+
+codecvt<char32_t, char8_t, mbstate_t>::~codecvt()
+{
+}
+
+codecvt<char32_t, char8_t, mbstate_t>::result
+codecvt<char32_t, char8_t, mbstate_t>::do_out(state_type&,
+ const intern_type* frm, const intern_type* frm_end, const intern_type*& frm_nxt,
+ extern_type* to, extern_type* to_end, extern_type*& to_nxt) const
+{
+ const uint32_t* _frm = reinterpret_cast<const uint32_t*>(frm);
+ const uint32_t* _frm_end = reinterpret_cast<const uint32_t*>(frm_end);
+ const uint32_t* _frm_nxt = _frm;
+ uint8_t* _to = reinterpret_cast<uint8_t*>(to);
+ uint8_t* _to_end = reinterpret_cast<uint8_t*>(to_end);
+ uint8_t* _to_nxt = _to;
+ result r = ucs4_to_utf8(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
+ frm_nxt = frm + (_frm_nxt - _frm);
+ to_nxt = to + (_to_nxt - _to);
+ return r;
+}
+
+codecvt<char32_t, char8_t, mbstate_t>::result
+codecvt<char32_t, char8_t, mbstate_t>::do_in(state_type&,
+ const extern_type* frm, const extern_type* frm_end, const extern_type*& frm_nxt,
+ intern_type* to, intern_type* to_end, intern_type*& to_nxt) const
+{
+ const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
+ const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
+ const uint8_t* _frm_nxt = _frm;
+ uint32_t* _to = reinterpret_cast<uint32_t*>(to);
+ uint32_t* _to_end = reinterpret_cast<uint32_t*>(to_end);
+ uint32_t* _to_nxt = _to;
+ result r = utf8_to_ucs4(_frm, _frm_end, _frm_nxt, _to, _to_end, _to_nxt);
+ frm_nxt = frm + (_frm_nxt - _frm);
+ to_nxt = to + (_to_nxt - _to);
+ return r;
+}
+
+codecvt<char32_t, char8_t, mbstate_t>::result
+codecvt<char32_t, char8_t, mbstate_t>::do_unshift(state_type&,
+ extern_type* to, extern_type*, extern_type*& to_nxt) const
+{
+ to_nxt = to;
+ return noconv;
+}
+
+int
+codecvt<char32_t, char8_t, mbstate_t>::do_encoding() const _NOEXCEPT
+{
+ return 0;
+}
+
+bool
+codecvt<char32_t, char8_t, mbstate_t>::do_always_noconv() const _NOEXCEPT
+{
+ return false;
+}
+
+int
+codecvt<char32_t, char8_t, mbstate_t>::do_length(state_type&,
+ const extern_type* frm, const extern_type* frm_end, size_t mx) const
+{
+ const uint8_t* _frm = reinterpret_cast<const uint8_t*>(frm);
+ const uint8_t* _frm_end = reinterpret_cast<const uint8_t*>(frm_end);
+ return utf8_to_ucs4_length(_frm, _frm_end, mx);
+}
+
+int
+codecvt<char32_t, char8_t, mbstate_t>::do_max_length() const _NOEXCEPT
+{
+ return 4;
+}
+
+#endif
+
// __codecvt_utf8<wchar_t>
__codecvt_utf8<wchar_t>::result
@@ -5128,7 +5314,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
mb = mbstate_t();
const char* bb = buf;
size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
- if (j == size_t(-1))
+ if (j == size_t(-1) || j == 0)
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__weeks_[i].assign(wbuf, wbe);
@@ -5136,7 +5322,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
mb = mbstate_t();
bb = buf;
j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
- if (j == size_t(-1))
+ if (j == size_t(-1) || j == 0)
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__weeks_[i+7].assign(wbuf, wbe);
@@ -5149,7 +5335,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
mb = mbstate_t();
const char* bb = buf;
size_t j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
- if (j == size_t(-1))
+ if (j == size_t(-1) || j == 0)
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__months_[i].assign(wbuf, wbe);
@@ -5157,7 +5343,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct)
mb = mbstate_t();
bb = buf;
j = __libcpp_mbsrtowcs_l(wbuf, &bb, countof(wbuf), &mb, __loc_);
- if (j == size_t(-1))
+ if (j == size_t(-1) || j == 0)
__throw_runtime_error("locale not supported");
wbe = wbuf + j;
__months_[i+12].assign(wbuf, wbe);
@@ -6148,7 +6334,11 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS messages_byname<wchar_t>
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char, char, mbstate_t>;
template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_t, char, mbstate_t>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
-template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
+template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char, mbstate_t>;
+template class _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char, mbstate_t>;
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char16_t, char8_t, mbstate_t>;
+template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<char32_t, char8_t, mbstate_t>;
+#endif
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/src/memory.cpp b/contrib/llvm-project/libcxx/src/memory.cpp
index 633c9a6f5658..5a5894fd94e4 100644
--- a/contrib/llvm-project/libcxx/src/memory.cpp
+++ b/contrib/llvm-project/libcxx/src/memory.cpp
@@ -124,16 +124,12 @@ __shared_weak_count::lock() _NOEXCEPT
return nullptr;
}
-#if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC)
-
const void*
__shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
{
return nullptr;
}
-#endif // _LIBCPP_NO_RTTI
-
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
_LIBCPP_SAFE_STATIC static const std::size_t __sp_mut_count = 16;
diff --git a/contrib/llvm-project/libcxx/src/new.cpp b/contrib/llvm-project/libcxx/src/new.cpp
index 901e78565857..9d01330ba7d5 100644
--- a/contrib/llvm-project/libcxx/src/new.cpp
+++ b/contrib/llvm-project/libcxx/src/new.cpp
@@ -64,7 +64,7 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
if (size == 0)
size = 1;
void* p;
- while ((p = ::malloc(size)) == 0)
+ while ((p = ::malloc(size)) == nullptr)
{
// If malloc fails and there is a new_handler,
// call it to try free up memory.
@@ -85,7 +85,7 @@ _LIBCPP_WEAK
void*
operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
{
- void* p = 0;
+ void* p = nullptr;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -111,7 +111,7 @@ _LIBCPP_WEAK
void*
operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
{
- void* p = 0;
+ void* p = nullptr;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -178,15 +178,16 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
size = 1;
if (static_cast<size_t>(alignment) < sizeof(void*))
alignment = std::align_val_t(sizeof(void*));
+
+ // Try allocating memory. If allocation fails and there is a new_handler,
+ // call it to try free up memory, and try again until it succeeds, or until
+ // the new_handler decides to terminate.
+ //
+ // If allocation fails and there is no new_handler, we throw bad_alloc
+ // (or return nullptr if exceptions are disabled).
void* p;
-#if defined(_LIBCPP_MSVCRT_LIKE)
- while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
-#else
- while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
-#endif
+ while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr)
{
- // If posix_memalign fails and there is a new_handler,
- // call it to try free up memory.
std::new_handler nh = std::get_new_handler();
if (nh)
nh();
@@ -194,7 +195,6 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
#ifndef _LIBCPP_NO_EXCEPTIONS
throw std::bad_alloc();
#else
- p = nullptr; // posix_memalign doesn't initialize 'p' on failure
break;
#endif
}
@@ -206,7 +206,7 @@ _LIBCPP_WEAK
void*
operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
{
- void* p = 0;
+ void* p = nullptr;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -232,7 +232,7 @@ _LIBCPP_WEAK
void*
operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
{
- void* p = 0;
+ void* p = nullptr;
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
@@ -251,11 +251,7 @@ _LIBCPP_WEAK
void
operator delete(void* ptr, std::align_val_t) _NOEXCEPT
{
-#if defined(_LIBCPP_MSVCRT_LIKE)
- ::_aligned_free(ptr);
-#else
- ::free(ptr);
-#endif
+ std::__libcpp_aligned_free(ptr);
}
_LIBCPP_WEAK
diff --git a/contrib/llvm-project/libcxx/src/optional.cpp b/contrib/llvm-project/libcxx/src/optional.cpp
index 3aaf5ea553ef..86d013b3504f 100644
--- a/contrib/llvm-project/libcxx/src/optional.cpp
+++ b/contrib/llvm-project/libcxx/src/optional.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "optional"
+#include "__availability"
namespace std
{
diff --git a/contrib/llvm-project/libcxx/src/random.cpp b/contrib/llvm-project/libcxx/src/random.cpp
index 04adc59f9bc9..29aa43b1e1e1 100644
--- a/contrib/llvm-project/libcxx/src/random.cpp
+++ b/contrib/llvm-project/libcxx/src/random.cpp
@@ -13,6 +13,7 @@
#define _CRT_RAND_S
#endif // defined(_LIBCPP_USING_WIN32_RANDOM)
+#include "limits"
#include "random"
#include "system_error"
@@ -29,6 +30,10 @@
#elif defined(_LIBCPP_USING_DEV_RANDOM)
#include <fcntl.h>
#include <unistd.h>
+#if __has_include(<sys/ioctl.h>) && __has_include(<linux/random.h>)
+#include <sys/ioctl.h>
+#include <linux/random.h>
+#endif
#elif defined(_LIBCPP_USING_NACL_RANDOM)
#include <nacl/nacl_random.h>
#endif
@@ -172,7 +177,23 @@ random_device::operator()()
double
random_device::entropy() const _NOEXCEPT
{
+#if defined(_LIBCPP_USING_DEV_RANDOM) && defined(RNDGETENTCNT)
+ int ent;
+ if (::ioctl(__f_, RNDGETENTCNT, &ent) < 0)
+ return 0;
+
+ if (ent < 0)
return 0;
+
+ if (ent > std::numeric_limits<result_type>::digits)
+ return std::numeric_limits<result_type>::digits;
+
+ return ent;
+#elif defined(__OpenBSD__)
+ return std::numeric_limits<result_type>::digits;
+#else
+ return 0;
+#endif
}
_LIBCPP_END_NAMESPACE_STD
diff --git a/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp b/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp
index 376a0381f545..faa112f7f3a4 100644
--- a/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp
+++ b/contrib/llvm-project/libcxx/src/support/runtime/exception_fallback.ipp
@@ -49,7 +49,6 @@ get_terminate() _NOEXCEPT
return __libcpp_atomic_load(&__terminate_handler);
}
-#ifndef __EMSCRIPTEN__ // We provide this in JS
_LIBCPP_NORETURN
void
terminate() _NOEXCEPT
@@ -72,9 +71,7 @@ terminate() _NOEXCEPT
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
-#endif // !__EMSCRIPTEN__
-#if !defined(__EMSCRIPTEN__)
bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; }
int uncaught_exceptions() _NOEXCEPT
@@ -83,7 +80,6 @@ int uncaught_exceptions() _NOEXCEPT
fprintf(stderr, "uncaught_exceptions not yet implemented\n");
::abort();
}
-#endif // !__EMSCRIPTEN__
exception::~exception() _NOEXCEPT
diff --git a/contrib/llvm-project/libcxx/src/thread.cpp b/contrib/llvm-project/libcxx/src/thread.cpp
index 5f44e9e40fc7..5959d8b71103 100644
--- a/contrib/llvm-project/libcxx/src/thread.cpp
+++ b/contrib/llvm-project/libcxx/src/thread.cpp
@@ -14,17 +14,9 @@
#include "vector"
#include "future"
#include "limits"
-#include <sys/types.h>
-
-#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
-# include <sys/param.h>
-# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__)
-# include <sys/sysctl.h>
-# endif
-#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#if __has_include(<unistd.h>)
-#include <unistd.h>
+# include <unistd.h> // for sysconf
#endif
#if defined(__NetBSD__)
@@ -80,13 +72,7 @@ thread::detach()
unsigned
thread::hardware_concurrency() _NOEXCEPT
{
-#if defined(CTL_HW) && defined(HW_NCPU)
- unsigned n;
- int mib[2] = {CTL_HW, HW_NCPU};
- std::size_t s = sizeof(n);
- sysctl(mib, 2, &n, &s, 0, 0);
- return n;
-#elif defined(_SC_NPROCESSORS_ONLN)
+#if defined(_SC_NPROCESSORS_ONLN)
long result = sysconf(_SC_NPROCESSORS_ONLN);
// sysconf returns -1 if the name is invalid, the option does not exist or
// does not have a definite limit.