diff options
Diffstat (limited to 'contrib/libc++/src')
33 files changed, 1371 insertions, 827 deletions
diff --git a/contrib/libc++/src/chrono.cpp b/contrib/libc++/src/chrono.cpp index 9b277a6..d0e184a 100644 --- a/contrib/libc++/src/chrono.cpp +++ b/contrib/libc++/src/chrono.cpp @@ -37,7 +37,7 @@ #if defined(_LIBCPP_WIN32API) #define WIN32_LEAN_AND_MEAN #define VC_EXTRA_LEAN -#include <Windows.h> +#include <windows.h> #if _WIN32_WINNT >= _WIN32_WINNT_WIN8 #include <winapifamily.h> #endif diff --git a/contrib/libc++/src/condition_variable.cpp b/contrib/libc++/src/condition_variable.cpp index 25e6603..2200aef 100644 --- a/contrib/libc++/src/condition_variable.cpp +++ b/contrib/libc++/src/condition_variable.cpp @@ -14,7 +14,7 @@ #include "condition_variable" #include "thread" #include "system_error" -#include "cassert" +#include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/contrib/libc++/src/exception.cpp b/contrib/libc++/src/exception.cpp index f25041d..4359d12 100644 --- a/contrib/libc++/src/exception.cpp +++ b/contrib/libc++/src/exception.cpp @@ -6,328 +6,31 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include <stdlib.h> -#include <stdio.h> #include "exception" #include "new" +#include "typeinfo" -#if defined(_LIBCPP_ABI_MICROSOFT) -#include <eh.h> -#include <corecrt_terminate.h> -#elif defined(__APPLE__) && !defined(LIBCXXRT) && \ - !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) +#if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) || \ + (defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)) #include <cxxabi.h> - using namespace __cxxabiv1; #define HAVE_DEPENDENT_EH_ABI 1 - #ifndef _LIBCPPABI_VERSION - using namespace __cxxabiapple; - // On Darwin, there are two STL shared libraries and a lower level ABI - // shared library. The globals holding the current terminate handler and - // current unexpected handler are in the ABI library. - #define __terminate_handler __cxxabiapple::__cxa_terminate_handler - #define __unexpected_handler __cxxabiapple::__cxa_unexpected_handler - #endif // _LIBCPPABI_VERSION -#elif defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) - #include <cxxabi.h> - using namespace __cxxabiv1; - #if defined(LIBCXXRT) || defined(_LIBCPPABI_VERSION) - #define HAVE_DEPENDENT_EH_ABI 1 - #endif -#elif !defined(__GLIBCXX__) // defined(LIBCXX_BUILDING_LIBCXXABI) - _LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler; - _LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler; -#endif // defined(LIBCXX_BUILDING_LIBCXXABI) - -namespace std -{ - -#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) - -// libcxxrt provides implementations of these functions itself. -unexpected_handler -set_unexpected(unexpected_handler func) _NOEXCEPT -{ -#if defined(_LIBCPP_ABI_MICROSOFT) - return ::set_unexpected(func); -#else - return __sync_lock_test_and_set(&__unexpected_handler, func); -#endif -} - -unexpected_handler -get_unexpected() _NOEXCEPT -{ -#if defined(_LIBCPP_ABI_MICROSOFT) - return ::_get_unexpected(); -#else - return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); -#endif -} - -_LIBCPP_NORETURN -void -unexpected() -{ - (*get_unexpected())(); - // unexpected handler should not return - terminate(); -} - -terminate_handler -set_terminate(terminate_handler func) _NOEXCEPT -{ -#if defined(_LIBCPP_ABI_MICROSOFT) - return ::set_terminate(func); -#else - return __sync_lock_test_and_set(&__terminate_handler, func); #endif -} -terminate_handler -get_terminate() _NOEXCEPT -{ #if defined(_LIBCPP_ABI_MICROSOFT) - return ::_get_terminate(); -#else - return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); -#endif -} - -#ifndef __EMSCRIPTEN__ // We provide this in JS -_LIBCPP_NORETURN -void -terminate() _NOEXCEPT -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - try - { -#endif // _LIBCPP_NO_EXCEPTIONS - (*get_terminate())(); - // handler should not return - fprintf(stderr, "terminate_handler unexpectedly returned\n"); - ::abort(); -#ifndef _LIBCPP_NO_EXCEPTIONS - } - catch (...) - { - // handler should not throw exception - fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); - ::abort(); - } -#endif // _LIBCPP_NO_EXCEPTIONS -} -#endif // !__EMSCRIPTEN__ -#endif // !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) - -#if !defined(LIBCXXRT) && !defined(__GLIBCXX__) && !defined(__EMSCRIPTEN__) - -bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } - -int uncaught_exceptions() _NOEXCEPT -{ -#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \ - (defined(__APPLE__) || defined(_LIBCPPABI_VERSION)) - // on Darwin, there is a helper function so __cxa_get_globals is private -# if _LIBCPPABI_VERSION > 1101 - return __cxa_uncaught_exceptions(); -# else - return __cxa_uncaught_exception() ? 1 : 0; -# endif -#elif defined(_LIBCPP_ABI_MICROSOFT) - return __uncaught_exceptions(); -#else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("uncaught_exceptions not yet implemented") -# else -# warning uncaught_exception not yet implemented -# endif - fprintf(stderr, "uncaught_exceptions not yet implemented\n"); - ::abort(); -#endif // __APPLE__ -} - - -#ifndef _LIBCPPABI_VERSION - -exception::~exception() _NOEXCEPT -{ -} - -const char* exception::what() const _NOEXCEPT -{ - return "std::exception"; -} - -#endif // _LIBCPPABI_VERSION -#endif //LIBCXXRT -#if !defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__) - -bad_exception::~bad_exception() _NOEXCEPT -{ -} - -const char* bad_exception::what() const _NOEXCEPT -{ - return "std::bad_exception"; -} - -#endif - -#if defined(__GLIBCXX__) - -// libsupc++ does not implement the dependent EH ABI and the functionality -// it uses to implement std::exception_ptr (which it declares as an alias of -// std::__exception_ptr::exception_ptr) is not directly exported to clients. So -// we have little choice but to hijack std::__exception_ptr::exception_ptr's -// (which fortunately has the same layout as our std::exception_ptr) copy -// constructor, assignment operator and destructor (which are part of its -// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) -// function. - -namespace __exception_ptr -{ - -struct exception_ptr -{ - void* __ptr_; - - exception_ptr(const exception_ptr&) _NOEXCEPT; - exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; - ~exception_ptr() _NOEXCEPT; -}; - -} - -_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr); - -#endif - -exception_ptr::~exception_ptr() _NOEXCEPT -{ -#if HAVE_DEPENDENT_EH_ABI - __cxa_decrement_exception_refcount(__ptr_); -#elif defined(__GLIBCXX__) - reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); -#else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("exception_ptr not yet implemented") -# else -# warning exception_ptr not yet implemented -# endif - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); -#endif -} - -exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT - : __ptr_(other.__ptr_) -{ -#if HAVE_DEPENDENT_EH_ABI - __cxa_increment_exception_refcount(__ptr_); -#elif defined(__GLIBCXX__) - new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr( - reinterpret_cast<const __exception_ptr::exception_ptr&>(other)); -#else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("exception_ptr not yet implemented") -# else -# warning exception_ptr not yet implemented -# endif - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); -#endif -} - -exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT -{ -#if HAVE_DEPENDENT_EH_ABI - if (__ptr_ != other.__ptr_) - { - __cxa_increment_exception_refcount(other.__ptr_); - __cxa_decrement_exception_refcount(__ptr_); - __ptr_ = other.__ptr_; - } - return *this; -#elif defined(__GLIBCXX__) - *reinterpret_cast<__exception_ptr::exception_ptr*>(this) = - reinterpret_cast<const __exception_ptr::exception_ptr&>(other); - return *this; -#else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("exception_ptr not yet implemented") -# else -# warning exception_ptr not yet implemented -# endif - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); -#endif -} - -nested_exception::nested_exception() _NOEXCEPT - : __ptr_(current_exception()) -{ -} - -#if !defined(__GLIBCXX__) - -nested_exception::~nested_exception() _NOEXCEPT -{ -} - -#endif - -_LIBCPP_NORETURN -void -nested_exception::rethrow_nested() const -{ - if (__ptr_ == nullptr) - terminate(); - rethrow_exception(__ptr_); -} - -#if !defined(__GLIBCXX__) - -exception_ptr current_exception() _NOEXCEPT -{ -#if HAVE_DEPENDENT_EH_ABI - // be nicer if there was a constructor that took a ptr, then - // this whole function would be just: - // return exception_ptr(__cxa_current_primary_exception()); - exception_ptr ptr; - ptr.__ptr_ = __cxa_current_primary_exception(); - return ptr; -#else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING( "exception_ptr not yet implemented" ) -# else -# warning exception_ptr not yet implemented -# endif - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); -#endif -} - -#endif // !__GLIBCXX__ - -_LIBCPP_NORETURN -void rethrow_exception(exception_ptr p) -{ -#if HAVE_DEPENDENT_EH_ABI - __cxa_rethrow_primary_exception(p.__ptr_); - // if p.__ptr_ is NULL, above returns so we terminate - terminate(); +#include "support/runtime/exception_msvc.ipp" +#include "support/runtime/exception_pointer_msvc.ipp" +#elif defined(_LIBCPPABI_VERSION) +#include "support/runtime/exception_libcxxabi.ipp" +#include "support/runtime/exception_pointer_cxxabi.ipp" +#elif defined(LIBCXXRT) +#include "support/runtime/exception_libcxxrt.ipp" +#include "support/runtime/exception_pointer_cxxabi.ipp" #elif defined(__GLIBCXX__) - rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); +#include "support/runtime/exception_glibcxx.ipp" +#include "support/runtime/exception_pointer_glibcxx.ipp" #else -# if defined(_MSC_VER) && ! defined(__clang__) - _LIBCPP_WARNING("exception_ptr not yet implemented") -# else -# warning exception_ptr not yet implemented -# endif - fprintf(stderr, "exception_ptr not yet implemented\n"); - ::abort(); +#include "support/runtime/exception_fallback.ipp" +#include "support/runtime/exception_pointer_unimplemented.ipp" #endif -} -} // std diff --git a/contrib/libc++/src/experimental/filesystem/directory_iterator.cpp b/contrib/libc++/src/experimental/filesystem/directory_iterator.cpp index a888dcf..2513585 100644 --- a/contrib/libc++/src/experimental/filesystem/directory_iterator.cpp +++ b/contrib/libc++/src/experimental/filesystem/directory_iterator.cpp @@ -1,28 +1,32 @@ +//===------------------ directory_iterator.cpp ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + #include "experimental/filesystem" +#include "__config" +#if defined(_LIBCPP_WIN32API) +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> +#else #include <dirent.h> +#endif #include <errno.h> _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM namespace { namespace detail { +#if !defined(_LIBCPP_WIN32API) inline error_code capture_errno() { _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); return error_code{errno, std::generic_category()}; } - -template <class ...Args> -inline bool capture_error_or_throw(std::error_code* user_ec, - const char* msg, Args&&... args) -{ - std::error_code my_ec = capture_errno(); - if (user_ec) { - *user_ec = my_ec; - return true; - } - __throw_filesystem_error(msg, std::forward<Args>(args)..., my_ec); - return false; -} +#endif template <class ...Args> inline bool set_or_throw(std::error_code& my_ec, @@ -37,25 +41,87 @@ inline bool set_or_throw(std::error_code& my_ec, return false; } -typedef path::string_type string_type; - - -inline string_type posix_readdir(DIR *dir_stream, error_code& ec) { +#if !defined(_LIBCPP_WIN32API) +inline path::string_type posix_readdir(DIR *dir_stream, error_code& ec) { struct dirent* dir_entry_ptr = nullptr; errno = 0; // zero errno in order to detect errors + ec.clear(); if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { - ec = capture_errno(); + if (errno) + ec = capture_errno(); return {}; } else { - ec.clear(); return dir_entry_ptr->d_name; } } +#endif }} // namespace detail using detail::set_or_throw; +#if defined(_LIBCPP_WIN32API) +class __dir_stream { +public: + __dir_stream() = delete; + __dir_stream& operator=(const __dir_stream&) = delete; + + __dir_stream(__dir_stream&& __ds) noexcept + : __stream_(__ds.__stream_), __root_(std::move(__ds.__root_)), + __entry_(std::move(__ds.__entry_)) { + __ds.__stream_ = INVALID_HANDLE_VALUE; + } + + __dir_stream(const path& root, directory_options opts, error_code& ec) + : __stream_(INVALID_HANDLE_VALUE), __root_(root) { + __stream_ = ::FindFirstFile(root.c_str(), &__data_); + if (__stream_ == INVALID_HANDLE_VALUE) { + ec = error_code(::GetLastError(), std::generic_category()); + const bool ignore_permission_denied = + bool(opts & directory_options::skip_permission_denied); + if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED) + ec.clear(); + return; + } + } + + ~__dir_stream() noexcept { + if (__stream_ == INVALID_HANDLE_VALUE) + return; + close(); + } + + 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; + __entry_.assign(__root_ / __data_.cFileName); + return true; + } + ec = error_code(::GetLastError(), std::generic_category()); + close(); + return false; + } + +private: + std::error_code close() noexcept { + std::error_code ec; + if (!::FindClose(__stream_)) + ec = error_code(::GetLastError(), std::generic_category()); + __stream_ = INVALID_HANDLE_VALUE; + return ec; + } + + HANDLE __stream_{INVALID_HANDLE_VALUE}; + WIN32_FIND_DATA __data_; + +public: + path __root_; + directory_entry __entry_; +}; +#else class __dir_stream { public: __dir_stream() = delete; @@ -117,6 +183,7 @@ public: path __root_; directory_entry __entry_; }; +#endif // directory_iterator @@ -149,7 +216,7 @@ directory_iterator& directory_iterator::__increment(error_code *ec) } -directory_entry const& directory_iterator::__deref() const { +directory_entry const& directory_iterator::__dereference() const { _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator"); return __imp_->__entry_; } @@ -195,7 +262,7 @@ int recursive_directory_iterator::depth() const { return __imp_->__stack_.size() - 1; } -const directory_entry& recursive_directory_iterator::__deref() const { +const directory_entry& recursive_directory_iterator::__dereference() const { return __imp_->__stack_.top().__entry_; } diff --git a/contrib/libc++/src/experimental/filesystem/filesystem_time_helper.h b/contrib/libc++/src/experimental/filesystem/filesystem_time_helper.h new file mode 100644 index 0000000..a60fdef --- /dev/null +++ b/contrib/libc++/src/experimental/filesystem/filesystem_time_helper.h @@ -0,0 +1,173 @@ +//===----------------------------------------------------------------------===//// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===//// + +#ifndef FILESYSTEM_TIME_HELPER_H +#define FILESYSTEM_TIME_HELPER_H + +#include "experimental/__config" +#include "chrono" +#include "cstdlib" +#include "climits" + +#include <unistd.h> +#include <sys/stat.h> +#if !defined(UTIME_OMIT) +#include <sys/time.h> // for ::utimes as used in __last_write_time +#endif + +_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +namespace time_detail { namespace { + +using namespace chrono; + +template <class FileTimeT, + bool IsFloat = is_floating_point<typename FileTimeT::rep>::value> +struct fs_time_util_base { + static constexpr auto max_seconds = + duration_cast<seconds>(FileTimeT::duration::max()).count(); + + static constexpr auto max_nsec = + duration_cast<nanoseconds>(FileTimeT::duration::max() - + seconds(max_seconds)) + .count(); + + static constexpr auto min_seconds = + duration_cast<seconds>(FileTimeT::duration::min()).count(); + + static constexpr auto min_nsec_timespec = + duration_cast<nanoseconds>( + (FileTimeT::duration::min() - seconds(min_seconds)) + seconds(1)) + .count(); + + // Static assert that these values properly round trip. + static_assert((seconds(min_seconds) + + duration_cast<microseconds>(nanoseconds(min_nsec_timespec))) - + duration_cast<microseconds>(seconds(1)) == + FileTimeT::duration::min(), + ""); +}; + +template <class FileTimeT> +struct fs_time_util_base<FileTimeT, true> { + static const long long max_seconds; + static const long long max_nsec; + static const long long min_seconds; + static const long long min_nsec_timespec; +}; + +template <class FileTimeT> +const long long fs_time_util_base<FileTimeT, true>::max_seconds = + duration_cast<seconds>(FileTimeT::duration::max()).count(); + +template <class FileTimeT> +const long long fs_time_util_base<FileTimeT, true>::max_nsec = + duration_cast<nanoseconds>(FileTimeT::duration::max() - + seconds(max_seconds)) + .count(); + +template <class FileTimeT> +const long long fs_time_util_base<FileTimeT, true>::min_seconds = + duration_cast<seconds>(FileTimeT::duration::min()).count(); + +template <class FileTimeT> +const long long fs_time_util_base<FileTimeT, true>::min_nsec_timespec = + duration_cast<nanoseconds>((FileTimeT::duration::min() - + seconds(min_seconds)) + + seconds(1)) + .count(); + +template <class FileTimeT, class TimeT, class TimeSpecT> +struct fs_time_util : fs_time_util_base<FileTimeT> { + using Base = fs_time_util_base<FileTimeT>; + using Base::max_nsec; + using Base::max_seconds; + using Base::min_nsec_timespec; + using Base::min_seconds; + +public: + template <class CType, class ChronoType> + static bool checked_set(CType* out, ChronoType time) { + using Lim = numeric_limits<CType>; + if (time > Lim::max() || time < Lim::min()) + return false; + *out = static_cast<CType>(time); + return true; + } + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool is_representable(TimeSpecT tm) { + if (tm.tv_sec >= 0) { + return (tm.tv_sec < max_seconds) || + (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec); + } else if (tm.tv_sec == (min_seconds - 1)) { + return tm.tv_nsec >= min_nsec_timespec; + } else { + return (tm.tv_sec >= min_seconds); + } + } + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 bool is_representable(FileTimeT tm) { + auto secs = duration_cast<seconds>(tm.time_since_epoch()); + auto nsecs = duration_cast<nanoseconds>(tm.time_since_epoch() - secs); + if (nsecs.count() < 0) { + secs = secs + seconds(1); + nsecs = nsecs + seconds(1); + } + using TLim = numeric_limits<TimeT>; + if (secs.count() >= 0) + return secs.count() <= TLim::max(); + return secs.count() >= TLim::min(); + } + + static _LIBCPP_CONSTEXPR_AFTER_CXX11 FileTimeT + convert_timespec(TimeSpecT tm) { + auto adj_msec = duration_cast<microseconds>(nanoseconds(tm.tv_nsec)); + if (tm.tv_sec >= 0) { + auto Dur = seconds(tm.tv_sec) + microseconds(adj_msec); + return FileTimeT(Dur); + } else if (duration_cast<microseconds>(nanoseconds(tm.tv_nsec)).count() == + 0) { + return FileTimeT(seconds(tm.tv_sec)); + } else { // tm.tv_sec < 0 + auto adj_subsec = + duration_cast<microseconds>(seconds(1) - nanoseconds(tm.tv_nsec)); + auto Dur = seconds(tm.tv_sec + 1) - adj_subsec; + return FileTimeT(Dur); + } + } + + template <class SubSecDurT, class SubSecT> + static bool set_times_checked(TimeT* sec_out, SubSecT* subsec_out, + FileTimeT tp) { + using namespace chrono; + auto dur = tp.time_since_epoch(); + auto sec_dur = duration_cast<seconds>(dur); + auto subsec_dur = duration_cast<SubSecDurT>(dur - sec_dur); + // The tv_nsec and tv_usec fields must not be negative so adjust accordingly + if (subsec_dur.count() < 0) { + if (sec_dur.count() > min_seconds) { + sec_dur -= seconds(1); + subsec_dur += seconds(1); + } else { + subsec_dur = SubSecDurT::zero(); + } + } + return checked_set(sec_out, sec_dur.count()) && + checked_set(subsec_out, subsec_dur.count()); + } +}; + +} // end namespace +} // end namespace time_detail + +using time_detail::fs_time_util; + +_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM + +#endif // FILESYSTEM_TIME_HELPER_H diff --git a/contrib/libc++/src/experimental/filesystem/operations.cpp b/contrib/libc++/src/experimental/filesystem/operations.cpp index 6c7e4cf..641a3c5 100644 --- a/contrib/libc++/src/experimental/filesystem/operations.cpp +++ b/contrib/libc++/src/experimental/filesystem/operations.cpp @@ -15,6 +15,8 @@ #include "cstdlib" #include "climits" +#include "filesystem_time_helper.h" + #include <unistd.h> #include <sys/stat.h> #include <sys/statvfs.h> @@ -35,12 +37,9 @@ namespace detail { namespace { using value_type = path::value_type; using string_type = path::string_type; - - inline std::error_code capture_errno() { - _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); - std::error_code m_ec(errno, std::generic_category()); - return m_ec; + _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); + return std::error_code(errno, std::generic_category()); } void set_or_throw(std::error_code const& m_ec, std::error_code* ec, @@ -429,17 +428,20 @@ void __current_path(const path& p, std::error_code *ec) { bool __equivalent(const path& p1, const path& p2, std::error_code *ec) { + auto make_unsupported_error = [&]() { + set_or_throw(make_error_code(errc::not_supported), ec, + "equivalent", p1, p2); + return false; + }; std::error_code ec1, ec2; struct ::stat st1 = {}; struct ::stat st2 = {}; auto s1 = detail::posix_stat(p1.native(), st1, &ec1); + if (!exists(s1)) + return make_unsupported_error(); auto s2 = detail::posix_stat(p2.native(), st2, &ec2); - - if ((!exists(s1) && !exists(s2)) || (is_other(s1) && is_other(s2))) { - set_or_throw(make_error_code(errc::not_supported), ec, - "equivalent", p1, p2); - return false; - } + if (!exists(s2)) + return make_unsupported_error(); if (ec) ec->clear(); return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); } @@ -505,19 +507,8 @@ bool __fs_is_empty(const path& p, std::error_code *ec) namespace detail { namespace { -using namespace std::chrono; - -template <class CType, class ChronoType> -bool checked_set(CType* out, ChronoType time) { - using Lim = numeric_limits<CType>; - if (time > Lim::max() || time < Lim::min()) - return false; - *out = static_cast<CType>(time); - return true; -} - -using TimeSpec = struct ::timespec; -using StatT = struct ::stat; +using TimeSpec = struct timespec; +using StatT = struct stat; #if defined(__APPLE__) TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } @@ -528,137 +519,10 @@ __attribute__((unused)) // Suppress warning TimeSpec extract_atime(StatT const& st) { return st.st_atim; } #endif -constexpr auto max_seconds = duration_cast<seconds>( - file_time_type::duration::max()).count(); - -constexpr auto max_nsec = duration_cast<nanoseconds>( - file_time_type::duration::max() - seconds(max_seconds)).count(); - -constexpr auto min_seconds = duration_cast<seconds>( - file_time_type::duration::min()).count(); - -constexpr auto min_nsec_timespec = duration_cast<nanoseconds>( - (file_time_type::duration::min() - seconds(min_seconds)) + seconds(1)).count(); - -// Static assert that these values properly round trip. -static_assert((seconds(min_seconds) + duration_cast<microseconds>(nanoseconds(min_nsec_timespec))) - - duration_cast<microseconds>(seconds(1)) - == file_time_type::duration::min(), ""); - -constexpr auto max_time_t = numeric_limits<time_t>::max(); -constexpr auto min_time_t = numeric_limits<time_t>::min(); - -#if !defined(__LP64__) && defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" -#endif - -_LIBCPP_CONSTEXPR_AFTER_CXX11 -bool is_representable(TimeSpec const& tm) { - if (tm.tv_sec >= 0) { - return (tm.tv_sec < max_seconds) || - (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec); - } else if (tm.tv_sec == (min_seconds - 1)) { - return tm.tv_nsec >= min_nsec_timespec; - } else { - return (tm.tv_sec >= min_seconds); - } -} -#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR -#if defined(__LP64__) -static_assert(is_representable({max_seconds, max_nsec}), ""); -static_assert(!is_representable({max_seconds + 1, 0}), ""); -static_assert(!is_representable({max_seconds, max_nsec + 1}), ""); -static_assert(!is_representable({max_time_t, 0}), ""); -static_assert(is_representable({min_seconds, 0}), ""); -static_assert(is_representable({min_seconds - 1, min_nsec_timespec}), ""); -static_assert(is_representable({min_seconds - 1, min_nsec_timespec + 1}), ""); -static_assert(!is_representable({min_seconds - 1, min_nsec_timespec - 1}), ""); -static_assert(!is_representable({min_time_t, 999999999}), ""); -#else -static_assert(is_representable({max_time_t, 999999999}), ""); -static_assert(is_representable({max_time_t, 1000000000}), ""); -static_assert(is_representable({min_time_t, 0}), ""); -#endif -#endif - -_LIBCPP_CONSTEXPR_AFTER_CXX11 -bool is_representable(file_time_type const& tm) { - auto secs = duration_cast<seconds>(tm.time_since_epoch()); - auto nsecs = duration_cast<nanoseconds>(tm.time_since_epoch() - secs); - if (nsecs.count() < 0) { - secs = secs + seconds(1); - nsecs = nsecs + seconds(1); - } - using TLim = numeric_limits<time_t>; - if (secs.count() >= 0) - return secs.count() <= TLim::max(); - return secs.count() >= TLim::min(); -} -#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR -#if defined(__LP64__) -static_assert(is_representable(file_time_type::max()), ""); -static_assert(is_representable(file_time_type::min()), ""); -#else -static_assert(!is_representable(file_time_type::max()), ""); -static_assert(!is_representable(file_time_type::min()), ""); -static_assert(is_representable(file_time_type(seconds(max_time_t))), ""); -static_assert(is_representable(file_time_type(seconds(min_time_t))), ""); -#endif -#endif - -_LIBCPP_CONSTEXPR_AFTER_CXX11 -file_time_type convert_timespec(TimeSpec const& tm) { - auto adj_msec = duration_cast<microseconds>(nanoseconds(tm.tv_nsec)); - if (tm.tv_sec >= 0) { - auto Dur = seconds(tm.tv_sec) + microseconds(adj_msec); - return file_time_type(Dur); - } else if (duration_cast<microseconds>(nanoseconds(tm.tv_nsec)).count() == 0) { - return file_time_type(seconds(tm.tv_sec)); - } else { // tm.tv_sec < 0 - auto adj_subsec = duration_cast<microseconds>(seconds(1) - nanoseconds(tm.tv_nsec)); - auto Dur = seconds(tm.tv_sec + 1) - adj_subsec; - return file_time_type(Dur); - } -} -#ifndef _LIBCPP_HAS_NO_CXX14_CONSTEXPR -#if defined(__LP64__) -static_assert(convert_timespec({max_seconds, max_nsec}) == file_time_type::max(), ""); -static_assert(convert_timespec({max_seconds, max_nsec - 1}) < file_time_type::max(), ""); -static_assert(convert_timespec({max_seconds - 1, 999999999}) < file_time_type::max(), ""); -static_assert(convert_timespec({min_seconds - 1, min_nsec_timespec}) == file_time_type::min(), ""); -static_assert(convert_timespec({min_seconds - 1, min_nsec_timespec + 1}) > file_time_type::min(), ""); -static_assert(convert_timespec({min_seconds , 0}) > file_time_type::min(), ""); -#else -// FIXME add tests for 32 bit builds -#endif -#endif - -#if !defined(__LP64__) && defined(__clang__) -#pragma clang diagnostic pop -#endif - -template <class SubSecDurT, class SubSecT> -bool set_times_checked(time_t* sec_out, SubSecT* subsec_out, file_time_type tp) { - using namespace chrono; - auto dur = tp.time_since_epoch(); - auto sec_dur = duration_cast<seconds>(dur); - auto subsec_dur = duration_cast<SubSecDurT>(dur - sec_dur); - // The tv_nsec and tv_usec fields must not be negative so adjust accordingly - if (subsec_dur.count() < 0) { - if (sec_dur.count() > min_seconds) { - sec_dur -= seconds(1); - subsec_dur += seconds(1); - } else { - subsec_dur = SubSecDurT::zero(); - } - } - return checked_set(sec_out, sec_dur.count()) - && checked_set(subsec_out, subsec_dur.count()); -} - }} // end namespace detail +using FSTime = fs_time_util<file_time_type, time_t, struct timespec>; + file_time_type __last_write_time(const path& p, std::error_code *ec) { using namespace ::std::chrono; @@ -671,12 +535,12 @@ file_time_type __last_write_time(const path& p, std::error_code *ec) } if (ec) ec->clear(); auto ts = detail::extract_mtime(st); - if (!detail::is_representable(ts)) { + if (!FSTime::is_representable(ts)) { set_or_throw(error_code(EOVERFLOW, generic_category()), ec, "last_write_time", p); return file_time_type::min(); } - return detail::convert_timespec(ts); + return FSTime::convert_timespec(ts); } void __last_write_time(const path& p, file_time_type new_time, @@ -701,7 +565,7 @@ void __last_write_time(const path& p, file_time_type new_time, struct ::timeval tbuf[2]; tbuf[0].tv_sec = atime.tv_sec; tbuf[0].tv_usec = duration_cast<microseconds>(nanoseconds(atime.tv_nsec)).count(); - const bool overflowed = !detail::set_times_checked<microseconds>( + const bool overflowed = !FSTime::set_times_checked<microseconds>( &tbuf[1].tv_sec, &tbuf[1].tv_usec, new_time); if (overflowed) { @@ -717,7 +581,7 @@ void __last_write_time(const path& p, file_time_type new_time, tbuf[0].tv_sec = 0; tbuf[0].tv_nsec = UTIME_OMIT; - const bool overflowed = !detail::set_times_checked<nanoseconds>( + const bool overflowed = !FSTime::set_times_checked<nanoseconds>( &tbuf[1].tv_sec, &tbuf[1].tv_nsec, new_time); if (overflowed) { set_or_throw(make_error_code(errc::invalid_argument), @@ -845,7 +709,7 @@ void __rename(const path& from, const path& to, std::error_code *ec) { } void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) { - if (::truncate(p.c_str(), static_cast<long>(size)) == -1) + if (::truncate(p.c_str(), static_cast<::off_t>(size)) == -1) set_or_throw(ec, "resize_file", p); else if (ec) ec->clear(); @@ -886,23 +750,28 @@ path __system_complete(const path& p, std::error_code *ec) { return absolute(p, current_path()); } -path __temp_directory_path(std::error_code *ec) { - const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; - const char* ret = nullptr; - for (auto & ep : env_paths) { - if ((ret = std::getenv(ep))) - break; - } - path p(ret ? ret : "/tmp"); - std::error_code m_ec; - if (is_directory(p, m_ec)) { - if (ec) ec->clear(); - return p; - } +path __temp_directory_path(std::error_code* ec) { + const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; + const char* ret = nullptr; + + for (auto& ep : env_paths) + if ((ret = std::getenv(ep))) + break; + if (ret == nullptr) + ret = "/tmp"; + + path p(ret); + std::error_code m_ec; + if (!exists(p, m_ec) || !is_directory(p, m_ec)) { if (!m_ec || m_ec == make_error_code(errc::no_such_file_or_directory)) - m_ec = make_error_code(errc::not_a_directory); + m_ec = make_error_code(errc::not_a_directory); set_or_throw(m_ec, ec, "temp_directory_path"); return {}; + } + + if (ec) + ec->clear(); + return p; } // An absolute path is composed according to the table in [fs.op.absolute]. diff --git a/contrib/libc++/src/experimental/filesystem/path.cpp b/contrib/libc++/src/experimental/filesystem/path.cpp index 96b81f7..dd4026c 100644 --- a/contrib/libc++/src/experimental/filesystem/path.cpp +++ b/contrib/libc++/src/experimental/filesystem/path.cpp @@ -6,11 +6,9 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#undef NDEBUG #include "experimental/filesystem" #include "string_view" #include "utility" -#include "cassert" namespace { namespace parser { @@ -58,13 +56,13 @@ public: } PosPtr peek() const noexcept { - auto End = &Path.back() + 1; auto TkEnd = getNextTokenStartPos(); + auto End = getAfterBack(); return TkEnd == End ? nullptr : TkEnd; } void increment() noexcept { - const PosPtr End = &Path.back() + 1; + const PosPtr End = getAfterBack(); const PosPtr Start = getNextTokenStartPos(); if (Start == End) return makeState(PS_AtEnd); @@ -111,9 +109,8 @@ public: } void decrement() noexcept { - const PosPtr REnd = &Path.front() - 1; + const PosPtr REnd = getBeforeFront(); const PosPtr RStart = getCurrentTokenStartPos() - 1; - assert(RStart != REnd); switch (State) { case PS_AtEnd: { @@ -198,19 +195,27 @@ private: RawEntry = {}; } + PosPtr getAfterBack() const noexcept { + return Path.data() + Path.size(); + } + + PosPtr getBeforeFront() const noexcept { + return Path.data() - 1; + } + /// \brief Return a pointer to the first character after the currently /// lexed element. PosPtr getNextTokenStartPos() const noexcept { switch (State) { case PS_BeforeBegin: - return &Path.front(); + return Path.data(); case PS_InRootName: case PS_InRootDir: case PS_InFilenames: return &RawEntry.back() + 1; case PS_InTrailingSep: case PS_AtEnd: - return &Path.back() + 1; + return getAfterBack(); } _LIBCPP_UNREACHABLE(); } @@ -256,7 +261,8 @@ private: string_view_pair separate_filename(string_view_t const & s) { if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""}; auto pos = s.find_last_of('.'); - if (pos == string_view_t::npos) return string_view_pair{s, string_view{}}; + if (pos == string_view_t::npos) + return string_view_pair{s, string_view_t{}}; return string_view_pair{s.substr(0, pos), s.substr(pos)}; } @@ -322,7 +328,6 @@ string_view_t path::__root_path_raw() const auto NextCh = PP.peek(); if (NextCh && *NextCh == '/') { ++PP; - assert(PP.State == PathParser::PS_InRootDir); return createView(__pn_.data(), &PP.RawEntry.back()); } return PP.RawEntry; @@ -392,7 +397,7 @@ int path::__compare(string_view_t __s) const { size_t hash_value(const path& __p) noexcept { auto PP = PathParser::CreateBegin(__p.native()); size_t hash_value = 0; - std::hash<string_view> hasher; + std::hash<string_view_t> hasher; while (PP) { hash_value = __hash_combine(hash_value, hasher(*PP)); ++PP; diff --git a/contrib/libc++/src/functional.cpp b/contrib/libc++/src/functional.cpp new file mode 100644 index 0000000..5c2646f --- /dev/null +++ b/contrib/libc++/src/functional.cpp @@ -0,0 +1,26 @@ +//===----------------------- functional.cpp -------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "functional" + +_LIBCPP_BEGIN_NAMESPACE_STD + +#ifdef _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +bad_function_call::~bad_function_call() _NOEXCEPT +{ +} + +const char* +bad_function_call::what() const _NOEXCEPT +{ + return "std::bad_function_call"; +} +#endif + +_LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libc++/src/include/atomic_support.h b/contrib/libc++/src/include/atomic_support.h index af0f5f5..08847e6 100644 --- a/contrib/libc++/src/include/atomic_support.h +++ b/contrib/libc++/src/include/atomic_support.h @@ -29,7 +29,7 @@ #endif #if !defined(_LIBCPP_HAS_ATOMIC_BUILTINS) && !defined(_LIBCPP_HAS_NO_THREADS) -# if defined(_MSC_VER) && !defined(__clang__) +# if defined(_LIBCPP_WARNING) _LIBCPP_WARNING("Building libc++ without __atomic builtins is unsupported") # else # warning Building libc++ without __atomic builtins is unsupported diff --git a/contrib/libc++/src/include/refstring.h b/contrib/libc++/src/include/refstring.h new file mode 100644 index 0000000..f0d5b44 --- /dev/null +++ b/contrib/libc++/src/include/refstring.h @@ -0,0 +1,127 @@ +//===------------------------ __refstring ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_REFSTRING_H +#define _LIBCPP_REFSTRING_H + +#include <__config> +#include <stdexcept> +#include <cstddef> +#include <cstring> +#ifdef __APPLE__ +#include <dlfcn.h> +#include <mach-o/dyld.h> +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __refstring_imp { namespace { +typedef int count_t; + +struct _Rep_base { + std::size_t len; + std::size_t cap; + count_t count; +}; + +inline _Rep_base* rep_from_data(const char *data_) noexcept { + char *data = const_cast<char *>(data_); + return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); +} + +inline char * data_from_rep(_Rep_base *rep) noexcept { + char *data = reinterpret_cast<char *>(rep); + return data + sizeof(*rep); +} + +#if defined(__APPLE__) +inline +const char* compute_gcc_empty_string_storage() _NOEXCEPT +{ + void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); + if (handle == nullptr) + return nullptr; + void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); + if (sym == nullptr) + return nullptr; + return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); +} + +inline +const char* +get_gcc_empty_string_storage() _NOEXCEPT +{ + static const char* p = compute_gcc_empty_string_storage(); + return p; +} +#endif + +}} // namespace __refstring_imp + +using namespace __refstring_imp; + +inline +__libcpp_refstring::__libcpp_refstring(const char* msg) { + std::size_t len = strlen(msg); + _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); + rep->len = len; + rep->cap = len; + rep->count = 0; + char *data = data_from_rep(rep); + std::memcpy(data, msg, len + 1); + __imp_ = data; +} + +inline +__libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT + : __imp_(s.__imp_) +{ + if (__uses_refcount()) + __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); +} + +inline +__libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT { + bool adjust_old_count = __uses_refcount(); + struct _Rep_base *old_rep = rep_from_data(__imp_); + __imp_ = s.__imp_; + if (__uses_refcount()) + __sync_add_and_fetch(&rep_from_data(__imp_)->count, 1); + if (adjust_old_count) + { + if (__sync_add_and_fetch(&old_rep->count, count_t(-1)) < 0) + { + ::operator delete(old_rep); + } + } + return *this; +} + +inline +__libcpp_refstring::~__libcpp_refstring() { + if (__uses_refcount()) { + _Rep_base* rep = rep_from_data(__imp_); + if (__sync_add_and_fetch(&rep->count, count_t(-1)) < 0) { + ::operator delete(rep); + } + } +} + +inline +bool __libcpp_refstring::__uses_refcount() const { +#ifdef __APPLE__ + return __imp_ != get_gcc_empty_string_storage(); +#else + return true; +#endif +} + +_LIBCPP_END_NAMESPACE_STD + +#endif //_LIBCPP_REFSTRING_H diff --git a/contrib/libc++/src/ios.cpp b/contrib/libc++/src/ios.cpp index 7c76ca2..0f1d88e 100644 --- a/contrib/libc++/src/ios.cpp +++ b/contrib/libc++/src/ios.cpp @@ -22,6 +22,7 @@ #include "new" #include "streambuf" #include "string" +#include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/contrib/libc++/src/iostream.cpp b/contrib/libc++/src/iostream.cpp index a972be9..534b47a 100644 --- a/contrib/libc++/src/iostream.cpp +++ b/contrib/libc++/src/iostream.cpp @@ -15,14 +15,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_STDIN _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?cin@__1@std@@3V?$basic_istream@DU?$char_traits@D@__1@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdinbuf<char> ) static char __cin[sizeof(__stdinbuf <char>)]; static mbstate_t mb_cin; _ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?wcin@__1@std@@3V?$basic_istream@_WU?$char_traits@_W@__1@std@@@12@A") #endif ; @@ -32,14 +32,14 @@ static mbstate_t mb_wcin; #ifndef _LIBCPP_HAS_NO_STDOUT _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?cout@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)]; static mbstate_t mb_cout; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?wcout@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") #endif ; @@ -48,14 +48,14 @@ static mbstate_t mb_wcout; #endif _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?cerr@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)]; static mbstate_t mb_cerr; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?wcerr@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") #endif ; @@ -63,12 +63,12 @@ _ALIGNAS_TYPE (__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wcha static mbstate_t mb_wcerr; _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?clog@__1@std@@3V?$basic_ostream@DU?$char_traits@D@__1@std@@@12@A") #endif ; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)] -#if defined(_MSC_VER) && defined(__clang__) +#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) __asm__("?wclog@__1@std@@3V?$basic_ostream@_WU?$char_traits@_W@__1@std@@@12@A") #endif ; diff --git a/contrib/libc++/src/locale.cpp b/contrib/libc++/src/locale.cpp index 338ffde..3b4c83a 100644 --- a/contrib/libc++/src/locale.cpp +++ b/contrib/libc++/src/locale.cpp @@ -36,6 +36,7 @@ #endif #include <stdlib.h> #include <stdio.h> +#include "__undef_macros" // On Linux, wint_t and wchar_t have different signed-ness, and this causes // lots of noise in the build log, but no bugs that I know of. @@ -45,6 +46,24 @@ _LIBCPP_BEGIN_NAMESPACE_STD +struct __libcpp_unique_locale { + __libcpp_unique_locale(const char* nm) : __loc_(newlocale(LC_ALL_MASK, nm, 0)) {} + + ~__libcpp_unique_locale() { + if (__loc_) + freelocale(__loc_); + } + + explicit operator bool() const { return __loc_; } + + locale_t& get() { return __loc_; } + + locale_t __loc_; +private: + __libcpp_unique_locale(__libcpp_unique_locale const&); + __libcpp_unique_locale& operator=(__libcpp_unique_locale const&); +}; + #ifdef __cloc_defined locale_t __cloc() { // In theory this could create a race condition. In practice @@ -68,8 +87,8 @@ T& make(A0 a0) { static typename aligned_storage<sizeof(T)>::type buf; - ::new (&buf) T(a0); - return *reinterpret_cast<T*>(&buf); + auto *obj = ::new (&buf) T(a0); + return *obj; } template <class T, class A0, class A1> @@ -88,8 +107,8 @@ T& make(A0 a0, A1 a1, A2 a2) { static typename aligned_storage<sizeof(T)>::type buf; - ::new (&buf) T(a0, a1, a2); - return *reinterpret_cast<T*>(&buf); + auto *obj = ::new (&buf) T(a0, a1, a2); + return *obj; } template <typename T, size_t N> @@ -480,8 +499,8 @@ locale::__imp::make_global() { // only one thread can get in here and it only gets in once static aligned_storage<sizeof(locale)>::type buf; - ::new (&buf) locale(locale::classic()); - return *reinterpret_cast<locale*>(&buf); + auto *obj = ::new (&buf) locale(locale::classic()); + return *obj; } locale& @@ -579,10 +598,8 @@ locale::global(const locale& loc) locale& g = __global(); locale r = g; g = loc; -#ifndef __CloudABI__ if (g.name() != "*") setlocale(LC_ALL, g.name().c_str()); -#endif return r; } @@ -1111,13 +1128,7 @@ ctype<char>::classic_table() _NOEXCEPT #elif __sun__ return __ctype_mask; #elif defined(_LIBCPP_MSVCRT) || defined(__MINGW32__) -#if _VC_CRT_MAJOR_VERSION < 14 - // This is assumed to be safe, which is a nonsense assumption because we're - // going to end up dereferencing it later... - return _ctype+1; // internal ctype mask table defined in msvcrt.dll -#else return __pctype_func(); -#endif #elif defined(__EMSCRIPTEN__) return *__ctype_b_loc(); #elif defined(_NEWLIB_VERSION) @@ -4193,7 +4204,7 @@ __widen_from_utf8<32>::~__widen_from_utf8() static bool checked_string_to_wchar_convert(wchar_t& dest, const char* ptr, - __locale_struct* loc) { + locale_t loc) { if (*ptr == '\0') return false; mbstate_t mb = {}; @@ -4208,7 +4219,7 @@ static bool checked_string_to_wchar_convert(wchar_t& dest, static bool checked_string_to_char_convert(char& dest, const char* ptr, - __locale_struct* __loc) { + locale_t __loc) { if (*ptr == '\0') return false; if (!ptr[1]) { @@ -4303,8 +4314,8 @@ numpunct_byname<char>::__init(const char* nm) { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("numpunct_byname<char>::numpunct_byname" " failed to construct for " + string(nm)); @@ -4341,8 +4352,8 @@ numpunct_byname<wchar_t>::__init(const char* nm) { if (strcmp(nm, "C") != 0) { - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("numpunct_byname<wchar_t>::numpunct_byname" " failed to construct for " + string(nm)); @@ -5828,8 +5839,8 @@ void moneypunct_byname<char, false>::init(const char* nm) { typedef moneypunct<char, false> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); @@ -5872,8 +5883,8 @@ void moneypunct_byname<char, true>::init(const char* nm) { typedef moneypunct<char, true> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); @@ -5932,8 +5943,8 @@ void moneypunct_byname<wchar_t, false>::init(const char* nm) { typedef moneypunct<wchar_t, false> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); lconv* lc = __libcpp_localeconv_l(loc.get()); @@ -5997,8 +6008,8 @@ void moneypunct_byname<wchar_t, true>::init(const char* nm) { typedef moneypunct<wchar_t, true> base; - __locale_unique_ptr loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); - if (loc == nullptr) + __libcpp_unique_locale loc(nm); + if (!loc) __throw_runtime_error("moneypunct_byname" " failed to construct for " + string(nm)); @@ -6147,6 +6158,4 @@ template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS codecvt_byname<wchar_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_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>; - _LIBCPP_END_NAMESPACE_STD diff --git a/contrib/libc++/src/memory.cpp b/contrib/libc++/src/memory.cpp index 8569faf..4e0d3af 100644 --- a/contrib/libc++/src/memory.cpp +++ b/contrib/libc++/src/memory.cpp @@ -17,28 +17,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD -namespace -{ - -// NOTE: Relaxed and acq/rel atomics (for increment and decrement respectively) -// should be sufficient for thread safety. -// See https://llvm.org/bugs/show_bug.cgi?id=22803 -template <class T> -inline T -increment(T& t) _NOEXCEPT -{ - return __libcpp_atomic_add(&t, 1, _AO_Relaxed); -} - -template <class T> -inline T -decrement(T& t) _NOEXCEPT -{ - return __libcpp_atomic_add(&t, -1, _AO_Acq_Rel); -} - -} // namespace - const allocator_arg_t allocator_arg = allocator_arg_t(); bad_weak_ptr::~bad_weak_ptr() _NOEXCEPT {} @@ -53,16 +31,21 @@ __shared_count::~__shared_count() { } +__shared_weak_count::~__shared_weak_count() +{ +} + +#if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) void __shared_count::__add_shared() _NOEXCEPT { - increment(__shared_owners_); + __libcpp_atomic_refcount_increment(__shared_owners_); } bool __shared_count::__release_shared() _NOEXCEPT { - if (decrement(__shared_owners_) == -1) + if (__libcpp_atomic_refcount_decrement(__shared_owners_) == -1) { __on_zero_shared(); return true; @@ -70,10 +53,6 @@ __shared_count::__release_shared() _NOEXCEPT return false; } -__shared_weak_count::~__shared_weak_count() -{ -} - void __shared_weak_count::__add_shared() _NOEXCEPT { @@ -83,7 +62,7 @@ __shared_weak_count::__add_shared() _NOEXCEPT void __shared_weak_count::__add_weak() _NOEXCEPT { - increment(__shared_weak_owners_); + __libcpp_atomic_refcount_increment(__shared_weak_owners_); } void @@ -93,6 +72,8 @@ __shared_weak_count::__release_shared() _NOEXCEPT __release_weak(); } +#endif // _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS + void __shared_weak_count::__release_weak() _NOEXCEPT { @@ -124,7 +105,7 @@ __shared_weak_count::__release_weak() _NOEXCEPT //__libcpp_atomic_store(&__shared_weak_owners_, -1, _AO_Release); __on_zero_shared_weak(); } - else if (decrement(__shared_weak_owners_) == -1) + else if (__libcpp_atomic_refcount_decrement(__shared_weak_owners_) == -1) __on_zero_shared_weak(); } @@ -139,7 +120,7 @@ __shared_weak_count::lock() _NOEXCEPT object_owners+1)) return this; } - return 0; + return nullptr; } #if !defined(_LIBCPP_NO_RTTI) || !defined(_LIBCPP_BUILD_STATIC) @@ -147,7 +128,7 @@ __shared_weak_count::lock() _NOEXCEPT const void* __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT { - return 0; + return nullptr; } #endif // _LIBCPP_NO_RTTI @@ -173,7 +154,7 @@ __sp_mut::lock() _NOEXCEPT { auto m = static_cast<__libcpp_mutex_t*>(__lx); unsigned count = 0; - while (__libcpp_mutex_trylock(m) != 0) + while (!__libcpp_mutex_trylock(m)) { if (++count > 16) { diff --git a/contrib/libc++/src/mutex.cpp b/contrib/libc++/src/mutex.cpp index 9397ae7..c36bd55 100644 --- a/contrib/libc++/src/mutex.cpp +++ b/contrib/libc++/src/mutex.cpp @@ -11,8 +11,8 @@ #include "mutex" #include "limits" #include "system_error" -#include "cassert" #include "include/atomic_support.h" +#include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_THREADS @@ -37,7 +37,7 @@ mutex::lock() bool mutex::try_lock() _NOEXCEPT { - return __libcpp_mutex_trylock(&__m_) == 0; + return __libcpp_mutex_trylock(&__m_); } void @@ -45,7 +45,7 @@ mutex::unlock() _NOEXCEPT { int ec = __libcpp_mutex_unlock(&__m_); (void)ec; - assert(ec == 0); + _LIBCPP_ASSERT(ec == 0, "call to mutex::unlock failed"); } // recursive_mutex @@ -61,7 +61,7 @@ recursive_mutex::~recursive_mutex() { int e = __libcpp_recursive_mutex_destroy(&__m_); (void)e; - assert(e == 0); + _LIBCPP_ASSERT(e == 0, "call to ~recursive_mutex() failed"); } void @@ -77,13 +77,13 @@ recursive_mutex::unlock() _NOEXCEPT { int e = __libcpp_recursive_mutex_unlock(&__m_); (void)e; - assert(e == 0); + _LIBCPP_ASSERT(e == 0, "call to recursive_mutex::unlock() failed"); } bool recursive_mutex::try_lock() _NOEXCEPT { - return __libcpp_recursive_mutex_trylock(&__m_) == 0; + return __libcpp_recursive_mutex_trylock(&__m_); } // timed_mutex diff --git a/contrib/libc++/src/new.cpp b/contrib/libc++/src/new.cpp index b1e8ee3..2b2682f 100644 --- a/contrib/libc++/src/new.cpp +++ b/contrib/libc++/src/new.cpp @@ -13,27 +13,48 @@ #include "new" -#if defined(__APPLE__) && !defined(LIBCXXRT) && \ - !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) - #include <cxxabi.h> - - #ifndef _LIBCPPABI_VERSION - // On Darwin, there are two STL shared libraries and a lower level ABI - // shared library. The global holding the current new handler is - // in the ABI library and named __cxa_new_handler. - #define __new_handler __cxxabiapple::__cxa_new_handler - #endif -#else // __APPLE__ - #if defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI) - #include <cxxabi.h> - #endif // defined(LIBCXX_BUILDING_LIBCXXABI) - #if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) || \ - (!defined(_LIBCPPABI_VERSION) && !defined(__GLIBCXX__)) - static std::new_handler __new_handler; - #endif // _LIBCPPABI_VERSION +#if defined(_LIBCPP_ABI_MICROSOFT) +// nothing todo +#elif defined(LIBCXX_BUILDING_LIBCXXABI) +#include <cxxabi.h> +#elif defined(LIBCXXRT) +#include <cxxabi.h> +#include "support/runtime/new_handler_fallback.ipp" +#elif defined(__GLIBCXX__) +// nothing todo +#else +# if defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) +# include <cxxabi.h> // FIXME: remove this once buildit is gone. +# else +# include "support/runtime/new_handler_fallback.ipp" +# endif #endif +namespace std +{ + #ifndef __GLIBCXX__ +const nothrow_t nothrow = {}; +#endif + +#ifndef LIBSTDCXX + +void +__throw_bad_alloc() +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + throw bad_alloc(); +#else + _VSTD::abort(); +#endif +} + +#endif // !LIBSTDCXX + +} // std + +#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_MICROSOFT) && \ + !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS) // Implement all new and delete operators as weak definitions // in this shared library, so that they can be overridden by programs @@ -162,7 +183,7 @@ operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC if (static_cast<size_t>(alignment) < sizeof(void*)) alignment = std::align_val_t(sizeof(void*)); void* p; -#if defined(_LIBCPP_MSVCRT) +#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) @@ -235,7 +256,7 @@ void operator delete(void* ptr, std::align_val_t) _NOEXCEPT { if (ptr) -#if defined(_LIBCPP_MSVCRT) +#if defined(_LIBCPP_MSVCRT_LIKE) ::_aligned_free(ptr); #else ::free(ptr); @@ -277,107 +298,5 @@ operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT ::operator delete[](ptr, alignment); } -#endif // !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) - -#endif // !__GLIBCXX__ - -namespace std -{ - -#ifndef __GLIBCXX__ -const nothrow_t nothrow = {}; -#endif - -#ifndef _LIBCPPABI_VERSION - -#ifndef __GLIBCXX__ - -new_handler -set_new_handler(new_handler handler) _NOEXCEPT -{ - return __sync_lock_test_and_set(&__new_handler, handler); -} - -new_handler -get_new_handler() _NOEXCEPT -{ - return __sync_fetch_and_add(&__new_handler, nullptr); -} - -#endif // !__GLIBCXX__ - -#ifndef LIBCXXRT - -bad_alloc::bad_alloc() _NOEXCEPT -{ -} - -#ifndef __GLIBCXX__ - -bad_alloc::~bad_alloc() _NOEXCEPT -{ -} - -const char* -bad_alloc::what() const _NOEXCEPT -{ - return "std::bad_alloc"; -} - -#endif // !__GLIBCXX__ - -bad_array_new_length::bad_array_new_length() _NOEXCEPT -{ -} - -#ifndef __GLIBCXX__ - -bad_array_new_length::~bad_array_new_length() _NOEXCEPT -{ -} - -const char* -bad_array_new_length::what() const _NOEXCEPT -{ - return "bad_array_new_length"; -} - -#endif // !__GLIBCXX__ - -#endif //LIBCXXRT - -bad_array_length::bad_array_length() _NOEXCEPT -{ -} - -#ifndef __GLIBCXX__ - -bad_array_length::~bad_array_length() _NOEXCEPT -{ -} - -const char* -bad_array_length::what() const _NOEXCEPT -{ - return "bad_array_length"; -} - -#endif // !__GLIBCXX__ - -#endif // _LIBCPPABI_VERSION - -#ifndef LIBSTDCXX - -void -__throw_bad_alloc() -{ -#ifndef _LIBCPP_NO_EXCEPTIONS - throw bad_alloc(); -#else - _VSTD::abort(); -#endif -} - -#endif // !LIBSTDCXX - -} // std +#endif // !_LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif // !__GLIBCXX__ && !_LIBCPP_ABI_MICROSOFT && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS diff --git a/contrib/libc++/src/stdexcept.cpp b/contrib/libc++/src/stdexcept.cpp index 3f33330..5e06e52 100644 --- a/contrib/libc++/src/stdexcept.cpp +++ b/contrib/libc++/src/stdexcept.cpp @@ -11,7 +11,7 @@ #include "new" #include "string" #include "system_error" -#include "__refstring" +#include "include/refstring.h" /* For _LIBCPPABI_VERSION */ #if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \ diff --git a/contrib/libc++/src/string.cpp b/contrib/libc++/src/string.cpp index cd64433..d7ebdd3 100644 --- a/contrib/libc++/src/string.cpp +++ b/contrib/libc++/src/string.cpp @@ -13,9 +13,6 @@ #include "cerrno" #include "limits" #include "stdexcept" -#ifdef _LIBCPP_MSVCRT -#include "support/win32/support.h" -#endif // _LIBCPP_MSVCRT #include <stdio.h> _LIBCPP_BEGIN_NAMESPACE_STD @@ -430,7 +427,7 @@ get_swprintf() #ifndef _LIBCPP_MSVCRT return swprintf; #else - return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(swprintf); + return static_cast<int (__cdecl*)(wchar_t* __restrict, size_t, const wchar_t*__restrict, ...)>(_snwprintf); #endif } diff --git a/contrib/libc++/src/strstream.cpp b/contrib/libc++/src/strstream.cpp index be94f9c..01523cf 100644 --- a/contrib/libc++/src/strstream.cpp +++ b/contrib/libc++/src/strstream.cpp @@ -13,6 +13,7 @@ #include "cstring" #include "cstdlib" #include "__debug" +#include "__undef_macros" _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/contrib/libc++/src/support/runtime/exception_fallback.ipp b/contrib/libc++/src/support/runtime/exception_fallback.ipp new file mode 100644 index 0000000..69c06a9 --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_fallback.ipp @@ -0,0 +1,182 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <cstdio> + +namespace std { + +_LIBCPP_SAFE_STATIC static std::terminate_handler __terminate_handler; +_LIBCPP_SAFE_STATIC static std::unexpected_handler __unexpected_handler; + + +// libcxxrt provides implementations of these functions itself. +unexpected_handler +set_unexpected(unexpected_handler func) _NOEXCEPT +{ + return __sync_lock_test_and_set(&__unexpected_handler, func); +} + +unexpected_handler +get_unexpected() _NOEXCEPT +{ + return __sync_fetch_and_add(&__unexpected_handler, (unexpected_handler)0); + +} + +_LIBCPP_NORETURN +void unexpected() +{ + (*get_unexpected())(); + // unexpected handler should not return + terminate(); +} + +terminate_handler +set_terminate(terminate_handler func) _NOEXCEPT +{ + return __sync_lock_test_and_set(&__terminate_handler, func); +} + +terminate_handler +get_terminate() _NOEXCEPT +{ + return __sync_fetch_and_add(&__terminate_handler, (terminate_handler)0); + +} + +#ifndef __EMSCRIPTEN__ // We provide this in JS +_LIBCPP_NORETURN +void +terminate() _NOEXCEPT +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + (*get_terminate())(); + // handler should not return + fprintf(stderr, "terminate_handler unexpectedly returned\n"); + ::abort(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + // handler should not throw exception + fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); + ::abort(); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} +#endif // !__EMSCRIPTEN__ + +#if !defined(__EMSCRIPTEN__) +bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } + +int uncaught_exceptions() _NOEXCEPT +{ +#warning uncaught_exception not yet implemented + fprintf(stderr, "uncaught_exceptions not yet implemented\n"); + ::abort(); +} +#endif // !__EMSCRIPTEN__ + + +exception::~exception() _NOEXCEPT +{ +} + +const char* exception::what() const _NOEXCEPT +{ + return "std::exception"; +} + +bad_exception::~bad_exception() _NOEXCEPT +{ +} + +const char* bad_exception::what() const _NOEXCEPT +{ + return "std::bad_exception"; +} + + +bad_alloc::bad_alloc() _NOEXCEPT +{ +} + +bad_alloc::~bad_alloc() _NOEXCEPT +{ +} + +const char* +bad_alloc::what() const _NOEXCEPT +{ + return "std::bad_alloc"; +} + +bad_array_new_length::bad_array_new_length() _NOEXCEPT +{ +} + +bad_array_new_length::~bad_array_new_length() _NOEXCEPT +{ +} + +const char* +bad_array_new_length::what() const _NOEXCEPT +{ + return "bad_array_new_length"; +} + + +bad_array_length::bad_array_length() _NOEXCEPT +{ +} + +bad_array_length::~bad_array_length() _NOEXCEPT +{ +} + +const char* +bad_array_length::what() const _NOEXCEPT +{ + return "bad_array_length"; +} + + +bad_cast::bad_cast() _NOEXCEPT +{ +} + +bad_typeid::bad_typeid() _NOEXCEPT +{ +} + +bad_cast::~bad_cast() _NOEXCEPT +{ +} + +const char* +bad_cast::what() const _NOEXCEPT +{ + return "std::bad_cast"; +} + +bad_typeid::~bad_typeid() _NOEXCEPT +{ +} + +const char* +bad_typeid::what() const _NOEXCEPT +{ + return "std::bad_typeid"; +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_glibcxx.ipp b/contrib/libc++/src/support/runtime/exception_glibcxx.ipp new file mode 100644 index 0000000..0f78932 --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_glibcxx.ipp @@ -0,0 +1,38 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef __GLIBCXX__ +#error header can only be used when targeting libstdc++ or libsupc++ +#endif + +namespace std { + +bad_alloc::bad_alloc() _NOEXCEPT +{ +} + +bad_array_new_length::bad_array_new_length() _NOEXCEPT +{ +} + +bad_array_length::bad_array_length() _NOEXCEPT +{ +} + + +bad_cast::bad_cast() _NOEXCEPT +{ +} + +bad_typeid::bad_typeid() _NOEXCEPT +{ +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_libcxxabi.ipp b/contrib/libc++/src/support/runtime/exception_libcxxabi.ipp new file mode 100644 index 0000000..c3dcf1e --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_libcxxabi.ipp @@ -0,0 +1,28 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPPABI_VERSION +#error this header can only be used with libc++abi +#endif + +namespace std { + +bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } + +int uncaught_exceptions() _NOEXCEPT +{ +# if _LIBCPPABI_VERSION > 1101 + return __cxa_uncaught_exceptions(); +# else + return __cxa_uncaught_exception() ? 1 : 0; +# endif +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_libcxxrt.ipp b/contrib/libc++/src/support/runtime/exception_libcxxrt.ipp new file mode 100644 index 0000000..6d9e0cf --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_libcxxrt.ipp @@ -0,0 +1,41 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LIBCXXRT +#error this header may only be used when targeting libcxxrt +#endif + +namespace std { + +bad_exception::~bad_exception() _NOEXCEPT +{ +} + +const char* bad_exception::what() const _NOEXCEPT +{ + return "std::bad_exception"; +} + + +bad_array_length::bad_array_length() _NOEXCEPT +{ +} + +bad_array_length::~bad_array_length() _NOEXCEPT +{ +} + +const char* +bad_array_length::what() const _NOEXCEPT +{ + return "bad_array_length"; +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_msvc.ipp b/contrib/libc++/src/support/runtime/exception_msvc.ipp new file mode 100644 index 0000000..950ec0c --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_msvc.ipp @@ -0,0 +1,89 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_ABI_MICROSOFT +#error this header can only be used when targeting the MSVC ABI +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <eh.h> +#include <corecrt_terminate.h> + +namespace std { + +// libcxxrt provides implementations of these functions itself. +unexpected_handler +set_unexpected(unexpected_handler func) _NOEXCEPT { + return ::set_unexpected(func); +} + +unexpected_handler get_unexpected() _NOEXCEPT { + return ::_get_unexpected(); +} + +_LIBCPP_NORETURN +void unexpected() { + (*get_unexpected())(); + // unexpected handler should not return + terminate(); +} + +terminate_handler set_terminate(terminate_handler func) _NOEXCEPT { + return ::set_terminate(func); +} + +terminate_handler get_terminate() _NOEXCEPT { + return ::_get_terminate(); +} + +_LIBCPP_NORETURN +void terminate() _NOEXCEPT +{ +#ifndef _LIBCPP_NO_EXCEPTIONS + try + { +#endif // _LIBCPP_NO_EXCEPTIONS + (*get_terminate())(); + // handler should not return + fprintf(stderr, "terminate_handler unexpectedly returned\n"); + ::abort(); +#ifndef _LIBCPP_NO_EXCEPTIONS + } + catch (...) + { + // handler should not throw exception + fprintf(stderr, "terminate_handler unexpectedly threw an exception\n"); + ::abort(); + } +#endif // _LIBCPP_NO_EXCEPTIONS +} + +bool uncaught_exception() _NOEXCEPT { return uncaught_exceptions() > 0; } + +int uncaught_exceptions() _NOEXCEPT { + return __uncaught_exceptions(); +} + +bad_array_length::bad_array_length() _NOEXCEPT +{ +} + +bad_array_length::~bad_array_length() _NOEXCEPT +{ +} + +const char* +bad_array_length::what() const _NOEXCEPT +{ + return "bad_array_length"; +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_pointer_cxxabi.ipp b/contrib/libc++/src/support/runtime/exception_pointer_cxxabi.ipp new file mode 100644 index 0000000..dfac864 --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_pointer_cxxabi.ipp @@ -0,0 +1,74 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef HAVE_DEPENDENT_EH_ABI +#error this header may only be used with libc++abi or libcxxrt +#endif + +namespace std { + +exception_ptr::~exception_ptr() _NOEXCEPT { + __cxa_decrement_exception_refcount(__ptr_); +} + +exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT + : __ptr_(other.__ptr_) +{ + __cxa_increment_exception_refcount(__ptr_); +} + +exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT +{ + if (__ptr_ != other.__ptr_) + { + __cxa_increment_exception_refcount(other.__ptr_); + __cxa_decrement_exception_refcount(__ptr_); + __ptr_ = other.__ptr_; + } + return *this; +} + +nested_exception::nested_exception() _NOEXCEPT + : __ptr_(current_exception()) +{ +} + +nested_exception::~nested_exception() _NOEXCEPT +{ +} + +_LIBCPP_NORETURN +void +nested_exception::rethrow_nested() const +{ + if (__ptr_ == nullptr) + terminate(); + rethrow_exception(__ptr_); +} + +exception_ptr current_exception() _NOEXCEPT +{ + // be nicer if there was a constructor that took a ptr, then + // this whole function would be just: + // return exception_ptr(__cxa_current_primary_exception()); + exception_ptr ptr; + ptr.__ptr_ = __cxa_current_primary_exception(); + return ptr; +} + +_LIBCPP_NORETURN +void rethrow_exception(exception_ptr p) +{ + __cxa_rethrow_primary_exception(p.__ptr_); + // if p.__ptr_ is NULL, above returns so we terminate + terminate(); +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_pointer_glibcxx.ipp b/contrib/libc++/src/support/runtime/exception_pointer_glibcxx.ipp new file mode 100644 index 0000000..9d20dfe --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_pointer_glibcxx.ipp @@ -0,0 +1,78 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// libsupc++ does not implement the dependent EH ABI and the functionality +// it uses to implement std::exception_ptr (which it declares as an alias of +// std::__exception_ptr::exception_ptr) is not directly exported to clients. So +// we have little choice but to hijack std::__exception_ptr::exception_ptr's +// (which fortunately has the same layout as our std::exception_ptr) copy +// constructor, assignment operator and destructor (which are part of its +// stable ABI), and its rethrow_exception(std::__exception_ptr::exception_ptr) +// function. + +namespace std { + +namespace __exception_ptr +{ + +struct exception_ptr +{ + void* __ptr_; + + exception_ptr(const exception_ptr&) _NOEXCEPT; + exception_ptr& operator=(const exception_ptr&) _NOEXCEPT; + ~exception_ptr() _NOEXCEPT; +}; + +} + +_LIBCPP_NORETURN void rethrow_exception(__exception_ptr::exception_ptr); + +exception_ptr::~exception_ptr() _NOEXCEPT +{ + reinterpret_cast<__exception_ptr::exception_ptr*>(this)->~exception_ptr(); +} + +exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT + : __ptr_(other.__ptr_) +{ + new (reinterpret_cast<void*>(this)) __exception_ptr::exception_ptr( + reinterpret_cast<const __exception_ptr::exception_ptr&>(other)); +} + +exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT +{ + *reinterpret_cast<__exception_ptr::exception_ptr*>(this) = + reinterpret_cast<const __exception_ptr::exception_ptr&>(other); + return *this; +} + +nested_exception::nested_exception() _NOEXCEPT + : __ptr_(current_exception()) +{ +} + + +_LIBCPP_NORETURN +void +nested_exception::rethrow_nested() const +{ + if (__ptr_ == nullptr) + terminate(); + rethrow_exception(__ptr_); +} + +_LIBCPP_NORETURN +void rethrow_exception(exception_ptr p) +{ + rethrow_exception(reinterpret_cast<__exception_ptr::exception_ptr&>(p)); +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_pointer_msvc.ipp b/contrib/libc++/src/support/runtime/exception_pointer_msvc.ipp new file mode 100644 index 0000000..eab5d30 --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_pointer_msvc.ipp @@ -0,0 +1,95 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> +#include <stdlib.h> +#include <yvals.h> // for _CRTIMP2_PURE + +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCreate(_Out_ void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrDestroy(_Inout_ void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrCopy(_Out_ void*, + _In_ const void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL +__ExceptionPtrAssign(_Inout_ void*, _In_ const void*); +_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL +__ExceptionPtrCompare(_In_ const void*, _In_ const void*); +_CRTIMP2_PURE bool __CLRCALL_PURE_OR_CDECL +__ExceptionPtrToBool(_In_ const void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL __ExceptionPtrSwap(_Inout_ void*, + _Inout_ void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL +__ExceptionPtrCurrentException(_Out_ void*); +[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL +__ExceptionPtrRethrow(_In_ const void*); +_CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL +__ExceptionPtrCopyException(_Inout_ void*, _In_ const void*, _In_ const void*); + +namespace std { + +exception_ptr::exception_ptr() _NOEXCEPT { __ExceptionPtrCreate(this); } +exception_ptr::exception_ptr(nullptr_t) _NOEXCEPT { __ExceptionPtrCreate(this); } + +exception_ptr::exception_ptr(const exception_ptr& __other) _NOEXCEPT { + __ExceptionPtrCopy(this, &__other); +} +exception_ptr& exception_ptr::operator=(const exception_ptr& __other) _NOEXCEPT { + __ExceptionPtrAssign(this, &__other); + return *this; +} + +exception_ptr& exception_ptr::operator=(nullptr_t) _NOEXCEPT { + exception_ptr dummy; + __ExceptionPtrAssign(this, &dummy); + return *this; +} + +exception_ptr::~exception_ptr() _NOEXCEPT { __ExceptionPtrDestroy(this); } + +exception_ptr::operator bool() const _NOEXCEPT { + return __ExceptionPtrToBool(this); +} + +bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT { + return __ExceptionPtrCompare(&__x, &__y); +} + + +void swap(exception_ptr& lhs, exception_ptr& rhs) _NOEXCEPT { + __ExceptionPtrSwap(&rhs, &lhs); +} + +exception_ptr __copy_exception_ptr(void* __except, const void* __ptr) { + exception_ptr __ret = nullptr; + if (__ptr) + __ExceptionPtrCopyException(&__ret, __except, __ptr); + return __ret; +} + +exception_ptr current_exception() _NOEXCEPT { + exception_ptr __ret; + __ExceptionPtrCurrentException(&__ret); + return __ret; +} + +_LIBCPP_NORETURN +void rethrow_exception(exception_ptr p) { __ExceptionPtrRethrow(&p); } + +nested_exception::nested_exception() _NOEXCEPT : __ptr_(current_exception()) {} + +nested_exception::~nested_exception() _NOEXCEPT {} + +_LIBCPP_NORETURN +void nested_exception::rethrow_nested() const { + if (__ptr_ == nullptr) + terminate(); + rethrow_exception(__ptr_); +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/exception_pointer_unimplemented.ipp b/contrib/libc++/src/support/runtime/exception_pointer_unimplemented.ipp new file mode 100644 index 0000000..21c182c --- /dev/null +++ b/contrib/libc++/src/support/runtime/exception_pointer_unimplemented.ipp @@ -0,0 +1,80 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> +#include <stdlib.h> + +namespace std { + +exception_ptr::~exception_ptr() _NOEXCEPT +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +} + +exception_ptr::exception_ptr(const exception_ptr& other) _NOEXCEPT + : __ptr_(other.__ptr_) +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +} + +exception_ptr& exception_ptr::operator=(const exception_ptr& other) _NOEXCEPT +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +} + +nested_exception::nested_exception() _NOEXCEPT + : __ptr_(current_exception()) +{ +} + +#if !defined(__GLIBCXX__) + +nested_exception::~nested_exception() _NOEXCEPT +{ +} + +#endif + +_LIBCPP_NORETURN +void +nested_exception::rethrow_nested() const +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +#if 0 + if (__ptr_ == nullptr) + terminate(); + rethrow_exception(__ptr_); +#endif // FIXME +} + +exception_ptr current_exception() _NOEXCEPT +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +} + +_LIBCPP_NORETURN +void rethrow_exception(exception_ptr p) +{ +# warning exception_ptr not yet implemented + fprintf(stderr, "exception_ptr not yet implemented\n"); + ::abort(); +} + +} // namespace std diff --git a/contrib/libc++/src/support/runtime/new_handler_fallback.ipp b/contrib/libc++/src/support/runtime/new_handler_fallback.ipp new file mode 100644 index 0000000..b7092d5 --- /dev/null +++ b/contrib/libc++/src/support/runtime/new_handler_fallback.ipp @@ -0,0 +1,27 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace std { + +_LIBCPP_SAFE_STATIC static std::new_handler __new_handler; + +new_handler +set_new_handler(new_handler handler) _NOEXCEPT +{ + return __sync_lock_test_and_set(&__new_handler, handler); +} + +new_handler +get_new_handler() _NOEXCEPT +{ + return __sync_fetch_and_add(&__new_handler, nullptr); +} + +} // namespace std diff --git a/contrib/libc++/src/system_error.cpp b/contrib/libc++/src/system_error.cpp index c547124..17f2c9a 100644 --- a/contrib/libc++/src/system_error.cpp +++ b/contrib/libc++/src/system_error.cpp @@ -17,9 +17,9 @@ #include "cstring" #include "cstdio" #include "cstdlib" -#include "cassert" #include "string" #include "string.h" +#include "__debug" #if defined(__ANDROID__) #include <android/api-level.h> @@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD // class error_category -#if defined(_LIBCPP_DEPRECATED_ABI_EXTERNAL_ERROR_CATEGORY_CONSTRUCTOR) +#if defined(_LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS) error_category::error_category() _NOEXCEPT { } @@ -65,7 +65,7 @@ constexpr size_t strerror_buff_size = 1024; string do_strerror_r(int ev); -#if defined(_LIBCPP_MSVCRT) +#if defined(_LIBCPP_MSVCRT_LIKE) string do_strerror_r(int ev) { char buffer[strerror_buff_size]; if (::strerror_s(buffer, strerror_buff_size, ev) == 0) @@ -96,7 +96,7 @@ string do_strerror_r(int ev) { std::snprintf(buffer, strerror_buff_size, "Unknown error %d", ev); return string(buffer); } else { - assert(new_errno == ERANGE); + _LIBCPP_ASSERT(new_errno == ERANGE, "unexpected error from ::strerr_r"); // FIXME maybe? 'strerror_buff_size' is likely to exceed the // maximum error size so ERANGE shouldn't be returned. std::abort(); diff --git a/contrib/libc++/src/thread.cpp b/contrib/libc++/src/thread.cpp index 5ccf829..550da8e 100644 --- a/contrib/libc++/src/thread.cpp +++ b/contrib/libc++/src/thread.cpp @@ -24,9 +24,9 @@ # endif // defined(BSD) #endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) || defined(__Fuchsia__) # include <unistd.h> -#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +#endif // defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__CloudABI__) || defined(__Fuchsia__) #if defined(__NetBSD__) #pragma weak pthread_create // Do not create libpthread dependency @@ -34,13 +34,13 @@ #if defined(_LIBCPP_WIN32API) #include <windows.h> -#endif // defined(_LIBCPP_WIN32API) +#endif _LIBCPP_BEGIN_NAMESPACE_STD thread::~thread() { - if (__t_ != 0) + if (!__libcpp_thread_isnull(&__t_)) terminate(); } @@ -48,11 +48,11 @@ void thread::join() { int ec = EINVAL; - if (__t_ != 0) + if (!__libcpp_thread_isnull(&__t_)) { ec = __libcpp_thread_join(&__t_); if (ec == 0) - __t_ = 0; + __t_ = _LIBCPP_NULL_THREAD; } if (ec) @@ -63,11 +63,11 @@ void thread::detach() { int ec = EINVAL; - if (__t_ != 0) + if (!__libcpp_thread_isnull(&__t_)) { ec = __libcpp_thread_detach(&__t_); if (ec == 0) - __t_ = 0; + __t_ = _LIBCPP_NULL_THREAD; } if (ec) @@ -99,7 +99,7 @@ thread::hardware_concurrency() _NOEXCEPT #else // defined(CTL_HW) && defined(HW_NCPU) // TODO: grovel through /proc or check cpuid on x86 and similar // instructions on other architectures. -# if defined(_MSC_VER) && ! defined(__clang__) +# if defined(_LIBCPP_WARNING) _LIBCPP_WARNING("hardware_concurrency not yet implemented") # else # warning hardware_concurrency not yet implemented @@ -114,33 +114,9 @@ namespace this_thread void sleep_for(const chrono::nanoseconds& ns) { - using namespace chrono; - if (ns > nanoseconds::zero()) + if (ns > chrono::nanoseconds::zero()) { -#if defined(_LIBCPP_WIN32API) - milliseconds ms = duration_cast<milliseconds>(ns); - if (ms.count() == 0 || ns > duration_cast<nanoseconds>(ms)) - ++ms; - Sleep(ms.count()); -#else - seconds s = duration_cast<seconds>(ns); - timespec ts; - typedef decltype(ts.tv_sec) ts_sec; - _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); - if (s.count() < ts_sec_max) - { - ts.tv_sec = static_cast<ts_sec>(s.count()); - ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count()); - } - else - { - ts.tv_sec = ts_sec_max; - ts.tv_nsec = giga::num - 1; - } - - while (nanosleep(&ts, &ts) == -1 && errno == EINTR) - ; -#endif + __libcpp_thread_sleep_for(ns); } } diff --git a/contrib/libc++/src/typeinfo.cpp b/contrib/libc++/src/typeinfo.cpp index d0a7dae..02778f3 100644 --- a/contrib/libc++/src/typeinfo.cpp +++ b/contrib/libc++/src/typeinfo.cpp @@ -6,73 +6,15 @@ // Source Licenses. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -#include <stdlib.h> - -#if !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) && \ - (defined(__APPLE__) || defined(LIBCXXRT) || defined(LIBCXX_BUILDING_LIBCXXABI)) -#include <cxxabi.h> -#endif #include "typeinfo" -#if defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) +// FIXME: Remove __APPLE__ default here once buildit is gone. +#if (!defined(_LIBCPP_ABI_MICROSOFT) && !defined(LIBCXX_BUILDING_LIBCXXABI) && \ + !defined(LIBCXXRT) && !defined(__GLIBCXX__) && \ + !defined(__APPLE__)) || \ + defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) // FIXME: remove this configuration. std::type_info::~type_info() { } #endif - -#if !defined(LIBCXXRT) && !defined(_LIBCPPABI_VERSION) - -std::bad_cast::bad_cast() _NOEXCEPT -{ -} - -std::bad_typeid::bad_typeid() _NOEXCEPT -{ -} - -#ifndef __GLIBCXX__ - -std::bad_cast::~bad_cast() _NOEXCEPT -{ -} - -const char* -std::bad_cast::what() const _NOEXCEPT -{ - return "std::bad_cast"; -} - -std::bad_typeid::~bad_typeid() _NOEXCEPT -{ -} - -const char* -std::bad_typeid::what() const _NOEXCEPT -{ - return "std::bad_typeid"; -} - -#if defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY) - // On Darwin, the cxa_bad_* functions cannot be in the lower level library - // because bad_cast and bad_typeid are defined in his higher level library - void __cxxabiv1::__cxa_bad_typeid() - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw std::bad_typeid(); -#else - _VSTD::abort(); -#endif - } - void __cxxabiv1::__cxa_bad_cast() - { -#ifndef _LIBCPP_NO_EXCEPTIONS - throw std::bad_cast(); -#else - _VSTD::abort(); -#endif - } -#endif - -#endif // !__GLIBCXX__ -#endif // !LIBCXXRT && !_LIBCPPABI_VERSION diff --git a/contrib/libc++/src/vector.cpp b/contrib/libc++/src/vector.cpp new file mode 100644 index 0000000..300adae --- /dev/null +++ b/contrib/libc++/src/vector.cpp @@ -0,0 +1,16 @@ +//===------------------------- vector.cpp ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "vector" + +_LIBCPP_BEGIN_NAMESPACE_STD + +template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __vector_base_common<true>; + +_LIBCPP_END_NAMESPACE_STD |