diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-02-04 17:04:38 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-02-04 17:04:38 +0000 |
commit | 6a74f946b99e0ce22e541b8abfaace449427f306 (patch) | |
tree | 260de92ee877be516f4f4182ae6ed25b90678bfb /lib | |
parent | 56b1e941d7292e371f158d5216935f49c4dcd9b2 (diff) |
Merge libc++, libc++abi and libunwind version 7.0.1.
Tested by visa on octeon
Tested by kettenis on arm64, armv7 and sparc64
"go for it" deraadt and sthen
Diffstat (limited to 'lib')
27 files changed, 1573 insertions, 4448 deletions
diff --git a/lib/libcxx/Makefile b/lib/libcxx/Makefile index 96579b071db..59796532b13 100644 --- a/lib/libcxx/Makefile +++ b/lib/libcxx/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.10 2018/10/13 19:19:21 kettenis Exp $ +# $OpenBSD: Makefile,v 1.11 2019/02/04 17:04:33 patrick Exp $ .include <bsd.own.mk> @@ -23,6 +23,7 @@ LIB= c++ SRCS+= algorithm.cpp \ any.cpp \ bind.cpp \ + charconv.cpp \ chrono.cpp \ condition_variable.cpp \ debug.cpp \ @@ -67,6 +68,7 @@ STD_HEADERS= __bit_reference \ __config \ __config_site.in \ __debug \ + __errc \ __functional_03 \ __functional_base \ __functional_base_03 \ @@ -74,6 +76,7 @@ STD_HEADERS= __bit_reference \ __libcpp_version \ __locale \ __mutex_base \ + __node_handle \ __nullptr \ __split_buffer \ __sso_allocator \ @@ -94,6 +97,7 @@ STD_HEADERS= __bit_reference \ cerrno \ cfenv \ cfloat \ + charconv \ chrono \ cinttypes \ ciso646 \ @@ -101,6 +105,7 @@ STD_HEADERS= __bit_reference \ clocale \ cmath \ codecvt \ + compare \ complex \ complex.h \ condition_variable \ @@ -121,6 +126,7 @@ STD_HEADERS= __bit_reference \ deque \ errno.h \ exception \ + filesystem \ float.h \ forward_list \ fstream \ @@ -156,6 +162,7 @@ STD_HEADERS= __bit_reference \ set \ setjmp.h \ shared_mutex \ + span \ sstream \ stack \ stdbool.h \ @@ -182,6 +189,7 @@ STD_HEADERS= __bit_reference \ valarray \ variant \ vector \ + version \ wchar.h \ wctype.h @@ -221,6 +229,7 @@ EXP_HEADERS= __config \ ratio \ regex \ set \ + simd \ string \ string_view \ system_error \ diff --git a/lib/libcxx/include/__config b/lib/libcxx/include/__config index 4be3d2c06be..d6942af125d 100644 --- a/lib/libcxx/include/__config +++ b/lib/libcxx/include/__config @@ -12,9 +12,9 @@ #define _LIBCPP_CONFIG #if defined(_MSC_VER) && !defined(__clang__) -#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -#endif +# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER +# endif #endif #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -24,79 +24,95 @@ #ifdef __cplusplus #ifdef __GNUC__ -#define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) +# define _GNUC_VER (__GNUC__ * 100 + __GNUC_MINOR__) // The _GNUC_VER_NEW macro better represents the new GCC versioning scheme // introduced in GCC 5.0. -#define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__) +# define _GNUC_VER_NEW (_GNUC_VER * 10 + __GNUC_PATCHLEVEL__) #else -#define _GNUC_VER 0 -#define _GNUC_VER_NEW 0 +# define _GNUC_VER 0 +# define _GNUC_VER_NEW 0 #endif -#define _LIBCPP_VERSION 6000 +#define _LIBCPP_VERSION 7000 #ifndef _LIBCPP_ABI_VERSION -#define _LIBCPP_ABI_VERSION 1 +# ifdef __Fuchsia__ +# define _LIBCPP_ABI_VERSION 2 +# else +# define _LIBCPP_ABI_VERSION 1 +# endif #endif +#ifndef _LIBCPP_STD_VER +# if __cplusplus <= 201103L +# define _LIBCPP_STD_VER 11 +# elif __cplusplus <= 201402L +# define _LIBCPP_STD_VER 14 +# elif __cplusplus <= 201703L +# define _LIBCPP_STD_VER 17 +# else +# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification +# endif +#endif // _LIBCPP_STD_VER + #if defined(__ELF__) -#define _LIBCPP_OBJECT_FORMAT_ELF 1 +# define _LIBCPP_OBJECT_FORMAT_ELF 1 #elif defined(__MACH__) -#define _LIBCPP_OBJECT_FORMAT_MACHO 1 +# define _LIBCPP_OBJECT_FORMAT_MACHO 1 #elif defined(_WIN32) -#define _LIBCPP_OBJECT_FORMAT_COFF 1 +# define _LIBCPP_OBJECT_FORMAT_COFF 1 #elif defined(__wasm__) -#define _LIBCPP_OBJECT_FORMAT_WASM 1 +# define _LIBCPP_OBJECT_FORMAT_WASM 1 #else -#error Unknown object file format +# error Unknown object file format #endif #if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 // Change short string representation so that string data starts at offset 0, // improving its alignment in some cases. -#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT // Fix deque iterator type in order to support incomplete types. -#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE +# define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE // Fix undefined behavior in how std::list stores its linked nodes. -#define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB // Fix undefined behavior in how __tree stores its end and parent nodes. -#define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB // Fix undefined behavior in how __hash_table stores its pointer types. -#define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB -#define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB -#define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE +# define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB +# define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB +# define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE // Don't use a nullptr_t simulation type in C++03 instead using C++11 nullptr // provided under the alternate keyword __nullptr, which changes the mangling // of nullptr_t. This option is ABI incompatible with GCC in C++03 mode. -#define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR +# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR // Define the `pointer_safety` enum as a C++11 strongly typed enumeration // instead of as a class simulating an enum. If this option is enabled // `pointer_safety` and `get_pointer_safety()` will no longer be available // in C++03. -#define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +# define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE // Define a key function for `bad_function_call` in the library, to centralize // its vtable and typeinfo to libc++ rather than having all other libraries // using that class define their own copies. -#define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION +# define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION // Enable optimized version of __do_get_(un)signed which avoids redundant copies. -#define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET +# define _LIBCPP_ABI_OPTIMIZED_LOCALE_NUM_GET // Use the smallest possible integer type to represent the index of the variant. // Previously libc++ used "unsigned int" exclusivly. -#define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION +# define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION #elif _LIBCPP_ABI_VERSION == 1 -#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) +# if !defined(_LIBCPP_OBJECT_FORMAT_COFF) // Enable compiling copies of now inline methods into the dylib to support // applications compiled against older libraries. This is unnecessary with // COFF dllexport semantics, since dllexport forces a non-inline definition // of inline functions to be emitted anyway. Our own non-inline copy would // conflict with the dllexport-emitted copy, so we disable it. -#define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS -#endif +# define _LIBCPP_DEPRECATED_ABI_LEGACY_LIBRARY_DEFINITIONS_FOR_INLINE_FUNCTIONS +# endif // Feature macros for disabling pre ABI v1 features. All of these options // are deprecated. -#if defined(__FreeBSD__) -#define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR -#endif +# if defined(__FreeBSD__) +# define _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR +# endif #endif #ifdef _LIBCPP_TRIVIAL_PAIR_COPY_CTOR @@ -116,46 +132,50 @@ #ifndef __has_attribute #define __has_attribute(__x) 0 #endif + #ifndef __has_builtin #define __has_builtin(__x) 0 #endif + #ifndef __has_extension #define __has_extension(__x) 0 #endif + #ifndef __has_feature #define __has_feature(__x) 0 #endif + #ifndef __has_cpp_attribute #define __has_cpp_attribute(__x) 0 #endif + // '__is_identifier' returns '0' if '__x' is a reserved identifier provided by // the compiler and '1' otherwise. #ifndef __is_identifier #define __is_identifier(__x) 1 #endif + #ifndef __has_declspec_attribute #define __has_declspec_attribute(__x) 0 #endif #define __has_keyword(__x) !(__is_identifier(__x)) -#ifdef __has_include -#define __libcpp_has_include(__x) __has_include(__x) -#else -#define __libcpp_has_include(__x) 0 +#ifndef __has_include +#define __has_include(...) 0 #endif #if defined(__clang__) -#define _LIBCPP_COMPILER_CLANG -# ifndef __apple_build_version__ -# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) -# endif +# define _LIBCPP_COMPILER_CLANG +# ifndef __apple_build_version__ +# define _LIBCPP_CLANG_VER (__clang_major__ * 100 + __clang_minor__) +# endif #elif defined(__GNUC__) -#define _LIBCPP_COMPILER_GCC +# define _LIBCPP_COMPILER_GCC #elif defined(_MSC_VER) -#define _LIBCPP_COMPILER_MSVC +# define _LIBCPP_COMPILER_MSVC #elif defined(__IBMCPP__) -#define _LIBCPP_COMPILER_IBM +# define _LIBCPP_COMPILER_IBM #endif #ifndef _LIBCPP_CLANG_VER @@ -168,67 +188,69 @@ // and allow the user to explicitly specify the ABI to handle cases where this // heuristic falls short. #if defined(_LIBCPP_ABI_FORCE_ITANIUM) && defined(_LIBCPP_ABI_FORCE_MICROSOFT) -# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined" +# error "Only one of _LIBCPP_ABI_FORCE_ITANIUM and _LIBCPP_ABI_FORCE_MICROSOFT can be defined" #elif defined(_LIBCPP_ABI_FORCE_ITANIUM) -# define _LIBCPP_ABI_ITANIUM +# define _LIBCPP_ABI_ITANIUM #elif defined(_LIBCPP_ABI_FORCE_MICROSOFT) -# define _LIBCPP_ABI_MICROSOFT -#else -# if defined(_WIN32) && defined(_MSC_VER) # define _LIBCPP_ABI_MICROSOFT -# else -# define _LIBCPP_ABI_ITANIUM -# endif +#else +# if defined(_WIN32) && defined(_MSC_VER) +# define _LIBCPP_ABI_MICROSOFT +# else +# define _LIBCPP_ABI_ITANIUM +# endif #endif // Need to detect which libc we're using if we're on Linux. #if defined(__linux__) -#include <features.h> -#if !defined(__GLIBC_PREREQ) -#define __GLIBC_PREREQ(a, b) 0 -#endif // !defined(__GLIBC_PREREQ) +# include <features.h> +# if defined(__GLIBC_PREREQ) +# define _LIBCPP_GLIBC_PREREQ(a, b) __GLIBC_PREREQ(a, b) +# else +# define _LIBCPP_GLIBC_PREREQ(a, b) 0 +# endif // defined(__GLIBC_PREREQ) #endif // defined(__linux__) #ifdef __LITTLE_ENDIAN__ -#if __LITTLE_ENDIAN__ -#define _LIBCPP_LITTLE_ENDIAN -#endif // __LITTLE_ENDIAN__ +# if __LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# endif // __LITTLE_ENDIAN__ #endif // __LITTLE_ENDIAN__ #ifdef __BIG_ENDIAN__ -#if __BIG_ENDIAN__ -#define _LIBCPP_BIG_ENDIAN -#endif // __BIG_ENDIAN__ +# if __BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BIG_ENDIAN__ #endif // __BIG_ENDIAN__ #ifdef __BYTE_ORDER__ -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -#define _LIBCPP_LITTLE_ENDIAN -#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#define _LIBCPP_BIG_ENDIAN -#endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define _LIBCPP_BIG_ENDIAN +# endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #endif // __BYTE_ORDER__ #ifdef __FreeBSD__ -# include <sys/endian.h> +# include <sys/endian.h> # if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN -# ifndef __LONG_LONG_SUPPORTED -# define _LIBCPP_HAS_NO_LONG_LONG -# endif // __LONG_LONG_SUPPORTED +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# ifndef __LONG_LONG_SUPPORTED +# define _LIBCPP_HAS_NO_LONG_LONG +# endif // __LONG_LONG_SUPPORTED #endif // __FreeBSD__ #ifdef __NetBSD__ -# include <sys/endian.h> +# include <sys/endian.h> # if _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# endif // _BYTE_ORDER == _LITTLE_ENDIAN -# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_LITTLE_ENDIAN +# else // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# endif // _BYTE_ORDER == _LITTLE_ENDIAN +# define _LIBCPP_HAS_QUICK_EXIT #endif // __NetBSD__ #ifdef __OpenBSD__ @@ -254,64 +276,90 @@ # if (defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_ARM) || defined(__arm__)) # define _LIBCPP_HAS_BITSCAN64 # endif -# if defined(_LIBCPP_MSVCRT) -# define _LIBCPP_HAS_QUICK_EXIT -# endif +# define _LIBCPP_HAS_OPEN_WITH_WCHAR +# if defined(_LIBCPP_MSVCRT) +# define _LIBCPP_HAS_QUICK_EXIT +# endif // Some CRT APIs are unavailable to store apps -#if defined(WINAPI_FAMILY) -#include <winapifamily.h> -#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \ - (!defined(WINAPI_PARTITION_SYSTEM) || \ - !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM)) -#define _LIBCPP_WINDOWS_STORE_APP -#endif -#endif +# if defined(WINAPI_FAMILY) +# include <winapifamily.h> +# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && \ + (!defined(WINAPI_PARTITION_SYSTEM) || \ + !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM)) +# define _LIBCPP_WINDOWS_STORE_APP +# endif +# endif #endif // defined(_WIN32) #ifdef __sun__ -# include <sys/isa_defs.h> -# ifdef _LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# else -# define _LIBCPP_BIG_ENDIAN -# endif +# include <sys/isa_defs.h> +# ifdef _LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# else +# define _LIBCPP_BIG_ENDIAN +# endif #endif // __sun__ #if defined(__CloudABI__) || defined(__OpenBSD__) - // Certain architectures provide arc4random(). Prefer using - // arc4random() over /dev/{u,}random to make it possible to obtain - // random data even when using sandboxing mechanisms such as chroots, - // Capsicum, etc. -# define _LIBCPP_USING_ARC4_RANDOM + // Certain architectures provide arc4random(). Prefer using + // arc4random() over /dev/{u,}random to make it possible to obtain + // random data even when using sandboxing mechanisms such as chroots, + // Capsicum, etc. +# define _LIBCPP_USING_ARC4_RANDOM #elif defined(__Fuchsia__) -# define _LIBCPP_USING_GETENTROPY +# define _LIBCPP_USING_GETENTROPY #elif defined(__native_client__) - // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, - // including accesses to the special files under /dev. C++11's - // std::random_device is instead exposed through a NaCl syscall. -# define _LIBCPP_USING_NACL_RANDOM + // NaCl's sandbox (which PNaCl also runs in) doesn't allow filesystem access, + // including accesses to the special files under /dev. C++11's + // std::random_device is instead exposed through a NaCl syscall. +# define _LIBCPP_USING_NACL_RANDOM #elif defined(_LIBCPP_WIN32API) -# define _LIBCPP_USING_WIN32_RANDOM +# define _LIBCPP_USING_WIN32_RANDOM #else -# define _LIBCPP_USING_DEV_RANDOM +# define _LIBCPP_USING_DEV_RANDOM #endif #if !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) -# include <endian.h> -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define _LIBCPP_LITTLE_ENDIAN -# elif __BYTE_ORDER == __BIG_ENDIAN -# define _LIBCPP_BIG_ENDIAN -# else // __BYTE_ORDER == __BIG_ENDIAN -# error unable to determine endian -# endif +# include <endian.h> +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define _LIBCPP_LITTLE_ENDIAN +# elif __BYTE_ORDER == __BIG_ENDIAN +# define _LIBCPP_BIG_ENDIAN +# else // __BYTE_ORDER == __BIG_ENDIAN +# error unable to determine endian +# endif #endif // !defined(_LIBCPP_LITTLE_ENDIAN) && !defined(_LIBCPP_BIG_ENDIAN) #if __has_attribute(__no_sanitize__) && !defined(_LIBCPP_COMPILER_GCC) -#define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) +# define _LIBCPP_NO_CFI __attribute__((__no_sanitize__("cfi"))) #else -#define _LIBCPP_NO_CFI +# define _LIBCPP_NO_CFI +#endif + +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +# if defined(__FreeBSD__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__Fuchsia__) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# elif defined(__linux__) +# if !defined(_LIBCPP_HAS_MUSL_LIBC) +# if _LIBCPP_GLIBC_PREREQ(2, 15) || defined(__BIONIC__) +# define _LIBCPP_HAS_QUICK_EXIT +# endif +# if _LIBCPP_GLIBC_PREREQ(2, 17) +# define _LIBCPP_HAS_C11_FEATURES +# define _LIBCPP_HAS_TIMESPEC_GET +# endif +# else // defined(_LIBCPP_HAS_MUSL_LIBC) +# define _LIBCPP_HAS_QUICK_EXIT +# define _LIBCPP_HAS_TIMESPEC_GET +# define _LIBCPP_HAS_C11_FEATURES +# endif +# endif // __linux__ #endif #if defined(_LIBCPP_COMPILER_CLANG) @@ -364,11 +412,11 @@ typedef __char32_t char32_t; #endif #if !(__has_feature(cxx_nullptr)) -# if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR) -# define nullptr __nullptr -# else -# define _LIBCPP_HAS_NO_NULLPTR -# endif +# if (__has_extension(cxx_nullptr) || __has_keyword(__nullptr)) && defined(_LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR) +# define nullptr __nullptr +# else +# define _LIBCPP_HAS_NO_NULLPTR +# endif #endif #if !(__has_feature(cxx_rvalue_references)) @@ -388,11 +436,11 @@ typedef __char32_t char32_t; #endif #if __has_feature(is_base_of) -# define _LIBCPP_HAS_IS_BASE_OF +#define _LIBCPP_HAS_IS_BASE_OF #endif #if __has_feature(is_final) -# define _LIBCPP_HAS_IS_FINAL +#define _LIBCPP_HAS_IS_FINAL #endif // Objective-C++ features (opt-in) @@ -416,38 +464,16 @@ typedef __char32_t char32_t; #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES #endif -#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L -#if defined(__FreeBSD__) -#define _LIBCPP_HAS_QUICK_EXIT -#define _LIBCPP_HAS_C11_FEATURES -#elif defined(__Fuchsia__) -#define _LIBCPP_HAS_QUICK_EXIT -#define _LIBCPP_HAS_C11_FEATURES -#elif defined(__linux__) -#if !defined(_LIBCPP_HAS_MUSL_LIBC) -#if __GLIBC_PREREQ(2, 15) || defined(__BIONIC__) -#define _LIBCPP_HAS_QUICK_EXIT -#endif -#if __GLIBC_PREREQ(2, 17) -#define _LIBCPP_HAS_C11_FEATURES -#endif -#else // defined(_LIBCPP_HAS_MUSL_LIBC) -#define _LIBCPP_HAS_QUICK_EXIT -#define _LIBCPP_HAS_C11_FEATURES -#endif -#endif // __linux__ -#endif - #if !(__has_feature(cxx_noexcept)) #define _LIBCPP_HAS_NO_NOEXCEPT #endif #if __has_feature(underlying_type) -# define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) +#define _LIBCPP_UNDERLYING_TYPE(T) __underlying_type(T) #endif #if __has_feature(is_literal) -# define _LIBCPP_IS_LITERAL(T) __is_literal(T) +#define _LIBCPP_IS_LITERAL(T) __is_literal(T) #endif // Inline namespaces are available in Clang regardless of C++ dialect. @@ -467,7 +493,7 @@ namespace std { // Allow for build-time disabling of unsigned integer sanitization #if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize) #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) -#endif +#endif #if __has_builtin(__builtin_launder) #define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER @@ -477,6 +503,8 @@ namespace std { #define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS #endif +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + #elif defined(_LIBCPP_COMPILER_GCC) #define _ALIGNAS(x) __attribute__((__aligned__(x))) @@ -491,19 +519,19 @@ namespace std { #endif #if defined(__GNUC__) && _GNUC_VER >= 403 -# define _LIBCPP_HAS_IS_BASE_OF +#define _LIBCPP_HAS_IS_BASE_OF #endif -#if !__EXCEPTIONS +#if !__EXCEPTIONS && !defined(_LIBCPP_NO_EXCEPTIONS) #define _LIBCPP_NO_EXCEPTIONS #endif // constexpr was added to GCC in 4.6. #if _GNUC_VER < 406 -#define _LIBCPP_HAS_NO_CONSTEXPR +# define _LIBCPP_HAS_NO_CONSTEXPR // Can only use constexpr in c++11 mode. #elif !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L -#define _LIBCPP_HAS_NO_CONSTEXPR +# define _LIBCPP_HAS_NO_CONSTEXPR #endif // Determine if GCC supports relaxed constexpr @@ -517,6 +545,7 @@ namespace std { #endif #ifndef __GXX_EXPERIMENTAL_CXX0X__ + #define _LIBCPP_HAS_NO_DECLTYPE #define _LIBCPP_HAS_NO_NULLPTR #define _LIBCPP_HAS_NO_UNICODE_CHARS @@ -567,6 +596,8 @@ namespace std { #define _LIBCPP_HAS_UNIQUE_OBJECT_REPRESENTATIONS #endif +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + #elif defined(_LIBCPP_COMPILER_MSVC) #define _LIBCPP_TOSTRING2(x) #x @@ -581,25 +612,28 @@ namespace std { #define _LIBCPP_HAS_NO_CONSTEXPR #define _LIBCPP_HAS_NO_CXX14_CONSTEXPR #define _LIBCPP_HAS_NO_VARIABLE_TEMPLATES -#if _MSC_VER <= 1800 -#define _LIBCPP_HAS_NO_UNICODE_CHARS -#endif #define _LIBCPP_HAS_NO_NOEXCEPT #define __alignof__ __alignof #define _LIBCPP_NORETURN __declspec(noreturn) #define _ALIGNAS(x) __declspec(align(x)) +#define _ALIGNAS_TYPE(x) alignas(x) #define _LIBCPP_HAS_NO_VARIADICS #define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { #define _LIBCPP_END_NAMESPACE_STD } #define _VSTD std -# define _LIBCPP_WEAK namespace std { } +#define _LIBCPP_WEAK + #define _LIBCPP_HAS_NO_ASAN +#define _LIBCPP_ALWAYS_INLINE __forceinline + +#define _LIBCPP_HAS_NO_VECTOR_EXTENSION + #elif defined(_LIBCPP_COMPILER_IBM) #define _ALIGNAS(x) __attribute__((__aligned__(x))) @@ -630,24 +664,49 @@ namespace std { #define _LIBCPP_HAS_NO_ASAN +#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) + +#define _LIBCPP_HAS_NO_VECTOR_EXTENSION + #endif // _LIBCPP_COMPILER_[CLANG|GCC|MSVC|IBM] +#if _LIBCPP_STD_VER >= 17 +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD inline namespace __fs { namespace filesystem { +#else +#define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM \ + _LIBCPP_BEGIN_NAMESPACE_STD namespace __fs { namespace filesystem { +#endif + +#define _LIBCPP_END_NAMESPACE_FILESYSTEM \ + _LIBCPP_END_NAMESPACE_STD } } + +#define _VSTD_FS _VSTD::__fs::filesystem + + #if defined(_LIBCPP_OBJECT_FORMAT_COFF) + +#ifdef _DLL +# define _LIBCPP_CRT_FUNC __declspec(dllimport) +#else +# define _LIBCPP_CRT_FUNC +#endif + #if defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -# define _LIBCPP_DLL_VIS -# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS -# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS -# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_DLL_VIS +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS #elif defined(_LIBCPP_BUILDING_LIBRARY) -# define _LIBCPP_DLL_VIS __declspec(dllexport) -# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS -# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS -# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_DLL_VIS __declspec(dllexport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_DLL_VIS #else -# define _LIBCPP_DLL_VIS __declspec(dllimport) -# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS -# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS -# define _LIBCPP_OVERRIDABLE_FUNC_VIS +# define _LIBCPP_DLL_VIS __declspec(dllimport) +# define _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS _LIBCPP_DLL_VIS +# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +# define _LIBCPP_OVERRIDABLE_FUNC_VIS #endif #define _LIBCPP_TYPE_VIS _LIBCPP_DLL_VIS @@ -660,39 +719,36 @@ namespace std { #define _LIBCPP_ENUM_VIS #if defined(_LIBCPP_COMPILER_MSVC) -# define _LIBCPP_INLINE_VISIBILITY __forceinline -# define _LIBCPP_ALWAYS_INLINE __forceinline -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __forceinline #else -# define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) -# define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__)) +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__ ((__always_inline__)) #endif + #endif // defined(_LIBCPP_OBJECT_FORMAT_COFF) #ifndef _LIBCPP_HIDDEN -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -#define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) -#else -#define _LIBCPP_HIDDEN -#endif +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_HIDDEN __attribute__ ((__visibility__("hidden"))) +# else +# define _LIBCPP_HIDDEN +# endif #endif #ifndef _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) // The inline should be removed once PR32114 is resolved -#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN -#else -#define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS -#endif +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS inline _LIBCPP_HIDDEN +# else +# define _LIBCPP_METHOD_TEMPLATE_IMPLICIT_INSTANTIATION_VIS +# endif #endif #ifndef _LIBCPP_FUNC_VIS -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -#define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) -#else -#define _LIBCPP_FUNC_VIS -#endif +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_FUNC_VIS __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_FUNC_VIS +# endif #endif #ifndef _LIBCPP_TYPE_VIS @@ -716,19 +772,19 @@ namespace std { #endif #ifndef _LIBCPP_EXTERN_VIS -# define _LIBCPP_EXTERN_VIS +#define _LIBCPP_EXTERN_VIS #endif #ifndef _LIBCPP_OVERRIDABLE_FUNC_VIS -# define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS +#define _LIBCPP_OVERRIDABLE_FUNC_VIS _LIBCPP_FUNC_VIS #endif #ifndef _LIBCPP_EXCEPTION_ABI -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) -#else -#define _LIBCPP_EXCEPTION_ABI -#endif +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) +# else +# define _LIBCPP_EXCEPTION_ABI +# endif #endif #ifndef _LIBCPP_ENUM_VIS @@ -748,31 +804,40 @@ namespace std { #endif #ifndef _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS -# define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS +#define _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS #endif -#ifndef _LIBCPP_INLINE_VISIBILITY -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) +#if __has_attribute(internal_linkage) +# define _LIBCPP_INTERNAL_LINKAGE __attribute__ ((internal_linkage)) #else -#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__always_inline__)) -#endif +# define _LIBCPP_INTERNAL_LINKAGE _LIBCPP_ALWAYS_INLINE #endif -#ifndef _LIBCPP_ALWAYS_INLINE -#if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__visibility__("hidden"), __always_inline__)) -#else -#define _LIBCPP_ALWAYS_INLINE __attribute__ ((__always_inline__)) +#ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU +# ifndef _LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 0 +# else +# define _LIBCPP_HIDE_FROM_ABI_PER_TU 1 +# endif #endif + +#ifndef _LIBCPP_HIDE_FROM_ABI +# if _LIBCPP_HIDE_FROM_ABI_PER_TU +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_INTERNAL_LINKAGE +# else +# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_ALWAYS_INLINE +# endif #endif +// Just so we can migrate to _LIBCPP_HIDE_FROM_ABI gradually. +#define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI + #ifndef _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY -# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__)) -# else -# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__)) -# endif +# if !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__visibility__("default"), __always_inline__)) +# else +# define _LIBCPP_EXTERN_TEMPLATE_INLINE_VISIBILITY __attribute__((__always_inline__)) +# endif #endif #ifndef _LIBCPP_PREFERRED_OVERLOAD @@ -790,14 +855,19 @@ namespace std { #endif #if defined(_LIBCPP_DEBUG_USE_EXCEPTIONS) -# if !defined(_LIBCPP_DEBUG) -# error cannot use _LIBCPP_DEBUG_USE_EXCEPTIONS unless _LIBCPP_DEBUG is defined -# endif -# define _NOEXCEPT_DEBUG noexcept(false) -# define _NOEXCEPT_DEBUG_(x) noexcept(false) +# if !defined(_LIBCPP_DEBUG) +# error cannot use _LIBCPP_DEBUG_USE_EXCEPTIONS unless _LIBCPP_DEBUG is defined +# endif +# ifdef _LIBCPP_HAS_NO_NOEXCEPT +# define _NOEXCEPT_DEBUG +# define _NOEXCEPT_DEBUG_(x) +# else +# define _NOEXCEPT_DEBUG noexcept(false) +# define _NOEXCEPT_DEBUG_(x) noexcept(false) +# endif #else -# define _NOEXCEPT_DEBUG _NOEXCEPT -# define _NOEXCEPT_DEBUG_(x) _NOEXCEPT_(x) +# define _NOEXCEPT_DEBUG _NOEXCEPT +# define _NOEXCEPT_DEBUG_(x) _NOEXCEPT_(x) #endif #ifdef _LIBCPP_HAS_NO_UNICODE_CHARS @@ -810,88 +880,88 @@ typedef unsigned int char32_t; #endif #ifdef _LIBCPP_CXX03_LANG -# if __has_extension(c_static_assert) -# define static_assert(__b, __m) _Static_assert(__b, __m) -# else +# if __has_extension(c_static_assert) +# define static_assert(__b, __m) _Static_assert(__b, __m) +# else extern "C++" { template <bool> struct __static_assert_test; template <> struct __static_assert_test<true> {}; template <unsigned> struct __static_assert_check {}; } -#define static_assert(__b, __m) \ - typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \ - _LIBCPP_CONCAT(__t, __LINE__) -# endif // __has_extension(c_static_assert) +# define static_assert(__b, __m) \ + typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \ + _LIBCPP_CONCAT(__t, __LINE__) +# endif // __has_extension(c_static_assert) #endif // _LIBCPP_CXX03_LANG #ifdef _LIBCPP_HAS_NO_DECLTYPE // GCC 4.6 provides __decltype in all standard modes. -#if __has_keyword(__decltype) || _LIBCPP_CLANG_VER >= 304 || _GNUC_VER >= 406 -# define decltype(__x) __decltype(__x) -#else -# define decltype(__x) __typeof__(__x) -#endif +# if __has_keyword(__decltype) || _LIBCPP_CLANG_VER >= 304 || _GNUC_VER >= 406 +# define decltype(__x) __decltype(__x) +# else +# define decltype(__x) __typeof__(__x) +# endif #endif #ifdef _LIBCPP_HAS_NO_CONSTEXPR -#define _LIBCPP_CONSTEXPR +# define _LIBCPP_CONSTEXPR #else -#define _LIBCPP_CONSTEXPR constexpr +# define _LIBCPP_CONSTEXPR constexpr #endif #ifdef _LIBCPP_CXX03_LANG -#define _LIBCPP_DEFAULT {} +# define _LIBCPP_DEFAULT {} #else -#define _LIBCPP_DEFAULT = default; +# define _LIBCPP_DEFAULT = default; #endif #ifdef _LIBCPP_CXX03_LANG -#define _LIBCPP_EQUAL_DELETE +# define _LIBCPP_EQUAL_DELETE #else -#define _LIBCPP_EQUAL_DELETE = delete +# define _LIBCPP_EQUAL_DELETE = delete #endif #ifdef __GNUC__ -#define _NOALIAS __attribute__((__malloc__)) +# define _NOALIAS __attribute__((__malloc__)) #else -#define _NOALIAS +# define _NOALIAS #endif #if __has_feature(cxx_explicit_conversions) || defined(__IBMCPP__) || \ (!defined(_LIBCPP_CXX03_LANG) && defined(__GNUC__)) // All supported GCC versions -# define _LIBCPP_EXPLICIT explicit +# define _LIBCPP_EXPLICIT explicit #else -# define _LIBCPP_EXPLICIT +# define _LIBCPP_EXPLICIT #endif #if !__has_builtin(__builtin_operator_new) || !__has_builtin(__builtin_operator_delete) -# define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE +#define _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE #endif #ifdef _LIBCPP_HAS_NO_STRONG_ENUMS -#define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx -#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ - __lx __v_; \ - _LIBCPP_ALWAYS_INLINE x(__lx __v) : __v_(__v) {} \ - _LIBCPP_ALWAYS_INLINE explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ - _LIBCPP_ALWAYS_INLINE operator int() const {return __v_;} \ - }; +# define _LIBCPP_DECLARE_STRONG_ENUM(x) struct _LIBCPP_TYPE_VIS x { enum __lx +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) \ + __lx __v_; \ + _LIBCPP_INLINE_VISIBILITY x(__lx __v) : __v_(__v) {} \ + _LIBCPP_INLINE_VISIBILITY explicit x(int __v) : __v_(static_cast<__lx>(__v)) {} \ + _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} \ + }; #else // _LIBCPP_HAS_NO_STRONG_ENUMS -#define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x -#define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) +# define _LIBCPP_DECLARE_STRONG_ENUM(x) enum class _LIBCPP_ENUM_VIS x +# define _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(x) #endif // _LIBCPP_HAS_NO_STRONG_ENUMS #ifdef _LIBCPP_DEBUG -# if _LIBCPP_DEBUG == 0 -# define _LIBCPP_DEBUG_LEVEL 1 -# elif _LIBCPP_DEBUG == 1 -# define _LIBCPP_DEBUG_LEVEL 2 -# else -# error Supported values for _LIBCPP_DEBUG are 0 and 1 -# endif -# if !defined(_LIBCPP_BUILDING_LIBRARY) -# define _LIBCPP_EXTERN_TEMPLATE(...) -# endif +# if _LIBCPP_DEBUG == 0 +# define _LIBCPP_DEBUG_LEVEL 1 +# elif _LIBCPP_DEBUG == 1 +# define _LIBCPP_DEBUG_LEVEL 2 +# else +# error Supported values for _LIBCPP_DEBUG are 0 and 1 +# endif +# if !defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_EXTERN_TEMPLATE(...) +# endif #endif #ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE @@ -918,27 +988,39 @@ template <unsigned> struct __static_assert_check {}; #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) // Most unix variants have catopen. These are the specific ones that don't. -#if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) -#define _LIBCPP_HAS_CATOPEN 1 -#endif +# if !defined(__BIONIC__) && !defined(_NEWLIB_VERSION) +# define _LIBCPP_HAS_CATOPEN 1 +# endif #endif #ifdef __FreeBSD__ #define _DECLARE_C99_LDBL_MATH 1 #endif +// If we are getting operator new from the MSVC CRT, then allocation overloads +// for align_val_t were added in 19.12, aka VS 2017 version 15.3. +#if defined(_LIBCPP_MSVCRT) && defined(_MSC_VER) && _MSC_VER < 1912 +#define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif + #if defined(__APPLE__) -# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ - defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ -# endif -# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION -# endif -# endif +# if !defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \ + defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) +# define __MAC_OS_X_VERSION_MIN_REQUIRED __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# endif +# if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +# if __MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +# endif +# endif #endif // defined(__APPLE__) +#if !defined(_LIBCPP_HAS_NO_ALIGNED_ALLOCATION) && \ + !defined(_LIBCPP_BUILDING_LIBRARY) && \ + (!defined(__cpp_aligned_new) || __cpp_aligned_new < 201606) +# define _LIBCPP_HAS_NO_ALIGNED_ALLOCATION +#endif + #if defined(__APPLE__) || defined(__FreeBSD__) #define _LIBCPP_HAS_DEFAULTRUNELOCALE #endif @@ -947,60 +1029,48 @@ template <unsigned> struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif -#ifndef _LIBCPP_STD_VER -# if __cplusplus <= 201103L -# define _LIBCPP_STD_VER 11 -# elif __cplusplus <= 201402L -# define _LIBCPP_STD_VER 14 -# elif __cplusplus <= 201703L -# define _LIBCPP_STD_VER 17 -# else -# define _LIBCPP_STD_VER 18 // current year, or date of c++2a ratification -# endif -#endif // _LIBCPP_STD_VER - #if _LIBCPP_STD_VER > 11 -#define _LIBCPP_DEPRECATED [[deprecated]] +# define _LIBCPP_DEPRECATED [[deprecated]] #else -#define _LIBCPP_DEPRECATED +# define _LIBCPP_DEPRECATED #endif #if _LIBCPP_STD_VER <= 11 -#define _LIBCPP_EXPLICIT_AFTER_CXX11 -#define _LIBCPP_DEPRECATED_AFTER_CXX11 +# define _LIBCPP_EXPLICIT_AFTER_CXX11 +# define _LIBCPP_DEPRECATED_AFTER_CXX11 #else -#define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit -#define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] +# define _LIBCPP_EXPLICIT_AFTER_CXX11 explicit +# define _LIBCPP_DEPRECATED_AFTER_CXX11 [[deprecated]] #endif #if _LIBCPP_STD_VER > 11 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) -#define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr +# define _LIBCPP_CONSTEXPR_AFTER_CXX11 constexpr #else -#define _LIBCPP_CONSTEXPR_AFTER_CXX11 +# define _LIBCPP_CONSTEXPR_AFTER_CXX11 #endif #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) -#define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr +# define _LIBCPP_CONSTEXPR_AFTER_CXX14 constexpr #else -#define _LIBCPP_CONSTEXPR_AFTER_CXX14 +# define _LIBCPP_CONSTEXPR_AFTER_CXX14 #endif #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) -#define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr +# define _LIBCPP_CONSTEXPR_AFTER_CXX17 constexpr #else -#define _LIBCPP_CONSTEXPR_AFTER_CXX17 +# define _LIBCPP_CONSTEXPR_AFTER_CXX17 #endif #if __has_cpp_attribute(nodiscard) && _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_DISABLE_NODISCARD_AFTER_CXX17) -#define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]] +# define _LIBCPP_NODISCARD_AFTER_CXX17 [[nodiscard]] #else -#define _LIBCPP_NODISCARD_AFTER_CXX17 +# define _LIBCPP_NODISCARD_AFTER_CXX17 #endif #if _LIBCPP_STD_VER > 14 && defined(__cpp_inline_variables) && (__cpp_inline_variables >= 201606L) -# define _LIBCPP_INLINE_VAR inline +# define _LIBCPP_INLINE_VAR inline #else -# define _LIBCPP_INLINE_VAR +# define _LIBCPP_INLINE_VAR #endif #ifdef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1009,6 +1079,14 @@ template <unsigned> struct __static_assert_check {}; # define _LIBCPP_EXPLICIT_MOVE(x) (x) #endif +#ifndef _LIBCPP_CONSTEXPR_IF_NODEBUG +#if defined(_LIBCPP_DEBUG) || defined(_LIBCPP_HAS_NO_CXX14_CONSTEXPR) +#define _LIBCPP_CONSTEXPR_IF_NODEBUG +#else +#define _LIBCPP_CONSTEXPR_IF_NODEBUG constexpr +#endif +#endif + #ifndef _LIBCPP_HAS_NO_ASAN _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( const void *, const void *, const void *, const void *); @@ -1018,8 +1096,10 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( // g++ and cl.exe have RTTI on by default and define a macro when it is. // g++ only defines the macro in 4.3.2 and onwards. #if !defined(_LIBCPP_NO_RTTI) -# if defined(__GNUC__) && ((__GNUC__ >= 5) || (__GNUC__ == 4 && \ - (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && !defined(__GXX_RTTI) +# if defined(__GNUC__) && \ + ((__GNUC__ >= 5) || \ + (__GNUC__ == 4 && (__GNUC_MINOR__ >= 3 || __GNUC_PATCHLEVEL__ >= 2))) && \ + !defined(__GXX_RTTI) # define _LIBCPP_NO_RTTI # elif defined(_LIBCPP_COMPILER_MSVC) && !defined(_CPPRTTI) # define _LIBCPP_NO_RTTI @@ -1027,7 +1107,7 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #endif #ifndef _LIBCPP_WEAK -# define _LIBCPP_WEAK __attribute__((__weak__)) +#define _LIBCPP_WEAK __attribute__((__weak__)) #endif // Thread API @@ -1035,36 +1115,36 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && \ !defined(_LIBCPP_HAS_THREAD_API_WIN32) && \ !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -# if defined(__FreeBSD__) || \ - defined(__Fuchsia__) || \ - defined(__NetBSD__) || \ - defined(__linux__) || \ - defined(__APPLE__) || \ - defined(__CloudABI__) || \ - defined(__sun__) || \ - (defined(__MINGW32__) && __libcpp_has_include(<pthread.h>)) || \ - defined(__OpenBSD__) -# define _LIBCPP_HAS_THREAD_API_PTHREAD -# elif defined(_LIBCPP_WIN32API) -# define _LIBCPP_HAS_THREAD_API_WIN32 -# else -# error "No thread API" -# endif // _LIBCPP_HAS_THREAD_API +# if defined(__FreeBSD__) || \ + defined(__Fuchsia__) || \ + defined(__NetBSD__) || \ + defined(__linux__) || \ + defined(__APPLE__) || \ + defined(__CloudABI__) || \ + defined(__sun__) || \ + (defined(__MINGW32__) && __has_include(<pthread.h>)) || \ + defined(__OpenBSD__) +# define _LIBCPP_HAS_THREAD_API_PTHREAD +# elif defined(_LIBCPP_WIN32API) +# define _LIBCPP_HAS_THREAD_API_WIN32 +# else +# error "No thread API" +# endif // _LIBCPP_HAS_THREAD_API #endif // _LIBCPP_HAS_NO_THREADS #if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_PTHREAD) -# error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ - _LIBCPP_HAS_NO_THREADS is not defined. +#error _LIBCPP_HAS_THREAD_API_PTHREAD may only be defined when \ + _LIBCPP_HAS_NO_THREADS is not defined. #endif #if defined(_LIBCPP_HAS_NO_THREADS) && defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -# error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \ - _LIBCPP_HAS_NO_THREADS is defined. +#error _LIBCPP_HAS_THREAD_API_EXTERNAL may not be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. #endif #if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) -# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ - _LIBCPP_HAS_NO_THREADS is defined. +#error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ + _LIBCPP_HAS_NO_THREADS is defined. #endif // Systems that use capability-based security (FreeBSD with Capsicum, @@ -1095,9 +1175,9 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #endif #if __has_feature(cxx_atomic) || __has_extension(c_atomic) || __has_keyword(_Atomic) -#define _LIBCPP_HAS_C_ATOMIC_IMP +# define _LIBCPP_HAS_C_ATOMIC_IMP #elif _GNUC_VER > 407 -#define _LIBCPP_HAS_GCC_ATOMIC_IMP +# define _LIBCPP_HAS_GCC_ATOMIC_IMP #endif #if (!defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)) \ @@ -1110,139 +1190,144 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #endif #if defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) -#if defined(__clang__) && __has_attribute(acquire_capability) +# if defined(__clang__) && __has_attribute(acquire_capability) // Work around the attribute handling in clang. When both __declspec and // __attribute__ are present, the processing goes awry preventing the definition // of the types. -#if !defined(_LIBCPP_OBJECT_FORMAT_COFF) -#define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS -#endif -#endif +# if !defined(_LIBCPP_OBJECT_FORMAT_COFF) +# define _LIBCPP_HAS_THREAD_SAFETY_ANNOTATIONS +# endif +# endif #endif #if __has_attribute(require_constant_initialization) -#define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) +# define _LIBCPP_SAFE_STATIC __attribute__((__require_constant_initialization__)) #else -#define _LIBCPP_SAFE_STATIC +# define _LIBCPP_SAFE_STATIC #endif #if !__has_builtin(__builtin_addressof) && _GNUC_VER < 700 -# define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF +#define _LIBCPP_HAS_NO_BUILTIN_ADDRESSOF #endif #if !defined(_LIBCPP_HAS_NO_OFF_T_FUNCTIONS) -#if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) -#define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS -#endif +# if defined(_LIBCPP_MSVCRT) || defined(_NEWLIB_VERSION) +# define _LIBCPP_HAS_NO_OFF_T_FUNCTIONS +# endif #endif #if __has_attribute(diagnose_if) && !defined(_LIBCPP_DISABLE_ADDITIONAL_DIAGNOSTICS) -# define _LIBCPP_DIAGNOSE_WARNING(...) \ - __attribute__((diagnose_if(__VA_ARGS__, "warning"))) -# define _LIBCPP_DIAGNOSE_ERROR(...) \ - __attribute__((diagnose_if(__VA_ARGS__, "error"))) +# define _LIBCPP_DIAGNOSE_WARNING(...) \ + __attribute__((diagnose_if(__VA_ARGS__, "warning"))) +# define _LIBCPP_DIAGNOSE_ERROR(...) \ + __attribute__((diagnose_if(__VA_ARGS__, "error"))) #else -# define _LIBCPP_DIAGNOSE_WARNING(...) -# define _LIBCPP_DIAGNOSE_ERROR(...) +# define _LIBCPP_DIAGNOSE_WARNING(...) +# define _LIBCPP_DIAGNOSE_ERROR(...) #endif #if __has_attribute(fallthough) || _GNUC_VER >= 700 // Use a function like macro to imply that it must be followed by a semicolon -#define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) +# define _LIBCPP_FALLTHROUGH() __attribute__((__fallthrough__)) #else -#define _LIBCPP_FALLTHROUGH() ((void)0) +# define _LIBCPP_FALLTHROUGH() ((void)0) #endif #if defined(_LIBCPP_ABI_MICROSOFT) && \ - (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases)) -# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) + (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases)) +# define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases) #else -# define _LIBCPP_DECLSPEC_EMPTY_BASES +# define _LIBCPP_DECLSPEC_EMPTY_BASES #endif #if defined(_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES) -# define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR -# define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS -# define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE -# define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS +#define _LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR +#define _LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS +#define _LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE +#define _LIBCPP_ENABLE_CXX17_REMOVED_BINDERS #endif // _LIBCPP_ENABLE_CXX17_REMOVED_FEATURES #if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611 -# define _LIBCPP_HAS_NO_DEDUCTION_GUIDES +#define _LIBCPP_HAS_NO_DEDUCTION_GUIDES #endif #if !__has_keyword(__is_aggregate) && (_GNUC_VER_NEW < 7001) -# define _LIBCPP_HAS_NO_IS_AGGREGATE +#define _LIBCPP_HAS_NO_IS_AGGREGATE #endif #if !defined(__cpp_coroutines) || __cpp_coroutines < 201703L -# define _LIBCPP_HAS_NO_COROUTINES +#define _LIBCPP_HAS_NO_COROUTINES #endif +// FIXME: Correct this macro when either (A) a feature test macro for the +// spaceship operator is provided, or (B) a compiler provides a complete +// implementation. +#define _LIBCPP_HAS_NO_SPACESHIP_OPERATOR + // Decide whether to use availability macros. #if !defined(_LIBCPP_BUILDING_LIBRARY) && \ !defined(_LIBCPP_DISABLE_AVAILABILITY) && \ __has_feature(attribute_availability_with_strict) && \ __has_feature(attribute_availability_in_templates) -#ifdef __APPLE__ -#define _LIBCPP_USE_AVAILABILITY_APPLE -#endif +# ifdef __APPLE__ +# define _LIBCPP_USE_AVAILABILITY_APPLE +# endif #endif // Define availability macros. #if defined(_LIBCPP_USE_AVAILABILITY_APPLE) -#define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) -#define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable)) -#define _LIBCPP_AVAILABILITY_BAD_ANY_CAST __attribute__((unavailable)) -#define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -#define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ - __attribute__((availability(macosx,strict,introduced=10.12))) \ - __attribute__((availability(ios,strict,introduced=10.0))) \ - __attribute__((availability(tvos,strict,introduced=10.0))) \ - __attribute__((availability(watchos,strict,introduced=3.0))) -#define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ - __attribute__((availability(ios,strict,introduced=6.0))) -#define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -#define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) -#define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ - __attribute__((availability(macosx,strict,introduced=10.9))) \ - __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST __attribute__((unavailable)) +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE \ + __attribute__((availability(macosx,strict,introduced=10.12))) \ + __attribute__((availability(ios,strict,introduced=10.0))) \ + __attribute__((availability(tvos,strict,introduced=10.0))) \ + __attribute__((availability(watchos,strict,introduced=3.0))) +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR \ + __attribute__((availability(ios,strict,introduced=6.0))) +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR \ + __attribute__((availability(macosx,strict,introduced=10.9))) \ + __attribute__((availability(ios,strict,introduced=7.0))) #else -#define _LIBCPP_AVAILABILITY_SHARED_MUTEX -#define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS -#define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH -#define _LIBCPP_AVAILABILITY_BAD_ANY_CAST -#define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS -#define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE -#define _LIBCPP_AVAILABILITY_FUTURE_ERROR -#define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE -#define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY -#define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR +# define _LIBCPP_AVAILABILITY_SHARED_MUTEX +# define _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS +# define _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH +# define _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_UNCAUGHT_EXCEPTIONS +# define _LIBCPP_AVAILABILITY_SIZED_NEW_DELETE +# define _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE +# define _LIBCPP_AVAILABILITY_LOCALE_CATEGORY +# define _LIBCPP_AVAILABILITY_ATOMIC_SHARED_PTR #endif // Define availability that depends on _LIBCPP_NO_EXCEPTIONS. #ifdef _LIBCPP_NO_EXCEPTIONS -#define _LIBCPP_AVAILABILITY_DYNARRAY -#define _LIBCPP_AVAILABILITY_FUTURE -#define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_DYNARRAY +# define _LIBCPP_AVAILABILITY_FUTURE +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST #else -#define _LIBCPP_AVAILABILITY_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH -#define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR -#define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST \ - _LIBCPP_AVAILABILITY_BAD_ANY_CAST +# define _LIBCPP_AVAILABILITY_DYNARRAY _LIBCPP_AVAILABILITY_BAD_ARRAY_LENGTH +# define _LIBCPP_AVAILABILITY_FUTURE _LIBCPP_AVAILABILITY_FUTURE_ERROR +# define _LIBCPP_AVAILABILITY_THROW_BAD_ANY_CAST \ + _LIBCPP_AVAILABILITY_BAD_ANY_CAST #endif // Availability of stream API in the dylib got dropped and re-added. The @@ -1262,38 +1347,40 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container( #endif #if defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO) -# define _LIBCPP_PUSH_MACROS -# define _LIBCPP_POP_MACROS +# define _LIBCPP_PUSH_MACROS +# define _LIBCPP_POP_MACROS #else // Don't warn about macro conflicts when we can restore them at the // end of the header. -# ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS -# define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS -# endif -# if defined(_LIBCPP_COMPILER_MSVC) -# define _LIBCPP_PUSH_MACROS \ - __pragma(push_macro("min")) \ - __pragma(push_macro("max")) -# define _LIBCPP_POP_MACROS \ - __pragma(pop_macro("min")) \ - __pragma(pop_macro("max")) -# else -# define _LIBCPP_PUSH_MACROS \ - _Pragma("push_macro(\"min\")") \ - _Pragma("push_macro(\"max\")") -# define _LIBCPP_POP_MACROS \ - _Pragma("pop_macro(\"min\")") \ - _Pragma("pop_macro(\"max\")") -# endif +# ifndef _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS +# define _LIBCPP_DISABLE_MACRO_CONFLICT_WARNINGS +# endif +# if defined(_LIBCPP_COMPILER_MSVC) +# define _LIBCPP_PUSH_MACROS \ + __pragma(push_macro("min")) \ + __pragma(push_macro("max")) +# define _LIBCPP_POP_MACROS \ + __pragma(pop_macro("min")) \ + __pragma(pop_macro("max")) +# else +# define _LIBCPP_PUSH_MACROS \ + _Pragma("push_macro(\"min\")") \ + _Pragma("push_macro(\"max\")") +# define _LIBCPP_POP_MACROS \ + _Pragma("pop_macro(\"min\")") \ + _Pragma("pop_macro(\"max\")") +# endif #endif // defined(_LIBCPP_HAS_NO_PRAGMA_PUSH_POP_MACRO) -#if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) -# if defined(_DLL) -# pragma(lib, "c++.lib") -# else -# pragma(lib, "libc++.lib") -# endif -#endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +#ifndef _LIBCPP_NO_AUTO_LINK +# if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +# if defined(_DLL) +# pragma comment(lib, "c++.lib") +# else +# pragma comment(lib, "libc++.lib") +# endif +# endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_BUILDING_LIBRARY) +#endif // _LIBCPP_NO_AUTO_LINK #endif // __cplusplus diff --git a/lib/libcxx/include/__locale b/lib/libcxx/include/__locale index bface07aa68..79063e08c85 100644 --- a/lib/libcxx/include/__locale +++ b/lib/libcxx/include/__locale @@ -24,11 +24,7 @@ #elif defined(_AIX) # include <support/ibm/xlocale.h> #elif defined(__ANDROID__) -// Android gained the locale aware functions in L (API level 21) -# include <android/api-level.h> -# if __ANDROID_API__ <= 20 -# include <support/android/locale_bionic.h> -# endif +# include <support/android/locale_bionic.h> #elif defined(__sun__) # include <xlocale.h> # include <support/solaris/xlocale.h> @@ -473,7 +469,7 @@ public: static const mask alnum = alpha | digit; static const mask graph = alnum | punct; - _LIBCPP_ALWAYS_INLINE ctype_base() {} + _LIBCPP_INLINE_VISIBILITY ctype_base() {} }; template <class _CharT> class _LIBCPP_TEMPLATE_VIS ctype; @@ -486,77 +482,77 @@ class _LIBCPP_TYPE_VIS ctype<wchar_t> public: typedef wchar_t char_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit ctype(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool is(mask __m, char_type __c) const { return do_is(__m, __c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const { return do_is(__low, __high, __vec); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* scan_is(mask __m, const char_type* __low, const char_type* __high) const { return do_scan_is(__m, __low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const { return do_scan_not(__m, __low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type toupper(char_type __c) const { return do_toupper(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* toupper(char_type* __low, const char_type* __high) const { return do_toupper(__low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type tolower(char_type __c) const { return do_tolower(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* tolower(char_type* __low, const char_type* __high) const { return do_tolower(__low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type widen(char __c) const { return do_widen(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char* widen(const char* __low, const char* __high, char_type* __to) const { return do_widen(__low, __high, __to); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const { return do_narrow(__low, __high, __dfault, __to); @@ -591,13 +587,13 @@ public: explicit ctype(const mask* __tab = 0, bool __del = false, size_t __refs = 0); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool is(mask __m, char_type __c) const { return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false; } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* is(const char_type* __low, const char_type* __high, mask* __vec) const { for (; __low != __high; ++__low, ++__vec) @@ -605,7 +601,7 @@ public: return __low; } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* scan_is (mask __m, const char_type* __low, const char_type* __high) const { for (; __low != __high; ++__low) @@ -614,7 +610,7 @@ public: return __low; } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* scan_not(mask __m, const char_type* __low, const char_type* __high) const { for (; __low != __high; ++__low) @@ -623,49 +619,49 @@ public: return __low; } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type toupper(char_type __c) const { return do_toupper(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* toupper(char_type* __low, const char_type* __high) const { return do_toupper(__low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type tolower(char_type __c) const { return do_tolower(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char_type* tolower(char_type* __low, const char_type* __high) const { return do_tolower(__low, __high); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char_type widen(char __c) const { return do_widen(__c); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char* widen(const char* __low, const char* __high, char_type* __to) const { return do_widen(__low, __high, __to); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY char narrow(char_type __c, char __dfault) const { return do_narrow(__c, __dfault); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY const char* narrow(const char_type* __low, const char_type* __high, char __dfault, char* __to) const { return do_narrow(__low, __high, __dfault, __to); @@ -678,7 +674,7 @@ public: #else static const size_t table_size = 256; // FIXME: Don't hardcode this. #endif - _LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;} + _LIBCPP_INLINE_VISIBILITY const mask* table() const _NOEXCEPT {return __tab_;} static const mask* classic_table() _NOEXCEPT; #if defined(__GLIBC__) || defined(__EMSCRIPTEN__) static const int* __classic_upper_table() _NOEXCEPT; @@ -858,7 +854,7 @@ tolower(_CharT __c, const locale& __loc) class _LIBCPP_TYPE_VIS codecvt_base { public: - _LIBCPP_ALWAYS_INLINE codecvt_base() {} + _LIBCPP_INLINE_VISIBILITY codecvt_base() {} enum result {ok, partial, error, noconv}; }; @@ -878,11 +874,11 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result out(state_type& __st, 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 @@ -890,14 +886,14 @@ public: return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { return do_unshift(__st, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result in(state_type& __st, 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 @@ -905,25 +901,25 @@ public: return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int encoding() const _NOEXCEPT { return do_encoding(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { return do_length(__st, __frm, __end, __mx); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int max_length() const _NOEXCEPT { return do_max_length(); @@ -932,7 +928,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} @@ -967,7 +963,7 @@ public: explicit codecvt(size_t __refs = 0); - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result out(state_type& __st, 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 @@ -975,14 +971,14 @@ public: return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { return do_unshift(__st, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result in(state_type& __st, 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 @@ -990,25 +986,25 @@ public: return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int encoding() const _NOEXCEPT { return do_encoding(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { return do_length(__st, __frm, __end, __mx); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int max_length() const _NOEXCEPT { return do_max_length(); @@ -1047,11 +1043,11 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result out(state_type& __st, 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 @@ -1059,14 +1055,14 @@ public: return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { return do_unshift(__st, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result in(state_type& __st, 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 @@ -1074,25 +1070,25 @@ public: return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int encoding() const _NOEXCEPT { return do_encoding(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { return do_length(__st, __frm, __end, __mx); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int max_length() const _NOEXCEPT { return do_max_length(); @@ -1101,7 +1097,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} @@ -1133,11 +1129,11 @@ public: typedef char extern_type; typedef mbstate_t state_type; - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result out(state_type& __st, 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 @@ -1145,14 +1141,14 @@ public: return do_out(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result unshift(state_type& __st, extern_type* __to, extern_type* __to_end, extern_type*& __to_nxt) const { return do_unshift(__st, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY result in(state_type& __st, 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 @@ -1160,25 +1156,25 @@ public: return do_in(__st, __frm, __frm_end, __frm_nxt, __to, __to_end, __to_nxt); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int encoding() const _NOEXCEPT { return do_encoding(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY bool always_noconv() const _NOEXCEPT { return do_always_noconv(); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int length(state_type& __st, const extern_type* __frm, const extern_type* __end, size_t __mx) const { return do_length(__st, __frm, __end, __mx); } - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY int max_length() const _NOEXCEPT { return do_max_length(); @@ -1187,7 +1183,7 @@ public: static locale::id id; protected: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt(const char*, size_t __refs = 0) : locale::facet(__refs) {} @@ -1214,10 +1210,10 @@ class _LIBCPP_TEMPLATE_VIS codecvt_byname : public codecvt<_InternT, _ExternT, _StateT> { public: - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt_byname(const char* __nm, size_t __refs = 0) : codecvt<_InternT, _ExternT, _StateT>(__nm, __refs) {} - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY explicit codecvt_byname(const string& __nm, size_t __refs = 0) : codecvt<_InternT, _ExternT, _StateT>(__nm.c_str(), __refs) {} protected: @@ -1248,7 +1244,7 @@ template <> struct __narrow_to_utf8<8> { template <class _OutputIterator, class _CharT> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { @@ -1262,13 +1258,13 @@ template <> struct __narrow_to_utf8<16> : public codecvt<char16_t, char, mbstate_t> { - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} ~__narrow_to_utf8(); template <class _OutputIterator, class _CharT> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { @@ -1296,13 +1292,13 @@ template <> struct __narrow_to_utf8<32> : public codecvt<char32_t, char, mbstate_t> { - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY __narrow_to_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} ~__narrow_to_utf8(); template <class _OutputIterator, class _CharT> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const _CharT* __wb, const _CharT* __we) const { @@ -1338,7 +1334,7 @@ template <> struct __widen_from_utf8<8> { template <class _OutputIterator> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { @@ -1352,13 +1348,13 @@ template <> struct __widen_from_utf8<16> : public codecvt<char16_t, char, mbstate_t> { - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt<char16_t, char, mbstate_t>(1) {} ~__widen_from_utf8(); template <class _OutputIterator> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { @@ -1386,13 +1382,13 @@ template <> struct __widen_from_utf8<32> : public codecvt<char32_t, char, mbstate_t> { - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY __widen_from_utf8() : codecvt<char32_t, char, mbstate_t>(1) {} ~__widen_from_utf8(); template <class _OutputIterator> - _LIBCPP_ALWAYS_INLINE + _LIBCPP_INLINE_VISIBILITY _OutputIterator operator()(_OutputIterator __s, const char* __nb, const char* __ne) const { @@ -1430,11 +1426,11 @@ public: explicit numpunct(size_t __refs = 0); - _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} - _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} - _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} - _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} - _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} + _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} + _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} + _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} static locale::id id; @@ -1461,11 +1457,11 @@ public: explicit numpunct(size_t __refs = 0); - _LIBCPP_ALWAYS_INLINE char_type decimal_point() const {return do_decimal_point();} - _LIBCPP_ALWAYS_INLINE char_type thousands_sep() const {return do_thousands_sep();} - _LIBCPP_ALWAYS_INLINE string grouping() const {return do_grouping();} - _LIBCPP_ALWAYS_INLINE string_type truename() const {return do_truename();} - _LIBCPP_ALWAYS_INLINE string_type falsename() const {return do_falsename();} + _LIBCPP_INLINE_VISIBILITY char_type decimal_point() const {return do_decimal_point();} + _LIBCPP_INLINE_VISIBILITY char_type thousands_sep() const {return do_thousands_sep();} + _LIBCPP_INLINE_VISIBILITY string grouping() const {return do_grouping();} + _LIBCPP_INLINE_VISIBILITY string_type truename() const {return do_truename();} + _LIBCPP_INLINE_VISIBILITY string_type falsename() const {return do_falsename();} static locale::id id; diff --git a/lib/libcxx/include/stdio.h b/lib/libcxx/include/stdio.h index 616d0a02d6a..b2e7cc28c98 100644 --- a/lib/libcxx/include/stdio.h +++ b/lib/libcxx/include/stdio.h @@ -109,13 +109,6 @@ void perror(const char* s); #ifdef __cplusplus -// snprintf -#if defined(_LIBCPP_MSVCRT_LIKE) -extern "C" { -int vasprintf(char **sptr, const char *__restrict fmt, va_list ap); -} -#endif - #undef getc #undef putc #undef clearerr diff --git a/lib/libcxx/include/support/newlib/xlocale.h b/lib/libcxx/include/support/newlib/xlocale.h index 2afb95e48bf..2ce6438b556 100644 --- a/lib/libcxx/include/support/newlib/xlocale.h +++ b/lib/libcxx/include/support/newlib/xlocale.h @@ -20,9 +20,9 @@ #if !defined(__NEWLIB__) || __NEWLIB__ < 2 || \ __NEWLIB__ == 2 && __NEWLIB_MINOR__ < 5 #include <support/xlocale/__nop_locale_mgmt.h> -#endif #include <support/xlocale/__posix_l_fallback.h> #endif +#endif #include <support/xlocale/__strtonum_fallback.h> #endif // _NEWLIB_VERSION diff --git a/lib/libcxx/shlib_version b/lib/libcxx/shlib_version index b52599a164f..c6e3f4d3fc0 100644 --- a/lib/libcxx/shlib_version +++ b/lib/libcxx/shlib_version @@ -1,2 +1,2 @@ major=2 -minor=0 +minor=1 diff --git a/lib/libcxx/src/experimental/filesystem/directory_iterator.cpp b/lib/libcxx/src/experimental/filesystem/directory_iterator.cpp deleted file mode 100644 index fa217ba7a12..00000000000 --- a/lib/libcxx/src/experimental/filesystem/directory_iterator.cpp +++ /dev/null @@ -1,256 +0,0 @@ -#include "experimental/filesystem" -#include <dirent.h> -#include <errno.h> - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM - -namespace { namespace detail { - -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; - } - __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec)); - return false; -} - -template <class ...Args> -inline bool set_or_throw(std::error_code& my_ec, - std::error_code* user_ec, - const char* msg, Args&&... args) -{ - if (user_ec) { - *user_ec = my_ec; - return true; - } - __libcpp_throw(filesystem_error(msg, std::forward<Args>(args)..., my_ec)); - return false; -} - -typedef path::string_type string_type; - - -inline 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 - if ((dir_entry_ptr = ::readdir(dir_stream)) == nullptr) { - ec = capture_errno(); - return {}; - } else { - ec.clear(); - return dir_entry_ptr->d_name; - } -} - -}} // namespace detail - -using detail::set_or_throw; - -class __dir_stream { -public: - __dir_stream() = delete; - __dir_stream& operator=(const __dir_stream&) = delete; - - __dir_stream(__dir_stream&& other) noexcept - : __stream_(other.__stream_), __root_(std::move(other.__root_)), - __entry_(std::move(other.__entry_)) - { - other.__stream_ = nullptr; - } - - - __dir_stream(const path& root, directory_options opts, error_code& ec) - : __stream_(nullptr), - __root_(root) - { - if ((__stream_ = ::opendir(root.c_str())) == nullptr) { - ec = detail::capture_errno(); - const bool allow_eacess = - bool(opts & directory_options::skip_permission_denied); - if (allow_eacess && ec.value() == EACCES) - ec.clear(); - return; - } - advance(ec); - } - - ~__dir_stream() noexcept - { if (__stream_) close(); } - - bool good() const noexcept { return __stream_ != nullptr; } - - bool advance(error_code &ec) { - while (true) { - auto str = detail::posix_readdir(__stream_, ec); - if (str == "." || str == "..") { - continue; - } else if (ec || str.empty()) { - close(); - return false; - } else { - __entry_.assign(__root_ / str); - return true; - } - } - } -private: - std::error_code close() noexcept { - std::error_code m_ec; - if (::closedir(__stream_) == -1) - m_ec = detail::capture_errno(); - __stream_ = nullptr; - return m_ec; - } - - DIR * __stream_{nullptr}; -public: - path __root_; - directory_entry __entry_; -}; - -// directory_iterator - -directory_iterator::directory_iterator(const path& p, error_code *ec, - directory_options opts) -{ - std::error_code m_ec; - __imp_ = make_shared<__dir_stream>(p, opts, m_ec); - if (ec) *ec = m_ec; - if (!__imp_->good()) { - __imp_.reset(); - if (m_ec) - set_or_throw(m_ec, ec, - "directory_iterator::directory_iterator(...)", p); - } -} - -directory_iterator& directory_iterator::__increment(error_code *ec) -{ - _LIBCPP_ASSERT(__imp_, "Attempting to increment an invalid iterator"); - std::error_code m_ec; - if (!__imp_->advance(m_ec)) { - __imp_.reset(); - if (m_ec) - set_or_throw(m_ec, ec, "directory_iterator::operator++()"); - } else { - if (ec) ec->clear(); - } - return *this; - -} - -directory_entry const& directory_iterator::__deref() const { - _LIBCPP_ASSERT(__imp_, "Attempting to dereference an invalid iterator"); - return __imp_->__entry_; -} - -// recursive_directory_iterator - -struct recursive_directory_iterator::__shared_imp { - stack<__dir_stream> __stack_; - directory_options __options_; -}; - -recursive_directory_iterator::recursive_directory_iterator(const path& p, - directory_options opt, error_code *ec) - : __imp_(nullptr), __rec_(true) -{ - if (ec) ec->clear(); - std::error_code m_ec; - __dir_stream new_s(p, opt, m_ec); - if (m_ec) set_or_throw(m_ec, ec, "recursive_directory_iterator", p); - if (m_ec || !new_s.good()) return; - - __imp_ = _VSTD::make_shared<__shared_imp>(); - __imp_->__options_ = opt; - __imp_->__stack_.push(_VSTD::move(new_s)); -} - -void recursive_directory_iterator::__pop(error_code* ec) -{ - _LIBCPP_ASSERT(__imp_, "Popping the end iterator"); - if (ec) ec->clear(); - __imp_->__stack_.pop(); - if (__imp_->__stack_.size() == 0) - __imp_.reset(); - else - __advance(ec); -} - -directory_options recursive_directory_iterator::options() const { - return __imp_->__options_; -} - -int recursive_directory_iterator::depth() const { - return __imp_->__stack_.size() - 1; -} - -const directory_entry& recursive_directory_iterator::__deref() const { - return __imp_->__stack_.top().__entry_; -} - -recursive_directory_iterator& -recursive_directory_iterator::__increment(error_code *ec) -{ - if (ec) ec->clear(); - if (recursion_pending()) { - if (__try_recursion(ec) || (ec && *ec)) - return *this; - } - __rec_ = true; - __advance(ec); - return *this; -} - -void recursive_directory_iterator::__advance(error_code* ec) { - // REQUIRES: ec must be cleared before calling this function. - const directory_iterator end_it; - auto& stack = __imp_->__stack_; - std::error_code m_ec; - while (stack.size() > 0) { - if (stack.top().advance(m_ec)) - return; - if (m_ec) break; - stack.pop(); - } - __imp_.reset(); - if (m_ec) - set_or_throw(m_ec, ec, "recursive_directory_iterator::operator++()"); -} - -bool recursive_directory_iterator::__try_recursion(error_code *ec) { - - bool rec_sym = - bool(options() & directory_options::follow_directory_symlink); - auto& curr_it = __imp_->__stack_.top(); - - if (is_directory(curr_it.__entry_.status()) && - (!is_symlink(curr_it.__entry_.symlink_status()) || rec_sym)) - { - std::error_code m_ec; - __dir_stream new_it(curr_it.__entry_.path(), __imp_->__options_, m_ec); - if (new_it.good()) { - __imp_->__stack_.push(_VSTD::move(new_it)); - return true; - } - if (m_ec) { - __imp_.reset(); - set_or_throw(m_ec, ec, - "recursive_directory_iterator::operator++()"); - } - } - return false; -} - - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/lib/libcxx/src/experimental/filesystem/filesystem_time_helper.h b/lib/libcxx/src/experimental/filesystem/filesystem_time_helper.h deleted file mode 100644 index a60fdef5f0d..00000000000 --- a/lib/libcxx/src/experimental/filesystem/filesystem_time_helper.h +++ /dev/null @@ -1,173 +0,0 @@ -//===----------------------------------------------------------------------===//// -// -// 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/lib/libcxx/src/experimental/filesystem/operations.cpp b/lib/libcxx/src/experimental/filesystem/operations.cpp deleted file mode 100644 index 369996fcbe6..00000000000 --- a/lib/libcxx/src/experimental/filesystem/operations.cpp +++ /dev/null @@ -1,794 +0,0 @@ -//===--------------------- filesystem/ops.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 "iterator" -#include "fstream" -#include "type_traits" -#include "random" /* for unique_path */ -#include "cstdlib" -#include "climits" - -#include <unistd.h> -#include <sys/stat.h> -#include <sys/statvfs.h> -#include <fcntl.h> /* values for fchmodat */ -#if !defined(UTIME_OMIT) -#include <sys/time.h> // for ::utimes as used in __last_write_time -#endif - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM - -filesystem_error::~filesystem_error() {} - - -// POSIX HELPERS - -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; -} - -void set_or_throw(std::error_code const& m_ec, std::error_code* ec, - const char* msg, path const& p = {}, path const& p2 = {}) -{ - if (ec) { - *ec = m_ec; - } else { - string msg_s("std::experimental::filesystem::"); - msg_s += msg; - __libcpp_throw(filesystem_error(msg_s, p, p2, m_ec)); - } -} - -void set_or_throw(std::error_code* ec, const char* msg, - path const& p = {}, path const& p2 = {}) -{ - return set_or_throw(capture_errno(), ec, msg, p, p2); -} - -perms posix_get_perms(const struct ::stat & st) noexcept { - return static_cast<perms>(st.st_mode) & perms::mask; -} - -::mode_t posix_convert_perms(perms prms) { - return static_cast< ::mode_t>(prms & perms::mask); -} - -file_status create_file_status(std::error_code& m_ec, path const& p, - struct ::stat& path_stat, - std::error_code* ec) -{ - if (ec) *ec = m_ec; - if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { - return file_status(file_type::not_found); - } - else if (m_ec) { - set_or_throw(m_ec, ec, "posix_stat", p); - return file_status(file_type::none); - } - // else - - file_status fs_tmp; - auto const mode = path_stat.st_mode; - if (S_ISLNK(mode)) fs_tmp.type(file_type::symlink); - else if (S_ISREG(mode)) fs_tmp.type(file_type::regular); - else if (S_ISDIR(mode)) fs_tmp.type(file_type::directory); - else if (S_ISBLK(mode)) fs_tmp.type(file_type::block); - else if (S_ISCHR(mode)) fs_tmp.type(file_type::character); - else if (S_ISFIFO(mode)) fs_tmp.type(file_type::fifo); - else if (S_ISSOCK(mode)) fs_tmp.type(file_type::socket); - else fs_tmp.type(file_type::unknown); - - fs_tmp.permissions(detail::posix_get_perms(path_stat)); - return fs_tmp; -} - -file_status posix_stat(path const & p, struct ::stat& path_stat, - std::error_code* ec) -{ - std::error_code m_ec; - if (::stat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); - return create_file_status(m_ec, p, path_stat, ec); -} - -file_status posix_stat(path const & p, std::error_code* ec) { - struct ::stat path_stat; - return posix_stat(p, path_stat, ec); -} - -file_status posix_lstat(path const & p, struct ::stat & path_stat, - std::error_code* ec) -{ - std::error_code m_ec; - if (::lstat(p.c_str(), &path_stat) == -1) - m_ec = detail::capture_errno(); - return create_file_status(m_ec, p, path_stat, ec); -} - -file_status posix_lstat(path const & p, std::error_code* ec) { - struct ::stat path_stat; - return posix_lstat(p, path_stat, ec); -} - -bool stat_equivalent(struct ::stat& st1, struct ::stat& st2) { - return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); -} - -// DETAIL::MISC - - -bool copy_file_impl(const path& from, const path& to, perms from_perms, - std::error_code *ec) -{ - std::ifstream in(from.c_str(), std::ios::binary); - std::ofstream out(to.c_str(), std::ios::binary); - - if (in.good() && out.good()) { - using InIt = std::istreambuf_iterator<char>; - using OutIt = std::ostreambuf_iterator<char>; - InIt bin(in); - InIt ein; - OutIt bout(out); - std::copy(bin, ein, bout); - } - if (out.fail() || in.fail()) { - set_or_throw(make_error_code(errc::operation_not_permitted), - ec, "copy_file", from, to); - return false; - } - __permissions(to, from_perms, ec); - // TODO what if permissions fails? - return true; -} - -}} // end namespace detail - -using detail::set_or_throw; - -path __canonical(path const & orig_p, const path& base, std::error_code *ec) -{ - path p = absolute(orig_p, base); - char buff[PATH_MAX + 1]; - char *ret; - if ((ret = ::realpath(p.c_str(), buff)) == nullptr) { - set_or_throw(ec, "canonical", orig_p, base); - return {}; - } - if (ec) ec->clear(); - return {ret}; -} - -void __copy(const path& from, const path& to, copy_options options, - std::error_code *ec) -{ - const bool sym_status = bool(options & - (copy_options::create_symlinks | copy_options::skip_symlinks)); - - const bool sym_status2 = bool(options & - copy_options::copy_symlinks); - - std::error_code m_ec; - struct ::stat f_st = {}; - const file_status f = sym_status || sym_status2 - ? detail::posix_lstat(from, f_st, &m_ec) - : detail::posix_stat(from, f_st, &m_ec); - if (m_ec) - return set_or_throw(m_ec, ec, "copy", from, to); - - struct ::stat t_st = {}; - const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec) - : detail::posix_stat(to, t_st, &m_ec); - - if (not status_known(t)) - return set_or_throw(m_ec, ec, "copy", from, to); - - if (!exists(f) || is_other(f) || is_other(t) - || (is_directory(f) && is_regular_file(t)) - || detail::stat_equivalent(f_st, t_st)) - { - return set_or_throw(make_error_code(errc::function_not_supported), - ec, "copy", from, to); - } - - if (ec) ec->clear(); - - if (is_symlink(f)) { - if (bool(copy_options::skip_symlinks & options)) { - // do nothing - } else if (not exists(t)) { - __copy_symlink(from, to, ec); - } else { - set_or_throw(make_error_code(errc::file_exists), - ec, "copy", from, to); - } - return; - } - else if (is_regular_file(f)) { - if (bool(copy_options::directories_only & options)) { - // do nothing - } - else if (bool(copy_options::create_symlinks & options)) { - __create_symlink(from, to, ec); - } - else if (bool(copy_options::create_hard_links & options)) { - __create_hard_link(from, to, ec); - } - else if (is_directory(t)) { - __copy_file(from, to / from.filename(), options, ec); - } else { - __copy_file(from, to, options, ec); - } - return; - } - else if (is_directory(f)) { - if (not bool(copy_options::recursive & options) && - bool(copy_options::__in_recursive_copy & options)) - { - return; - } - - if (!exists(t)) { - // create directory to with attributes from 'from'. - __create_directory(to, from, ec); - if (ec && *ec) { return; } - } - directory_iterator it = ec ? directory_iterator(from, *ec) - : directory_iterator(from); - if (ec && *ec) { return; } - std::error_code m_ec; - for (; it != directory_iterator(); it.increment(m_ec)) { - if (m_ec) return set_or_throw(m_ec, ec, "copy", from, to); - __copy(it->path(), to / it->path().filename(), - options | copy_options::__in_recursive_copy, ec); - if (ec && *ec) { return; } - } - } -} - - -bool __copy_file(const path& from, const path& to, copy_options options, - std::error_code *ec) -{ - if (ec) ec->clear(); - - std::error_code m_ec; - auto from_st = detail::posix_stat(from, &m_ec); - if (not is_regular_file(from_st)) { - if (not m_ec) - m_ec = make_error_code(errc::not_supported); - set_or_throw(m_ec, ec, "copy_file", from, to); - return false; - } - - auto to_st = detail::posix_stat(to, &m_ec); - if (!status_known(to_st)) { - set_or_throw(m_ec, ec, "copy_file", from, to); - return false; - } - - const bool to_exists = exists(to_st); - if (to_exists && bool(copy_options::skip_existing & options)) { - return false; - } - else if (to_exists && bool(copy_options::update_existing & options)) { - auto from_time = __last_write_time(from, ec); - if (ec && *ec) { return false; } - auto to_time = __last_write_time(to, ec); - if (ec && *ec) { return false; } - if (from_time <= to_time) { - return false; - } - return detail::copy_file_impl(from, to, from_st.permissions(), ec); - } - else if (!to_exists || bool(copy_options::overwrite_existing & options)) { - return detail::copy_file_impl(from, to, from_st.permissions(), ec); - } - else { - set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to); - return false; - } -} - -void __copy_symlink(const path& existing_symlink, const path& new_symlink, - std::error_code *ec) -{ - const path real_path(__read_symlink(existing_symlink, ec)); - if (ec && *ec) { return; } - // NOTE: proposal says you should detect if you should call - // create_symlink or create_directory_symlink. I don't think this - // is needed with POSIX - __create_symlink(real_path, new_symlink, ec); -} - - -bool __create_directories(const path& p, std::error_code *ec) -{ - std::error_code m_ec; - auto const st = detail::posix_stat(p, &m_ec); - if (!status_known(st)) { - set_or_throw(m_ec, ec, "create_directories", p); - return false; - } - else if (is_directory(st)) { - if (ec) ec->clear(); - return false; - } - else if (exists(st)) { - set_or_throw(make_error_code(errc::file_exists), - ec, "create_directories", p); - return false; - } - - const path parent = p.parent_path(); - if (!parent.empty()) { - const file_status parent_st = status(parent, m_ec); - if (not status_known(parent_st)) { - set_or_throw(m_ec, ec, "create_directories", p); - return false; - } - if (not exists(parent_st)) { - __create_directories(parent, ec); - if (ec && *ec) { return false; } - } - } - return __create_directory(p, ec); -} - -bool __create_directory(const path& p, std::error_code *ec) -{ - if (ec) ec->clear(); - if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) - return true; - if (errno != EEXIST || !is_directory(p)) - set_or_throw(ec, "create_directory", p); - return false; -} - -bool __create_directory(path const & p, path const & attributes, - std::error_code *ec) -{ - struct ::stat attr_stat; - std::error_code mec; - auto st = detail::posix_stat(attributes, attr_stat, &mec); - if (!status_known(st)) { - set_or_throw(mec, ec, "create_directory", p, attributes); - return false; - } - if (ec) ec->clear(); - if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) - return true; - if (errno != EEXIST || !is_directory(p)) - set_or_throw(ec, "create_directory", p, attributes); - return false; -} - -void __create_directory_symlink(path const & from, path const & to, - std::error_code *ec){ - if (::symlink(from.c_str(), to.c_str()) != 0) - set_or_throw(ec, "create_directory_symlink", from, to); - else if (ec) - ec->clear(); -} - -void __create_hard_link(const path& from, const path& to, std::error_code *ec){ - if (::link(from.c_str(), to.c_str()) == -1) - set_or_throw(ec, "create_hard_link", from, to); - else if (ec) - ec->clear(); -} - -void __create_symlink(path const & from, path const & to, std::error_code *ec) { - - if (::symlink(from.c_str(), to.c_str()) == -1) - set_or_throw(ec, "create_symlink", from, to); - else if (ec) - ec->clear(); -} - -path __current_path(std::error_code *ec) { - auto size = ::pathconf(".", _PC_PATH_MAX); - _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size"); - - auto buff = std::unique_ptr<char[]>(new char[size + 1]); - char* ret; - if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr) { - set_or_throw(ec, "current_path"); - return {}; - } - if (ec) ec->clear(); - return {buff.get()}; -} - -void __current_path(const path& p, std::error_code *ec) { - if (::chdir(p.c_str()) == -1) - set_or_throw(ec, "current_path", p); - else if (ec) - ec->clear(); -} - -bool __equivalent(const path& p1, const path& p2, std::error_code *ec) -{ - std::error_code ec1, ec2; - struct ::stat st1 = {}; - struct ::stat st2 = {}; - auto s1 = detail::posix_stat(p1.native(), st1, &ec1); - 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 (ec) ec->clear(); - return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); -} - - -std::uintmax_t __file_size(const path& p, std::error_code *ec) -{ - std::error_code m_ec; - struct ::stat st; - file_status fst = detail::posix_stat(p, st, &m_ec); - if (!exists(fst) || !is_regular_file(fst)) { - if (!m_ec) - m_ec = make_error_code(errc::not_supported); - set_or_throw(m_ec, ec, "file_size", p); - return static_cast<uintmax_t>(-1); - } - // is_regular_file(p) == true - if (ec) ec->clear(); - return static_cast<std::uintmax_t>(st.st_size); -} - -std::uintmax_t __hard_link_count(const path& p, std::error_code *ec) -{ - std::error_code m_ec; - struct ::stat st; - detail::posix_stat(p, st, &m_ec); - if (m_ec) { - set_or_throw(m_ec, ec, "hard_link_count", p); - return static_cast<std::uintmax_t>(-1); - } - if (ec) ec->clear(); - return static_cast<std::uintmax_t>(st.st_nlink); -} - - -bool __fs_is_empty(const path& p, std::error_code *ec) -{ - if (ec) ec->clear(); - std::error_code m_ec; - struct ::stat pst; - auto st = detail::posix_stat(p, pst, &m_ec); - if (is_directory(st)) - return directory_iterator(p) == directory_iterator{}; - else if (is_regular_file(st)) - return static_cast<std::uintmax_t>(pst.st_size) == 0; - // else - set_or_throw(m_ec, ec, "is_empty", p); - return false; -} - - -namespace detail { namespace { - -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; -} - -constexpr long long min_seconds = file_time_type::duration::min().count() - / file_time_type::period::den; - -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 - - -file_time_type __last_write_time(const path& p, std::error_code *ec) -{ - std::error_code m_ec; - struct ::stat st; - detail::posix_stat(p, st, &m_ec); - if (m_ec) { - set_or_throw(m_ec, ec, "last_write_time", p); - return file_time_type::min(); - } - if (ec) ec->clear(); - return file_time_type::clock::from_time_t(st.st_mtime); -} - -void __last_write_time(const path& p, file_time_type new_time, - std::error_code *ec) -{ - using namespace std::chrono; - std::error_code m_ec; - - // We can use the presence of UTIME_OMIT to detect platforms that do not - // provide utimensat. -#if !defined(UTIME_OMIT) - // This implementation has a race condition between determining the - // last access time and attempting to set it to the same value using - // ::utimes - struct ::stat st; - file_status fst = detail::posix_stat(p, st, &m_ec); - if (m_ec && !status_known(fst)) { - set_or_throw(m_ec, ec, "last_write_time", p); - return; - } - struct ::timeval tbuf[2]; - tbuf[0].tv_sec = st.st_atime; - tbuf[0].tv_usec = 0; - const bool overflowed = !detail::set_times_checked<microseconds>( - &tbuf[1].tv_sec, &tbuf[1].tv_usec, new_time); - - if (overflowed) { - set_or_throw(make_error_code(errc::invalid_argument), ec, - "last_write_time", p); - return; - } - if (::utimes(p.c_str(), tbuf) == -1) { - m_ec = detail::capture_errno(); - } -#else - struct ::timespec tbuf[2]; - tbuf[0].tv_sec = 0; - tbuf[0].tv_nsec = UTIME_OMIT; - - const bool overflowed = !detail::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), - ec, "last_write_time", p); - return; - } - if (::utimensat(AT_FDCWD, p.c_str(), tbuf, 0) == -1) { - m_ec = detail::capture_errno(); - } -#endif - if (m_ec) - set_or_throw(m_ec, ec, "last_write_time", p); - else if (ec) - ec->clear(); -} - - -void __permissions(const path& p, perms prms, std::error_code *ec) -{ - - const bool resolve_symlinks = !bool(perms::symlink_nofollow & prms); - const bool add_perms = bool(perms::add_perms & prms); - const bool remove_perms = bool(perms::remove_perms & prms); - _LIBCPP_ASSERT(!(add_perms && remove_perms), - "Both add_perms and remove_perms are set"); - - bool set_sym_perms = false; - prms &= perms::mask; - if (!resolve_symlinks || (add_perms || remove_perms)) { - std::error_code m_ec; - file_status st = resolve_symlinks ? detail::posix_stat(p, &m_ec) - : detail::posix_lstat(p, &m_ec); - set_sym_perms = is_symlink(st); - if (m_ec) return set_or_throw(m_ec, ec, "permissions", p); - _LIBCPP_ASSERT(st.permissions() != perms::unknown, - "Permissions unexpectedly unknown"); - if (add_perms) - prms |= st.permissions(); - else if (remove_perms) - prms = st.permissions() & ~prms; - } - const auto real_perms = detail::posix_convert_perms(prms); - -# if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) - const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; - if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { - return set_or_throw(ec, "permissions", p); - } -# else - if (set_sym_perms) - return set_or_throw(make_error_code(errc::operation_not_supported), - ec, "permissions", p); - if (::chmod(p.c_str(), real_perms) == -1) { - return set_or_throw(ec, "permissions", p); - } -# endif - if (ec) ec->clear(); -} - - -path __read_symlink(const path& p, std::error_code *ec) { - char buff[PATH_MAX + 1]; - std::error_code m_ec; - ::ssize_t ret; - if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) { - set_or_throw(ec, "read_symlink", p); - return {}; - } - _LIBCPP_ASSERT(ret <= PATH_MAX, "TODO"); - _LIBCPP_ASSERT(ret > 0, "TODO"); - if (ec) ec->clear(); - buff[ret] = 0; - return {buff}; -} - - -bool __remove(const path& p, std::error_code *ec) { - if (ec) ec->clear(); - if (::remove(p.c_str()) == -1) { - set_or_throw(ec, "remove", p); - return false; - } - return true; -} - -namespace { - -std::uintmax_t remove_all_impl(path const & p, std::error_code& ec) -{ - const auto npos = static_cast<std::uintmax_t>(-1); - const file_status st = __symlink_status(p, &ec); - if (ec) return npos; - std::uintmax_t count = 1; - if (is_directory(st)) { - for (directory_iterator it(p, ec); !ec && it != directory_iterator(); - it.increment(ec)) { - auto other_count = remove_all_impl(it->path(), ec); - if (ec) return npos; - count += other_count; - } - if (ec) return npos; - } - if (!__remove(p, &ec)) return npos; - return count; -} - -} // end namespace - -std::uintmax_t __remove_all(const path& p, std::error_code *ec) { - std::error_code mec; - auto count = remove_all_impl(p, mec); - if (mec) { - set_or_throw(mec, ec, "remove_all", p); - return static_cast<std::uintmax_t>(-1); - } - if (ec) ec->clear(); - return count; -} - -void __rename(const path& from, const path& to, std::error_code *ec) { - if (::rename(from.c_str(), to.c_str()) == -1) - set_or_throw(ec, "rename", from, to); - else if (ec) - ec->clear(); -} - -void __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) { - if (::truncate(p.c_str(), static_cast<long>(size)) == -1) - set_or_throw(ec, "resize_file", p); - else if (ec) - ec->clear(); -} - -space_info __space(const path& p, std::error_code *ec) { - space_info si; - struct statvfs m_svfs = {}; - if (::statvfs(p.c_str(), &m_svfs) == -1) { - set_or_throw(ec, "space", p); - si.capacity = si.free = si.available = - static_cast<std::uintmax_t>(-1); - return si; - } - if (ec) ec->clear(); - // Multiply with overflow checking. - auto do_mult = [&](std::uintmax_t& out, std::uintmax_t other) { - out = other * m_svfs.f_frsize; - if (out / other != m_svfs.f_frsize || other == 0) - out = static_cast<std::uintmax_t>(-1); - }; - do_mult(si.capacity, m_svfs.f_blocks); - do_mult(si.free, m_svfs.f_bfree); - do_mult(si.available, m_svfs.f_bavail); - return si; -} - -file_status __status(const path& p, std::error_code *ec) { - return detail::posix_stat(p, ec); -} - -file_status __symlink_status(const path& p, std::error_code *ec) { - return detail::posix_lstat(p, ec); -} - -path __system_complete(const path& p, std::error_code *ec) { - if (ec) ec->clear(); - 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; - } - if (!m_ec || m_ec == make_error_code(errc::no_such_file_or_directory)) - m_ec = make_error_code(errc::not_a_directory); - set_or_throw(m_ec, ec, "temp_directory_path"); - return {}; -} - -// An absolute path is composed according to the table in [fs.op.absolute]. -path absolute(const path& p, const path& base) { - auto root_name = p.root_name(); - auto root_dir = p.root_directory(); - - if (!root_name.empty() && !root_dir.empty()) - return p; - - auto abs_base = base.is_absolute() ? base : absolute(base); - - /* !has_root_name && !has_root_dir */ - if (root_name.empty() && root_dir.empty()) - { - return abs_base / p; - } - else if (!root_name.empty()) /* has_root_name && !has_root_dir */ - { - return root_name / abs_base.root_directory() - / - abs_base.relative_path() / p.relative_path(); - } - else /* !has_root_name && has_root_dir */ - { - if (abs_base.has_root_name()) - return abs_base.root_name() / p; - // else p is absolute, return outside of block - } - return p; -} - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/lib/libcxx/src/experimental/filesystem/path.cpp b/lib/libcxx/src/experimental/filesystem/path.cpp deleted file mode 100644 index 38c449832f6..00000000000 --- a/lib/libcxx/src/experimental/filesystem/path.cpp +++ /dev/null @@ -1,391 +0,0 @@ -//===--------------------- filesystem/path.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 "experimental/string_view" -#include "utility" - -_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM - -_LIBCPP_CONSTEXPR path::value_type path::preferred_separator; - -namespace { namespace parser -{ - -using string_type = string_view; -using value_type = path::value_type; - -using string_view_pair = pair<string_view, string_view>; - -// status reporting -constexpr size_t npos = static_cast<size_t>(-1); - -inline bool good(size_t pos) { return pos != npos; } - -// lexical elements -constexpr value_type preferred_separator = path::preferred_separator; -constexpr value_type const * preferred_separator_str = "/"; -constexpr value_type const * dot = "."; - -// forward // -bool is_separator(string_type const &, size_t); -bool is_root_name(const string_type&, size_t); -bool is_root_directory(string_type const &, size_t); -bool is_trailing_separator(string_type const &, size_t); - -size_t start_of(string_type const &, size_t); -size_t end_of(string_type const &, size_t); - -size_t root_name_start(const string_type& s); -size_t root_name_end(const string_type&); - -size_t root_directory_start(string_type const &); -size_t root_directory_end(string_type const &); - -string_view_pair separate_filename(string_type const &); -string_view extract_raw(string_type const &, size_t); -string_view extract_preferred(string_type const &, size_t); - -inline bool is_separator(const string_type& s, size_t pos) { - return (pos < s.size() && s[pos] == preferred_separator); -} - -inline bool is_root_name(const string_type& s, size_t pos) { - return good(pos) && pos == 0 ? root_name_start(s) == pos : false; -} - -inline bool is_root_directory(const string_type& s, size_t pos) { - return good(pos) ? root_directory_start(s) == pos : false; -} - -inline bool is_trailing_separator(const string_type& s, size_t pos) { - return (pos < s.size() && is_separator(s, pos) && - end_of(s, pos) == s.size()-1 && - !is_root_directory(s, pos) && !is_root_name(s, pos)); -} - -size_t start_of(const string_type& s, size_t pos) { - if (pos >= s.size()) return npos; - bool in_sep = (s[pos] == preferred_separator); - while (pos - 1 < s.size() && - (s[pos-1] == preferred_separator) == in_sep) - { --pos; } - if (pos == 2 && !in_sep && s[0] == preferred_separator && - s[1] == preferred_separator) - { return 0; } - return pos; -} - -size_t end_of(const string_type& s, size_t pos) { - if (pos >= s.size()) return npos; - // special case for root name - if (pos == 0 && is_root_name(s, pos)) return root_name_end(s); - bool in_sep = (s[pos] == preferred_separator); - while (pos + 1 < s.size() && (s[pos+1] == preferred_separator) == in_sep) - { ++pos; } - return pos; -} - -inline size_t root_name_start(const string_type& s) { - return good(root_name_end(s)) ? 0 : npos; -} - -size_t root_name_end(const string_type& s) { - if (s.size() < 2 || s[0] != preferred_separator - || s[1] != preferred_separator) { - return npos; - } - if (s.size() == 2) { - return 1; - } - size_t index = 2; // current position - if (s[index] == preferred_separator) { - return npos; - } - while (index + 1 < s.size() && s[index+1] != preferred_separator) { - ++index; - } - return index; -} - -size_t root_directory_start(const string_type& s) { - size_t e = root_name_end(s); - if (!good(e)) - return is_separator(s, 0) ? 0 : npos; - return is_separator(s, e + 1) ? e + 1 : npos; -} - -size_t root_directory_end(const string_type& s) { - size_t st = root_directory_start(s); - if (!good(st)) return npos; - size_t index = st; - while (index + 1 < s.size() && s[index + 1] == preferred_separator) - { ++index; } - return index; -} - -string_view_pair separate_filename(string_type const & s) { - if (s == "." || s == ".." || s.empty()) return string_view_pair{s, ""}; - auto pos = s.find_last_of('.'); - if (pos == string_type::npos) return string_view_pair{s, string_view{}}; - return string_view_pair{s.substr(0, pos), s.substr(pos)}; -} - -inline string_view extract_raw(const string_type& s, size_t pos) { - size_t end_i = end_of(s, pos); - if (!good(end_i)) return string_view{}; - return string_view(s).substr(pos, end_i - pos + 1); -} - -string_view extract_preferred(const string_type& s, size_t pos) { - string_view raw = extract_raw(s, pos); - if (raw.empty()) - return raw; - if (is_trailing_separator(s, pos)) - return string_view{dot}; - if (is_separator(s, pos) && !is_root_name(s, pos)) - return string_view(preferred_separator_str); - return raw; -} - -}} // namespace parser - - -//////////////////////////////////////////////////////////////////////////////// -// path_view_iterator -//////////////////////////////////////////////////////////////////////////////// -namespace { - -struct path_view_iterator { - const string_view __s_; - size_t __pos_; - - explicit path_view_iterator(string_view const& __s) : __s_(__s), __pos_(__s_.empty() ? parser::npos : 0) {} - explicit path_view_iterator(string_view const& __s, size_t __p) : __s_(__s), __pos_(__p) {} - - string_view operator*() const { - return parser::extract_preferred(__s_, __pos_); - } - - path_view_iterator& operator++() { - increment(); - return *this; - } - - path_view_iterator& operator--() { - decrement(); - return *this; - } - - void increment() { - if (__pos_ == parser::npos) return; - while (! set_position(parser::end_of(__s_, __pos_)+1)) - ; - return; - } - - void decrement() { - if (__pos_ == 0) { - set_position(0); - } - else if (__pos_ == parser::npos) { - auto const str_size = __s_.size(); - set_position(parser::start_of( - __s_, str_size != 0 ? str_size - 1 : str_size)); - } else { - while (!set_position(parser::start_of(__s_, __pos_-1))) - ; - } - } - - bool set_position(size_t pos) { - if (pos >= __s_.size()) { - __pos_ = parser::npos; - } else { - __pos_ = pos; - } - return valid_iterator_position(); - } - - bool valid_iterator_position() const { - if (__pos_ == parser::npos) return true; // end position is valid - return (!parser::is_separator (__s_, __pos_) || - parser::is_root_directory (__s_, __pos_) || - parser::is_trailing_separator(__s_, __pos_) || - parser::is_root_name (__s_, __pos_)); - } - - bool is_end() const { return __pos_ == parser::npos; } - - inline bool operator==(path_view_iterator const& __p) { - return __pos_ == __p.__pos_; - } -}; - -path_view_iterator pbegin(path const& p) { - return path_view_iterator(p.native()); -} - -path_view_iterator pend(path const& p) { - path_view_iterator __p(p.native()); - __p.__pos_ = parser::npos; - return __p; -} - -} // end namespace -/////////////////////////////////////////////////////////////////////////////// -// path definitions -/////////////////////////////////////////////////////////////////////////////// - -path & path::replace_extension(path const & replacement) -{ - path p = extension(); - if (not p.empty()) { - __pn_.erase(__pn_.size() - p.native().size()); - } - if (!replacement.empty()) { - if (replacement.native()[0] != '.') { - __pn_ += "."; - } - __pn_.append(replacement.__pn_); - } - return *this; -} - -/////////////////////////////////////////////////////////////////////////////// -// path.decompose - -string_view path::__root_name() const -{ - return parser::is_root_name(__pn_, 0) - ? parser::extract_preferred(__pn_, 0) - : string_view{}; -} - -string_view path::__root_directory() const -{ - auto start_i = parser::root_directory_start(__pn_); - if(!parser::good(start_i)) { - return {}; - } - return parser::extract_preferred(__pn_, start_i); -} - -string_view path::__relative_path() const -{ - if (empty()) { - return {__pn_}; - } - auto end_i = parser::root_directory_end(__pn_); - if (not parser::good(end_i)) { - end_i = parser::root_name_end(__pn_); - } - if (not parser::good(end_i)) { - return {__pn_}; - } - return string_view(__pn_).substr(end_i+1); -} - -string_view path::__parent_path() const -{ - if (empty() || pbegin(*this) == --pend(*this)) { - return {}; - } - auto end_it = --(--pend(*this)); - auto end_i = parser::end_of(__pn_, end_it.__pos_); - return string_view(__pn_).substr(0, end_i+1); -} - -string_view path::__filename() const -{ - return empty() ? string_view{} : *--pend(*this); -} - -string_view path::__stem() const -{ - return parser::separate_filename(__filename()).first; -} - -string_view path::__extension() const -{ - return parser::separate_filename(__filename()).second; -} - -//////////////////////////////////////////////////////////////////////////// -// path.comparisons -int path::__compare(const value_type* __s) const { - path_view_iterator thisIter(this->native()); - path_view_iterator sIter(__s); - while (!thisIter.is_end() && !sIter.is_end()) { - int res = (*thisIter).compare(*sIter); - if (res != 0) return res; - ++thisIter; ++sIter; - } - if (thisIter.is_end() && sIter.is_end()) - return 0; - if (thisIter.is_end()) - return -1; - return 1; -} - -//////////////////////////////////////////////////////////////////////////// -// path.nonmembers -size_t hash_value(const path& __p) _NOEXCEPT { - path_view_iterator thisIter(__p.native()); - struct HashPairT { - size_t first; - size_t second; - }; - HashPairT hp = {0, 0}; - std::hash<string_view> hasher; - std::__scalar_hash<decltype(hp)> pair_hasher; - while (!thisIter.is_end()) { - hp.second = hasher(*thisIter); - hp.first = pair_hasher(hp); - ++thisIter; - } - return hp.first; -} - -//////////////////////////////////////////////////////////////////////////// -// path.itr -path::iterator path::begin() const -{ - path_view_iterator pit = pbegin(*this); - iterator it; - it.__path_ptr_ = this; - it.__pos_ = pit.__pos_; - it.__elem_.__assign_view(*pit); - return it; -} - -path::iterator path::end() const -{ - iterator it{}; - it.__path_ptr_ = this; - it.__pos_ = parser::npos; - return it; -} - -path::iterator& path::iterator::__increment() { - path_view_iterator it(__path_ptr_->native(), __pos_); - it.increment(); - __pos_ = it.__pos_; - __elem_.__assign_view(*it); - return *this; -} - -path::iterator& path::iterator::__decrement() { - path_view_iterator it(__path_ptr_->native(), __pos_); - it.decrement(); - __pos_ = it.__pos_; - __elem_.__assign_view(*it); - return *this; -} - -_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM diff --git a/lib/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h b/lib/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h deleted file mode 100644 index 1e853e2cd4e..00000000000 --- a/lib/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h +++ /dev/null @@ -1,915 +0,0 @@ -// Support for registering benchmarks for functions. - -/* Example usage: -// Define a function that executes the code to be measured a -// specified number of times: -static void BM_StringCreation(benchmark::State& state) { - while (state.KeepRunning()) - std::string empty_string; -} - -// Register the function as a benchmark -BENCHMARK(BM_StringCreation); - -// Define another benchmark -static void BM_StringCopy(benchmark::State& state) { - std::string x = "hello"; - while (state.KeepRunning()) - std::string copy(x); -} -BENCHMARK(BM_StringCopy); - -// Augment the main() program to invoke benchmarks if specified -// via the --benchmarks command line flag. E.g., -// my_unittest --benchmark_filter=all -// my_unittest --benchmark_filter=BM_StringCreation -// my_unittest --benchmark_filter=String -// my_unittest --benchmark_filter='Copy|Creation' -int main(int argc, char** argv) { - benchmark::Initialize(&argc, argv); - benchmark::RunSpecifiedBenchmarks(); - return 0; -} - -// Sometimes a family of microbenchmarks can be implemented with -// just one routine that takes an extra argument to specify which -// one of the family of benchmarks to run. For example, the following -// code defines a family of microbenchmarks for measuring the speed -// of memcpy() calls of different lengths: - -static void BM_memcpy(benchmark::State& state) { - char* src = new char[state.range(0)]; char* dst = new char[state.range(0)]; - memset(src, 'x', state.range(0)); - while (state.KeepRunning()) - memcpy(dst, src, state.range(0)); - state.SetBytesProcessed(int64_t(state.iterations()) * - int64_t(state.range(0))); - delete[] src; delete[] dst; -} -BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10); - -// The preceding code is quite repetitive, and can be replaced with the -// following short-hand. The following invocation will pick a few -// appropriate arguments in the specified range and will generate a -// microbenchmark for each such argument. -BENCHMARK(BM_memcpy)->Range(8, 8<<10); - -// You might have a microbenchmark that depends on two inputs. For -// example, the following code defines a family of microbenchmarks for -// measuring the speed of set insertion. -static void BM_SetInsert(benchmark::State& state) { - while (state.KeepRunning()) { - state.PauseTiming(); - set<int> data = ConstructRandomSet(state.range(0)); - state.ResumeTiming(); - for (int j = 0; j < state.range(1); ++j) - data.insert(RandomNumber()); - } -} -BENCHMARK(BM_SetInsert) - ->Args({1<<10, 1}) - ->Args({1<<10, 8}) - ->Args({1<<10, 64}) - ->Args({1<<10, 512}) - ->Args({8<<10, 1}) - ->Args({8<<10, 8}) - ->Args({8<<10, 64}) - ->Args({8<<10, 512}); - -// The preceding code is quite repetitive, and can be replaced with -// the following short-hand. The following macro will pick a few -// appropriate arguments in the product of the two specified ranges -// and will generate a microbenchmark for each such pair. -BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); - -// For more complex patterns of inputs, passing a custom function -// to Apply allows programmatic specification of an -// arbitrary set of arguments to run the microbenchmark on. -// The following example enumerates a dense range on -// one parameter, and a sparse range on the second. -static void CustomArguments(benchmark::internal::Benchmark* b) { - for (int i = 0; i <= 10; ++i) - for (int j = 32; j <= 1024*1024; j *= 8) - b->Args({i, j}); -} -BENCHMARK(BM_SetInsert)->Apply(CustomArguments); - -// Templated microbenchmarks work the same way: -// Produce then consume 'size' messages 'iters' times -// Measures throughput in the absence of multiprogramming. -template <class Q> int BM_Sequential(benchmark::State& state) { - Q q; - typename Q::value_type v; - while (state.KeepRunning()) { - for (int i = state.range(0); i--; ) - q.push(v); - for (int e = state.range(0); e--; ) - q.Wait(&v); - } - // actually messages, not bytes: - state.SetBytesProcessed( - static_cast<int64_t>(state.iterations())*state.range(0)); -} -BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10); - -Use `Benchmark::MinTime(double t)` to set the minimum time used to run the -benchmark. This option overrides the `benchmark_min_time` flag. - -void BM_test(benchmark::State& state) { - ... body ... -} -BENCHMARK(BM_test)->MinTime(2.0); // Run for at least 2 seconds. - -In a multithreaded test, it is guaranteed that none of the threads will start -until all have called KeepRunning, and all will have finished before KeepRunning -returns false. As such, any global setup or teardown you want to do can be -wrapped in a check against the thread index: - -static void BM_MultiThreaded(benchmark::State& state) { - if (state.thread_index == 0) { - // Setup code here. - } - while (state.KeepRunning()) { - // Run the test as normal. - } - if (state.thread_index == 0) { - // Teardown code here. - } -} -BENCHMARK(BM_MultiThreaded)->Threads(4); - - -If a benchmark runs a few milliseconds it may be hard to visually compare the -measured times, since the output data is given in nanoseconds per default. In -order to manually set the time unit, you can specify it manually: - -BENCHMARK(BM_test)->Unit(benchmark::kMillisecond); -*/ - -#ifndef BENCHMARK_BENCHMARK_API_H_ -#define BENCHMARK_BENCHMARK_API_H_ - -#include <assert.h> -#include <stddef.h> -#include <stdint.h> - -#include <string> -#include <vector> -#include <map> - -#include "macros.h" - -#if defined(BENCHMARK_HAS_CXX11) -#include <type_traits> -#include <initializer_list> -#include <utility> -#endif - -#if defined(_MSC_VER) -#include <intrin.h> // for _ReadWriteBarrier -#endif - -namespace benchmark { -class BenchmarkReporter; - -void Initialize(int* argc, char** argv); - -// Report to stdout all arguments in 'argv' as unrecognized except the first. -// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1). -bool ReportUnrecognizedArguments(int argc, char** argv); - -// Generate a list of benchmarks matching the specified --benchmark_filter flag -// and if --benchmark_list_tests is specified return after printing the name -// of each matching benchmark. Otherwise run each matching benchmark and -// report the results. -// -// The second and third overload use the specified 'console_reporter' and -// 'file_reporter' respectively. 'file_reporter' will write to the file -// specified -// by '--benchmark_output'. If '--benchmark_output' is not given the -// 'file_reporter' is ignored. -// -// RETURNS: The number of matching benchmarks. -size_t RunSpecifiedBenchmarks(); -size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter); -size_t RunSpecifiedBenchmarks(BenchmarkReporter* console_reporter, - BenchmarkReporter* file_reporter); - -// If this routine is called, peak memory allocation past this point in the -// benchmark is reported at the end of the benchmark report line. (It is -// computed by running the benchmark once with a single iteration and a memory -// tracer.) -// TODO(dominic) -// void MemoryUsage(); - -namespace internal { -class Benchmark; -class BenchmarkImp; -class BenchmarkFamilies; - -void UseCharPointer(char const volatile*); - -// Take ownership of the pointer and register the benchmark. Return the -// registered benchmark. -Benchmark* RegisterBenchmarkInternal(Benchmark*); - -// Ensure that the standard streams are properly initialized in every TU. -int InitializeStreams(); -BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams(); - -} // end namespace internal - - -#if !defined(__GNUC__) || defined(__pnacl__) || defined(EMSCRIPTN) -# define BENCHMARK_HAS_NO_INLINE_ASSEMBLY -#endif - -// The DoNotOptimize(...) function can be used to prevent a value or -// expression from being optimized away by the compiler. This function is -// intended to add little to no overhead. -// See: https://youtu.be/nXaxk27zwlk?t=2441 -#ifndef BENCHMARK_HAS_NO_INLINE_ASSEMBLY -template <class Tp> -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - asm volatile("" : : "g"(value) : "memory"); -} -// Force the compiler to flush pending writes to global memory. Acts as an -// effective read/write barrier -inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { - asm volatile("" : : : "memory"); -} -#elif defined(_MSC_VER) -template <class Tp> -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value)); - _ReadWriteBarrier(); -} - -inline BENCHMARK_ALWAYS_INLINE void ClobberMemory() { - _ReadWriteBarrier(); -} -#else -template <class Tp> -inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) { - internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value)); -} -// FIXME Add ClobberMemory() for non-gnu and non-msvc compilers -#endif - - - -// This class is used for user-defined counters. -class Counter { -public: - - enum Flags { - kDefaults = 0, - // Mark the counter as a rate. It will be presented divided - // by the duration of the benchmark. - kIsRate = 1, - // Mark the counter as a thread-average quantity. It will be - // presented divided by the number of threads. - kAvgThreads = 2, - // Mark the counter as a thread-average rate. See above. - kAvgThreadsRate = kIsRate|kAvgThreads - }; - - double value; - Flags flags; - - BENCHMARK_ALWAYS_INLINE - Counter(double v = 0., Flags f = kDefaults) : value(v), flags(f) {} - - BENCHMARK_ALWAYS_INLINE operator double const& () const { return value; } - BENCHMARK_ALWAYS_INLINE operator double & () { return value; } - -}; - -// This is the container for the user-defined counters. -typedef std::map<std::string, Counter> UserCounters; - - -// TimeUnit is passed to a benchmark in order to specify the order of magnitude -// for the measured time. -enum TimeUnit { kNanosecond, kMicrosecond, kMillisecond }; - -// BigO is passed to a benchmark in order to specify the asymptotic -// computational -// complexity for the benchmark. In case oAuto is selected, complexity will be -// calculated automatically to the best fit. -enum BigO { oNone, o1, oN, oNSquared, oNCubed, oLogN, oNLogN, oAuto, oLambda }; - -// BigOFunc is passed to a benchmark in order to specify the asymptotic -// computational complexity for the benchmark. -typedef double(BigOFunc)(int); - -namespace internal { -class ThreadTimer; -class ThreadManager; - -#if defined(BENCHMARK_HAS_CXX11) -enum ReportMode : unsigned { -#else -enum ReportMode { -#endif - RM_Unspecified, // The mode has not been manually specified - RM_Default, // The mode is user-specified as default. - RM_ReportAggregatesOnly -}; -} - -// State is passed to a running Benchmark and contains state for the -// benchmark to use. -class State { - public: - // Returns true if the benchmark should continue through another iteration. - // NOTE: A benchmark may not return from the test until KeepRunning() has - // returned false. - bool KeepRunning() { - if (BENCHMARK_BUILTIN_EXPECT(!started_, false)) { - StartKeepRunning(); - } - bool const res = total_iterations_++ < max_iterations; - if (BENCHMARK_BUILTIN_EXPECT(!res, false)) { - FinishKeepRunning(); - } - return res; - } - - // REQUIRES: timer is running and 'SkipWithError(...)' has not been called - // by the current thread. - // Stop the benchmark timer. If not called, the timer will be - // automatically stopped after KeepRunning() returns false for the first time. - // - // For threaded benchmarks the PauseTiming() function only pauses the timing - // for the current thread. - // - // NOTE: The "real time" measurement is per-thread. If different threads - // report different measurements the largest one is reported. - // - // NOTE: PauseTiming()/ResumeTiming() are relatively - // heavyweight, and so their use should generally be avoided - // within each benchmark iteration, if possible. - void PauseTiming(); - - // REQUIRES: timer is not running and 'SkipWithError(...)' has not been called - // by the current thread. - // Start the benchmark timer. The timer is NOT running on entrance to the - // benchmark function. It begins running after the first call to KeepRunning() - // - // NOTE: PauseTiming()/ResumeTiming() are relatively - // heavyweight, and so their use should generally be avoided - // within each benchmark iteration, if possible. - void ResumeTiming(); - - // REQUIRES: 'SkipWithError(...)' has not been called previously by the - // current thread. - // Skip any future iterations of the 'KeepRunning()' loop in the current - // thread and report an error with the specified 'msg'. After this call - // the user may explicitly 'return' from the benchmark. - // - // For threaded benchmarks only the current thread stops executing and future - // calls to `KeepRunning()` will block until all threads have completed - // the `KeepRunning()` loop. If multiple threads report an error only the - // first error message is used. - // - // NOTE: Calling 'SkipWithError(...)' does not cause the benchmark to exit - // the current scope immediately. If the function is called from within - // the 'KeepRunning()' loop the current iteration will finish. It is the users - // responsibility to exit the scope as needed. - void SkipWithError(const char* msg); - - // REQUIRES: called exactly once per iteration of the KeepRunning loop. - // Set the manually measured time for this benchmark iteration, which - // is used instead of automatically measured time if UseManualTime() was - // specified. - // - // For threaded benchmarks the final value will be set to the largest - // reported values. - void SetIterationTime(double seconds); - - // Set the number of bytes processed by the current benchmark - // execution. This routine is typically called once at the end of a - // throughput oriented benchmark. If this routine is called with a - // value > 0, the report is printed in MB/sec instead of nanoseconds - // per iteration. - // - // REQUIRES: a benchmark has exited its KeepRunning loop. - BENCHMARK_ALWAYS_INLINE - void SetBytesProcessed(size_t bytes) { bytes_processed_ = bytes; } - - BENCHMARK_ALWAYS_INLINE - size_t bytes_processed() const { return bytes_processed_; } - - // If this routine is called with complexity_n > 0 and complexity report is - // requested for the - // family benchmark, then current benchmark will be part of the computation - // and complexity_n will - // represent the length of N. - BENCHMARK_ALWAYS_INLINE - void SetComplexityN(int complexity_n) { complexity_n_ = complexity_n; } - - BENCHMARK_ALWAYS_INLINE - int complexity_length_n() { return complexity_n_; } - - // If this routine is called with items > 0, then an items/s - // label is printed on the benchmark report line for the currently - // executing benchmark. It is typically called at the end of a processing - // benchmark where a processing items/second output is desired. - // - // REQUIRES: a benchmark has exited its KeepRunning loop. - BENCHMARK_ALWAYS_INLINE - void SetItemsProcessed(size_t items) { items_processed_ = items; } - - BENCHMARK_ALWAYS_INLINE - size_t items_processed() const { return items_processed_; } - - // If this routine is called, the specified label is printed at the - // end of the benchmark report line for the currently executing - // benchmark. Example: - // static void BM_Compress(benchmark::State& state) { - // ... - // double compress = input_size / output_size; - // state.SetLabel(StringPrintf("compress:%.1f%%", 100.0*compression)); - // } - // Produces output that looks like: - // BM_Compress 50 50 14115038 compress:27.3% - // - // REQUIRES: a benchmark has exited its KeepRunning loop. - void SetLabel(const char* label); - - void BENCHMARK_ALWAYS_INLINE SetLabel(const std::string& str) { - this->SetLabel(str.c_str()); - } - - // Range arguments for this run. CHECKs if the argument has been set. - BENCHMARK_ALWAYS_INLINE - int range(std::size_t pos = 0) const { - assert(range_.size() > pos); - return range_[pos]; - } - - BENCHMARK_DEPRECATED_MSG("use 'range(0)' instead") - int range_x() const { return range(0); } - - BENCHMARK_DEPRECATED_MSG("use 'range(1)' instead") - int range_y() const { return range(1); } - - BENCHMARK_ALWAYS_INLINE - size_t iterations() const { return total_iterations_; } - - private: - bool started_; - bool finished_; - size_t total_iterations_; - - std::vector<int> range_; - - size_t bytes_processed_; - size_t items_processed_; - - int complexity_n_; - - bool error_occurred_; - - public: - // Container for user-defined counters. - UserCounters counters; - // Index of the executing thread. Values from [0, threads). - const int thread_index; - // Number of threads concurrently executing the benchmark. - const int threads; - const size_t max_iterations; - - // TODO make me private - State(size_t max_iters, const std::vector<int>& ranges, int thread_i, - int n_threads, internal::ThreadTimer* timer, - internal::ThreadManager* manager); - - private: - void StartKeepRunning(); - void FinishKeepRunning(); - internal::ThreadTimer* timer_; - internal::ThreadManager* manager_; - BENCHMARK_DISALLOW_COPY_AND_ASSIGN(State); -}; - -namespace internal { - -typedef void(Function)(State&); - -// ------------------------------------------------------ -// Benchmark registration object. The BENCHMARK() macro expands -// into an internal::Benchmark* object. Various methods can -// be called on this object to change the properties of the benchmark. -// Each method returns "this" so that multiple method calls can -// chained into one expression. -class Benchmark { - public: - virtual ~Benchmark(); - - // Note: the following methods all return "this" so that multiple - // method calls can be chained together in one expression. - - // Run this benchmark once with "x" as the extra argument passed - // to the function. - // REQUIRES: The function passed to the constructor must accept an arg1. - Benchmark* Arg(int x); - - // Run this benchmark with the given time unit for the generated output report - Benchmark* Unit(TimeUnit unit); - - // Run this benchmark once for a number of values picked from the - // range [start..limit]. (start and limit are always picked.) - // REQUIRES: The function passed to the constructor must accept an arg1. - Benchmark* Range(int start, int limit); - - // Run this benchmark once for all values in the range [start..limit] with - // specific step - // REQUIRES: The function passed to the constructor must accept an arg1. - Benchmark* DenseRange(int start, int limit, int step = 1); - - // Run this benchmark once with "args" as the extra arguments passed - // to the function. - // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... - Benchmark* Args(const std::vector<int>& args); - - // Equivalent to Args({x, y}) - // NOTE: This is a legacy C++03 interface provided for compatibility only. - // New code should use 'Args'. - Benchmark* ArgPair(int x, int y) { - std::vector<int> args; - args.push_back(x); - args.push_back(y); - return Args(args); - } - - // Run this benchmark once for a number of values picked from the - // ranges [start..limit]. (starts and limits are always picked.) - // REQUIRES: The function passed to the constructor must accept arg1, arg2 ... - Benchmark* Ranges(const std::vector<std::pair<int, int> >& ranges); - - // Equivalent to ArgNames({name}) - Benchmark* ArgName(const std::string& name); - - // Set the argument names to display in the benchmark name. If not called, - // only argument values will be shown. - Benchmark* ArgNames(const std::vector<std::string>& names); - - // Equivalent to Ranges({{lo1, hi1}, {lo2, hi2}}). - // NOTE: This is a legacy C++03 interface provided for compatibility only. - // New code should use 'Ranges'. - Benchmark* RangePair(int lo1, int hi1, int lo2, int hi2) { - std::vector<std::pair<int, int> > ranges; - ranges.push_back(std::make_pair(lo1, hi1)); - ranges.push_back(std::make_pair(lo2, hi2)); - return Ranges(ranges); - } - - // Pass this benchmark object to *func, which can customize - // the benchmark by calling various methods like Arg, Args, - // Threads, etc. - Benchmark* Apply(void (*func)(Benchmark* benchmark)); - - // Set the range multiplier for non-dense range. If not called, the range - // multiplier kRangeMultiplier will be used. - Benchmark* RangeMultiplier(int multiplier); - - // Set the minimum amount of time to use when running this benchmark. This - // option overrides the `benchmark_min_time` flag. - // REQUIRES: `t > 0` and `Iterations` has not been called on this benchmark. - Benchmark* MinTime(double t); - - // Specify the amount of iterations that should be run by this benchmark. - // REQUIRES: 'n > 0' and `MinTime` has not been called on this benchmark. - // - // NOTE: This function should only be used when *exact* iteration control is - // needed and never to control or limit how long a benchmark runs, where - // `--benchmark_min_time=N` or `MinTime(...)` should be used instead. - Benchmark* Iterations(size_t n); - - // Specify the amount of times to repeat this benchmark. This option overrides - // the `benchmark_repetitions` flag. - // REQUIRES: `n > 0` - Benchmark* Repetitions(int n); - - // Specify if each repetition of the benchmark should be reported separately - // or if only the final statistics should be reported. If the benchmark - // is not repeated then the single result is always reported. - Benchmark* ReportAggregatesOnly(bool v = true); - - // If a particular benchmark is I/O bound, runs multiple threads internally or - // if for some reason CPU timings are not representative, call this method. If - // called, the elapsed time will be used to control how many iterations are - // run, and in the printing of items/second or MB/seconds values. If not - // called, the cpu time used by the benchmark will be used. - Benchmark* UseRealTime(); - - // If a benchmark must measure time manually (e.g. if GPU execution time is - // being - // measured), call this method. If called, each benchmark iteration should - // call - // SetIterationTime(seconds) to report the measured time, which will be used - // to control how many iterations are run, and in the printing of items/second - // or MB/second values. - Benchmark* UseManualTime(); - - // Set the asymptotic computational complexity for the benchmark. If called - // the asymptotic computational complexity will be shown on the output. - Benchmark* Complexity(BigO complexity = benchmark::oAuto); - - // Set the asymptotic computational complexity for the benchmark. If called - // the asymptotic computational complexity will be shown on the output. - Benchmark* Complexity(BigOFunc* complexity); - - // Support for running multiple copies of the same benchmark concurrently - // in multiple threads. This may be useful when measuring the scaling - // of some piece of code. - - // Run one instance of this benchmark concurrently in t threads. - Benchmark* Threads(int t); - - // Pick a set of values T from [min_threads,max_threads]. - // min_threads and max_threads are always included in T. Run this - // benchmark once for each value in T. The benchmark run for a - // particular value t consists of t threads running the benchmark - // function concurrently. For example, consider: - // BENCHMARK(Foo)->ThreadRange(1,16); - // This will run the following benchmarks: - // Foo in 1 thread - // Foo in 2 threads - // Foo in 4 threads - // Foo in 8 threads - // Foo in 16 threads - Benchmark* ThreadRange(int min_threads, int max_threads); - - // For each value n in the range, run this benchmark once using n threads. - // min_threads and max_threads are always included in the range. - // stride specifies the increment. E.g. DenseThreadRange(1, 8, 3) starts - // a benchmark with 1, 4, 7 and 8 threads. - Benchmark* DenseThreadRange(int min_threads, int max_threads, int stride = 1); - - // Equivalent to ThreadRange(NumCPUs(), NumCPUs()) - Benchmark* ThreadPerCpu(); - - virtual void Run(State& state) = 0; - - // Used inside the benchmark implementation - struct Instance; - - protected: - explicit Benchmark(const char* name); - Benchmark(Benchmark const&); - void SetName(const char* name); - - int ArgsCnt() const; - - static void AddRange(std::vector<int>* dst, int lo, int hi, int mult); - - private: - friend class BenchmarkFamilies; - - std::string name_; - ReportMode report_mode_; - std::vector<std::string> arg_names_; // Args for all benchmark runs - std::vector<std::vector<int> > args_; // Args for all benchmark runs - TimeUnit time_unit_; - int range_multiplier_; - double min_time_; - size_t iterations_; - int repetitions_; - bool use_real_time_; - bool use_manual_time_; - BigO complexity_; - BigOFunc* complexity_lambda_; - std::vector<int> thread_counts_; - - Benchmark& operator=(Benchmark const&); -}; - -} // namespace internal - -// Create and register a benchmark with the specified 'name' that invokes -// the specified functor 'fn'. -// -// RETURNS: A pointer to the registered benchmark. -internal::Benchmark* RegisterBenchmark(const char* name, - internal::Function* fn); - -#if defined(BENCHMARK_HAS_CXX11) -template <class Lambda> -internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn); -#endif - -namespace internal { -// The class used to hold all Benchmarks created from static function. -// (ie those created using the BENCHMARK(...) macros. -class FunctionBenchmark : public Benchmark { - public: - FunctionBenchmark(const char* name, Function* func) - : Benchmark(name), func_(func) {} - - virtual void Run(State& st); - - private: - Function* func_; -}; - -#ifdef BENCHMARK_HAS_CXX11 -template <class Lambda> -class LambdaBenchmark : public Benchmark { - public: - virtual void Run(State& st) { lambda_(st); } - - private: - template <class OLambda> - LambdaBenchmark(const char* name, OLambda&& lam) - : Benchmark(name), lambda_(std::forward<OLambda>(lam)) {} - - LambdaBenchmark(LambdaBenchmark const&) = delete; - - private: - template <class Lam> - friend Benchmark* ::benchmark::RegisterBenchmark(const char*, Lam&&); - - Lambda lambda_; -}; -#endif - -} // end namespace internal - -inline internal::Benchmark* RegisterBenchmark(const char* name, - internal::Function* fn) { - return internal::RegisterBenchmarkInternal( - ::new internal::FunctionBenchmark(name, fn)); -} - -#ifdef BENCHMARK_HAS_CXX11 -template <class Lambda> -internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn) { - using BenchType = - internal::LambdaBenchmark<typename std::decay<Lambda>::type>; - return internal::RegisterBenchmarkInternal( - ::new BenchType(name, std::forward<Lambda>(fn))); -} -#endif - -#if defined(BENCHMARK_HAS_CXX11) && \ - (!defined(BENCHMARK_GCC_VERSION) || BENCHMARK_GCC_VERSION >= 409) -template <class Lambda, class... Args> -internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn, - Args&&... args) { - return benchmark::RegisterBenchmark( - name, [=](benchmark::State& st) { fn(st, args...); }); -} -#else -#define BENCHMARK_HAS_NO_VARIADIC_REGISTER_BENCHMARK -#endif - -// The base class for all fixture tests. -class Fixture : public internal::Benchmark { - public: - Fixture() : internal::Benchmark("") {} - - virtual void Run(State& st) { - this->SetUp(st); - this->BenchmarkCase(st); - this->TearDown(st); - } - - // These will be deprecated ... - virtual void SetUp(const State&) {} - virtual void TearDown(const State&) {} - // ... In favor of these. - virtual void SetUp(State& st) { SetUp(const_cast<const State&>(st)); } - virtual void TearDown(State& st) { TearDown(const_cast<const State&>(st)); } - - protected: - virtual void BenchmarkCase(State&) = 0; -}; - -} // end namespace benchmark - -// ------------------------------------------------------ -// Macro to register benchmarks - -// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1 -// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be -// empty. If X is empty the expression becomes (+1 == +0). -#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0) -#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__ -#else -#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__ -#endif - -// Helpers for generating unique variable names -#define BENCHMARK_PRIVATE_NAME(n) \ - BENCHMARK_PRIVATE_CONCAT(_benchmark_, BENCHMARK_PRIVATE_UNIQUE_ID, n) -#define BENCHMARK_PRIVATE_CONCAT(a, b, c) BENCHMARK_PRIVATE_CONCAT2(a, b, c) -#define BENCHMARK_PRIVATE_CONCAT2(a, b, c) a##b##c - -#define BENCHMARK_PRIVATE_DECLARE(n) \ - static ::benchmark::internal::Benchmark* BENCHMARK_PRIVATE_NAME(n) \ - BENCHMARK_UNUSED - -#define BENCHMARK(n) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n, n))) - -// Old-style macros -#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a)) -#define BENCHMARK_WITH_ARG2(n, a1, a2) BENCHMARK(n)->Args({(a1), (a2)}) -#define BENCHMARK_WITH_UNIT(n, t) BENCHMARK(n)->Unit((t)) -#define BENCHMARK_RANGE(n, lo, hi) BENCHMARK(n)->Range((lo), (hi)) -#define BENCHMARK_RANGE2(n, l1, h1, l2, h2) \ - BENCHMARK(n)->RangePair({{(l1), (h1)}, {(l2), (h2)}}) - -#if __cplusplus >= 201103L - -// Register a benchmark which invokes the function specified by `func` -// with the additional arguments specified by `...`. -// -// For example: -// -// template <class ...ExtraArgs>` -// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) { -// [...] -//} -// /* Registers a benchmark named "BM_takes_args/int_string_test` */ -// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc")); -#define BENCHMARK_CAPTURE(func, test_case_name, ...) \ - BENCHMARK_PRIVATE_DECLARE(func) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark( \ - #func "/" #test_case_name, \ - [](::benchmark::State& st) { func(st, __VA_ARGS__); }))) - -#endif // __cplusplus >= 11 - -// This will register a benchmark for a templatized function. For example: -// -// template<int arg> -// void BM_Foo(int iters); -// -// BENCHMARK_TEMPLATE(BM_Foo, 1); -// -// will register BM_Foo<1> as a benchmark. -#define BENCHMARK_TEMPLATE1(n, a) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n "<" #a ">", n<a>))) - -#define BENCHMARK_TEMPLATE2(n, a, b) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark(#n "<" #a "," #b ">", \ - n<a, b>))) - -#if __cplusplus >= 201103L -#define BENCHMARK_TEMPLATE(n, ...) \ - BENCHMARK_PRIVATE_DECLARE(n) = \ - (::benchmark::internal::RegisterBenchmarkInternal( \ - new ::benchmark::internal::FunctionBenchmark( \ - #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>))) -#else -#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a) -#endif - -#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ - class BaseClass##_##Method##_Benchmark : public BaseClass { \ - public: \ - BaseClass##_##Method##_Benchmark() : BaseClass() { \ - this->SetName(#BaseClass "/" #Method); \ - } \ - \ - protected: \ - virtual void BenchmarkCase(::benchmark::State&); \ - }; - -#define BENCHMARK_DEFINE_F(BaseClass, Method) \ - BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ - void BaseClass##_##Method##_Benchmark::BenchmarkCase - -#define BENCHMARK_REGISTER_F(BaseClass, Method) \ - BENCHMARK_PRIVATE_REGISTER_F(BaseClass##_##Method##_Benchmark) - -#define BENCHMARK_PRIVATE_REGISTER_F(TestName) \ - BENCHMARK_PRIVATE_DECLARE(TestName) = \ - (::benchmark::internal::RegisterBenchmarkInternal(new TestName())) - -// This macro will define and register a benchmark within a fixture class. -#define BENCHMARK_F(BaseClass, Method) \ - BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \ - BENCHMARK_REGISTER_F(BaseClass, Method); \ - void BaseClass##_##Method##_Benchmark::BenchmarkCase - -// Helper macro to create a main routine in a test that runs the benchmarks -#define BENCHMARK_MAIN() \ - int main(int argc, char** argv) { \ - ::benchmark::Initialize(&argc, argv); \ - if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \ - ::benchmark::RunSpecifiedBenchmarks(); \ - } - -#endif // BENCHMARK_BENCHMARK_API_H_ diff --git a/lib/libcxx/utils/google-benchmark/include/benchmark/macros.h b/lib/libcxx/utils/google-benchmark/include/benchmark/macros.h deleted file mode 100644 index 2466fd3fad0..00000000000 --- a/lib/libcxx/utils/google-benchmark/include/benchmark/macros.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef BENCHMARK_MACROS_H_ -#define BENCHMARK_MACROS_H_ - -#if __cplusplus >= 201103L -#define BENCHMARK_HAS_CXX11 -#endif - -#ifndef BENCHMARK_HAS_CXX11 -#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - TypeName& operator=(const TypeName&) -#else -#define BENCHMARK_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - TypeName& operator=(const TypeName&) = delete -#endif - -#if defined(__GNUC__) -#define BENCHMARK_UNUSED __attribute__((unused)) -#define BENCHMARK_ALWAYS_INLINE __attribute__((always_inline)) -#define BENCHMARK_NOEXCEPT noexcept -#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) -#elif defined(_MSC_VER) && !defined(__clang__) -#define BENCHMARK_UNUSED -#define BENCHMARK_ALWAYS_INLINE __forceinline -#if _MSC_VER >= 1900 -#define BENCHMARK_NOEXCEPT noexcept -#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x) -#else -#define BENCHMARK_NOEXCEPT -#define BENCHMARK_NOEXCEPT_OP(x) -#endif -#define __func__ __FUNCTION__ -#else -#define BENCHMARK_UNUSED -#define BENCHMARK_ALWAYS_INLINE -#define BENCHMARK_NOEXCEPT -#define BENCHMARK_NOEXCEPT_OP(x) -#endif - -#if defined(__GNUC__) -#define BENCHMARK_BUILTIN_EXPECT(x, y) __builtin_expect(x, y) -#define BENCHMARK_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) -#else -#define BENCHMARK_BUILTIN_EXPECT(x, y) x -#define BENCHMARK_DEPRECATED_MSG(msg) -#endif - -#if defined(__GNUC__) && !defined(__clang__) -#define BENCHMARK_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -#endif - -#endif // BENCHMARK_MACROS_H_ diff --git a/lib/libcxx/utils/google-benchmark/include/benchmark/reporter.h b/lib/libcxx/utils/google-benchmark/include/benchmark/reporter.h deleted file mode 100644 index 789124ba813..00000000000 --- a/lib/libcxx/utils/google-benchmark/include/benchmark/reporter.h +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2015 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef BENCHMARK_REPORTER_H_ -#define BENCHMARK_REPORTER_H_ - -#include <cassert> -#include <iosfwd> -#include <string> -#include <utility> -#include <vector> -#include <set> - -#include "benchmark_api.h" // For forward declaration of BenchmarkReporter - -namespace benchmark { - -// Interface for custom benchmark result printers. -// By default, benchmark reports are printed to stdout. However an application -// can control the destination of the reports by calling -// RunSpecifiedBenchmarks and passing it a custom reporter object. -// The reporter object must implement the following interface. -class BenchmarkReporter { - public: - struct Context { - int num_cpus; - double mhz_per_cpu; - bool cpu_scaling_enabled; - - // The number of chars in the longest benchmark name. - size_t name_field_width; - }; - - struct Run { - Run() - : error_occurred(false), - iterations(1), - time_unit(kNanosecond), - real_accumulated_time(0), - cpu_accumulated_time(0), - bytes_per_second(0), - items_per_second(0), - max_heapbytes_used(0), - complexity(oNone), - complexity_lambda(), - complexity_n(0), - report_big_o(false), - report_rms(false), - counters() {} - - std::string benchmark_name; - std::string report_label; // Empty if not set by benchmark. - bool error_occurred; - std::string error_message; - - int64_t iterations; - TimeUnit time_unit; - double real_accumulated_time; - double cpu_accumulated_time; - - // Return a value representing the real time per iteration in the unit - // specified by 'time_unit'. - // NOTE: If 'iterations' is zero the returned value represents the - // accumulated time. - double GetAdjustedRealTime() const; - - // Return a value representing the cpu time per iteration in the unit - // specified by 'time_unit'. - // NOTE: If 'iterations' is zero the returned value represents the - // accumulated time. - double GetAdjustedCPUTime() const; - - // Zero if not set by benchmark. - double bytes_per_second; - double items_per_second; - - // This is set to 0.0 if memory tracing is not enabled. - double max_heapbytes_used; - - // Keep track of arguments to compute asymptotic complexity - BigO complexity; - BigOFunc* complexity_lambda; - int complexity_n; - - // Inform print function whether the current run is a complexity report - bool report_big_o; - bool report_rms; - - UserCounters counters; - }; - - // Construct a BenchmarkReporter with the output stream set to 'std::cout' - // and the error stream set to 'std::cerr' - BenchmarkReporter(); - - // Called once for every suite of benchmarks run. - // The parameter "context" contains information that the - // reporter may wish to use when generating its report, for example the - // platform under which the benchmarks are running. The benchmark run is - // never started if this function returns false, allowing the reporter - // to skip runs based on the context information. - virtual bool ReportContext(const Context& context) = 0; - - // Called once for each group of benchmark runs, gives information about - // cpu-time and heap memory usage during the benchmark run. If the group - // of runs contained more than two entries then 'report' contains additional - // elements representing the mean and standard deviation of those runs. - // Additionally if this group of runs was the last in a family of benchmarks - // 'reports' contains additional entries representing the asymptotic - // complexity and RMS of that benchmark family. - virtual void ReportRuns(const std::vector<Run>& report) = 0; - - // Called once and only once after ever group of benchmarks is run and - // reported. - virtual void Finalize() {} - - // REQUIRES: The object referenced by 'out' is valid for the lifetime - // of the reporter. - void SetOutputStream(std::ostream* out) { - assert(out); - output_stream_ = out; - } - - // REQUIRES: The object referenced by 'err' is valid for the lifetime - // of the reporter. - void SetErrorStream(std::ostream* err) { - assert(err); - error_stream_ = err; - } - - std::ostream& GetOutputStream() const { return *output_stream_; } - - std::ostream& GetErrorStream() const { return *error_stream_; } - - virtual ~BenchmarkReporter(); - - // Write a human readable string to 'out' representing the specified - // 'context'. - // REQUIRES: 'out' is non-null. - static void PrintBasicContext(std::ostream* out, Context const& context); - - private: - std::ostream* output_stream_; - std::ostream* error_stream_; -}; - -// Simple reporter that outputs benchmark data to the console. This is the -// default reporter used by RunSpecifiedBenchmarks(). -class ConsoleReporter : public BenchmarkReporter { - public: - enum OutputOptions { OO_None, OO_Color }; - explicit ConsoleReporter(OutputOptions color_output = OO_Color) - : name_field_width_(0), color_output_(color_output == OO_Color) {} - - virtual bool ReportContext(const Context& context); - virtual void ReportRuns(const std::vector<Run>& reports); - - protected: - virtual void PrintRunData(const Run& report); - virtual void PrintHeader(const Run& report); - - size_t name_field_width_; - bool printed_header_; - - private: - bool color_output_; -}; - -class JSONReporter : public BenchmarkReporter { - public: - JSONReporter() : first_report_(true) {} - virtual bool ReportContext(const Context& context); - virtual void ReportRuns(const std::vector<Run>& reports); - virtual void Finalize(); - - private: - void PrintRunData(const Run& report); - - bool first_report_; -}; - -class CSVReporter : public BenchmarkReporter { - public: - CSVReporter() : printed_header_(false) {} - virtual bool ReportContext(const Context& context); - virtual void ReportRuns(const std::vector<Run>& reports); - - private: - void PrintRunData(const Run& report); - - bool printed_header_; - std::set< std::string > user_counter_names_; -}; - -inline const char* GetTimeUnitString(TimeUnit unit) { - switch (unit) { - case kMillisecond: - return "ms"; - case kMicrosecond: - return "us"; - case kNanosecond: - default: - return "ns"; - } -} - -inline double GetTimeUnitMultiplier(TimeUnit unit) { - switch (unit) { - case kMillisecond: - return 1e3; - case kMicrosecond: - return 1e6; - case kNanosecond: - default: - return 1e9; - } -} - -} // end namespace benchmark -#endif // BENCHMARK_REPORTER_H_ diff --git a/lib/libcxx/utils/google-benchmark/mingw.py b/lib/libcxx/utils/google-benchmark/mingw.py deleted file mode 100644 index 706ad559db9..00000000000 --- a/lib/libcxx/utils/google-benchmark/mingw.py +++ /dev/null @@ -1,320 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -import argparse -import errno -import logging -import os -import platform -import re -import sys -import subprocess -import tempfile - -try: - import winreg -except ImportError: - import _winreg as winreg -try: - import urllib.request as request -except ImportError: - import urllib as request -try: - import urllib.parse as parse -except ImportError: - import urlparse as parse - -class EmptyLogger(object): - ''' - Provides an implementation that performs no logging - ''' - def debug(self, *k, **kw): - pass - def info(self, *k, **kw): - pass - def warn(self, *k, **kw): - pass - def error(self, *k, **kw): - pass - def critical(self, *k, **kw): - pass - def setLevel(self, *k, **kw): - pass - -urls = ( - 'http://downloads.sourceforge.net/project/mingw-w64/Toolchains%20' - 'targetting%20Win32/Personal%20Builds/mingw-builds/installer/' - 'repository.txt', - 'http://downloads.sourceforge.net/project/mingwbuilds/host-windows/' - 'repository.txt' -) -''' -A list of mingw-build repositories -''' - -def repository(urls = urls, log = EmptyLogger()): - ''' - Downloads and parse mingw-build repository files and parses them - ''' - log.info('getting mingw-builds repository') - versions = {} - re_sourceforge = re.compile(r'http://sourceforge.net/projects/([^/]+)/files') - re_sub = r'http://downloads.sourceforge.net/project/\1' - for url in urls: - log.debug(' - requesting: %s', url) - socket = request.urlopen(url) - repo = socket.read() - if not isinstance(repo, str): - repo = repo.decode(); - socket.close() - for entry in repo.split('\n')[:-1]: - value = entry.split('|') - version = tuple([int(n) for n in value[0].strip().split('.')]) - version = versions.setdefault(version, {}) - arch = value[1].strip() - if arch == 'x32': - arch = 'i686' - elif arch == 'x64': - arch = 'x86_64' - arch = version.setdefault(arch, {}) - threading = arch.setdefault(value[2].strip(), {}) - exceptions = threading.setdefault(value[3].strip(), {}) - revision = exceptions.setdefault(int(value[4].strip()[3:]), - re_sourceforge.sub(re_sub, value[5].strip())) - return versions - -def find_in_path(file, path=None): - ''' - Attempts to find an executable in the path - ''' - if platform.system() == 'Windows': - file += '.exe' - if path is None: - path = os.environ.get('PATH', '') - if type(path) is type(''): - path = path.split(os.pathsep) - return list(filter(os.path.exists, - map(lambda dir, file=file: os.path.join(dir, file), path))) - -def find_7zip(log = EmptyLogger()): - ''' - Attempts to find 7zip for unpacking the mingw-build archives - ''' - log.info('finding 7zip') - path = find_in_path('7z') - if not path: - key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\7-Zip') - path, _ = winreg.QueryValueEx(key, 'Path') - path = [os.path.join(path, '7z.exe')] - log.debug('found \'%s\'', path[0]) - return path[0] - -find_7zip() - -def unpack(archive, location, log = EmptyLogger()): - ''' - Unpacks a mingw-builds archive - ''' - sevenzip = find_7zip(log) - log.info('unpacking %s', os.path.basename(archive)) - cmd = [sevenzip, 'x', archive, '-o' + location, '-y'] - log.debug(' - %r', cmd) - with open(os.devnull, 'w') as devnull: - subprocess.check_call(cmd, stdout = devnull) - -def download(url, location, log = EmptyLogger()): - ''' - Downloads and unpacks a mingw-builds archive - ''' - log.info('downloading MinGW') - log.debug(' - url: %s', url) - log.debug(' - location: %s', location) - - re_content = re.compile(r'attachment;[ \t]*filename=(")?([^"]*)(")?[\r\n]*') - - stream = request.urlopen(url) - try: - content = stream.getheader('Content-Disposition') or '' - except AttributeError: - content = stream.headers.getheader('Content-Disposition') or '' - matches = re_content.match(content) - if matches: - filename = matches.group(2) - else: - parsed = parse.urlparse(stream.geturl()) - filename = os.path.basename(parsed.path) - - try: - os.makedirs(location) - except OSError as e: - if e.errno == errno.EEXIST and os.path.isdir(location): - pass - else: - raise - - archive = os.path.join(location, filename) - with open(archive, 'wb') as out: - while True: - buf = stream.read(1024) - if not buf: - break - out.write(buf) - unpack(archive, location, log = log) - os.remove(archive) - - possible = os.path.join(location, 'mingw64') - if not os.path.exists(possible): - possible = os.path.join(location, 'mingw32') - if not os.path.exists(possible): - raise ValueError('Failed to find unpacked MinGW: ' + possible) - return possible - -def root(location = None, arch = None, version = None, threading = None, - exceptions = None, revision = None, log = EmptyLogger()): - ''' - Returns the root folder of a specific version of the mingw-builds variant - of gcc. Will download the compiler if needed - ''' - - # Get the repository if we don't have all the information - if not (arch and version and threading and exceptions and revision): - versions = repository(log = log) - - # Determine some defaults - version = version or max(versions.keys()) - if not arch: - arch = platform.machine().lower() - if arch == 'x86': - arch = 'i686' - elif arch == 'amd64': - arch = 'x86_64' - if not threading: - keys = versions[version][arch].keys() - if 'posix' in keys: - threading = 'posix' - elif 'win32' in keys: - threading = 'win32' - else: - threading = keys[0] - if not exceptions: - keys = versions[version][arch][threading].keys() - if 'seh' in keys: - exceptions = 'seh' - elif 'sjlj' in keys: - exceptions = 'sjlj' - else: - exceptions = keys[0] - if revision == None: - revision = max(versions[version][arch][threading][exceptions].keys()) - if not location: - location = os.path.join(tempfile.gettempdir(), 'mingw-builds') - - # Get the download url - url = versions[version][arch][threading][exceptions][revision] - - # Tell the user whatzzup - log.info('finding MinGW %s', '.'.join(str(v) for v in version)) - log.debug(' - arch: %s', arch) - log.debug(' - threading: %s', threading) - log.debug(' - exceptions: %s', exceptions) - log.debug(' - revision: %s', revision) - log.debug(' - url: %s', url) - - # Store each specific revision differently - slug = '{version}-{arch}-{threading}-{exceptions}-rev{revision}' - slug = slug.format( - version = '.'.join(str(v) for v in version), - arch = arch, - threading = threading, - exceptions = exceptions, - revision = revision - ) - if arch == 'x86_64': - root_dir = os.path.join(location, slug, 'mingw64') - elif arch == 'i686': - root_dir = os.path.join(location, slug, 'mingw32') - else: - raise ValueError('Unknown MinGW arch: ' + arch) - - # Download if needed - if not os.path.exists(root_dir): - downloaded = download(url, os.path.join(location, slug), log = log) - if downloaded != root_dir: - raise ValueError('The location of mingw did not match\n%s\n%s' - % (downloaded, root_dir)) - - return root_dir - -def str2ver(string): - ''' - Converts a version string into a tuple - ''' - try: - version = tuple(int(v) for v in string.split('.')) - if len(version) is not 3: - raise ValueError() - except ValueError: - raise argparse.ArgumentTypeError( - 'please provide a three digit version string') - return version - -def main(): - ''' - Invoked when the script is run directly by the python interpreter - ''' - parser = argparse.ArgumentParser( - description = 'Downloads a specific version of MinGW', - formatter_class = argparse.ArgumentDefaultsHelpFormatter - ) - parser.add_argument('--location', - help = 'the location to download the compiler to', - default = os.path.join(tempfile.gettempdir(), 'mingw-builds')) - parser.add_argument('--arch', required = True, choices = ['i686', 'x86_64'], - help = 'the target MinGW architecture string') - parser.add_argument('--version', type = str2ver, - help = 'the version of GCC to download') - parser.add_argument('--threading', choices = ['posix', 'win32'], - help = 'the threading type of the compiler') - parser.add_argument('--exceptions', choices = ['sjlj', 'seh', 'dwarf'], - help = 'the method to throw exceptions') - parser.add_argument('--revision', type=int, - help = 'the revision of the MinGW release') - group = parser.add_mutually_exclusive_group() - group.add_argument('-v', '--verbose', action='store_true', - help='increase the script output verbosity') - group.add_argument('-q', '--quiet', action='store_true', - help='only print errors and warning') - args = parser.parse_args() - - # Create the logger - logger = logging.getLogger('mingw') - handler = logging.StreamHandler() - formatter = logging.Formatter('%(message)s') - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(logging.INFO) - if args.quiet: - logger.setLevel(logging.WARN) - if args.verbose: - logger.setLevel(logging.DEBUG) - - # Get MinGW - root_dir = root(location = args.location, arch = args.arch, - version = args.version, threading = args.threading, - exceptions = args.exceptions, revision = args.revision, - log = logger) - - sys.stdout.write('%s\n' % os.path.join(root_dir, 'bin')) - -if __name__ == '__main__': - try: - main() - except IOError as e: - sys.stderr.write('IO error: %s\n' % e) - sys.exit(1) - except OSError as e: - sys.stderr.write('OS error: %s\n' % e) - sys.exit(1) - except KeyboardInterrupt as e: - sys.stderr.write('Killed\n') - sys.exit(1) diff --git a/lib/libcxx/utils/google-benchmark/src/stat.h b/lib/libcxx/utils/google-benchmark/src/stat.h deleted file mode 100644 index 136c3aa8d61..00000000000 --- a/lib/libcxx/utils/google-benchmark/src/stat.h +++ /dev/null @@ -1,306 +0,0 @@ -#ifndef BENCHMARK_STAT_H_ -#define BENCHMARK_STAT_H_ - -#include <cmath> -#include <limits> -#include <ostream> -#include <type_traits> - -namespace benchmark { - -template <typename VType, typename NumType> -class Stat1; - -template <typename VType, typename NumType> -class Stat1MinMax; - -typedef Stat1<float, int64_t> Stat1_f; -typedef Stat1<double, int64_t> Stat1_d; -typedef Stat1MinMax<float, int64_t> Stat1MinMax_f; -typedef Stat1MinMax<double, int64_t> Stat1MinMax_d; - -template <typename VType> -class Vector2; -template <typename VType> -class Vector3; -template <typename VType> -class Vector4; - -template <typename VType, typename NumType> -class Stat1 { - public: - typedef Stat1<VType, NumType> Self; - - Stat1() { Clear(); } - // Create a sample of value dat and weight 1 - explicit Stat1(const VType &dat) { - sum_ = dat; - sum_squares_ = Sqr(dat); - numsamples_ = 1; - } - // Create statistics for all the samples between begin (included) - // and end(excluded) - explicit Stat1(const VType *begin, const VType *end) { - Clear(); - for (const VType *item = begin; item < end; ++item) { - (*this) += Stat1(*item); - } - } - // Create a sample of value dat and weight w - Stat1(const VType &dat, const NumType &w) { - sum_ = w * dat; - sum_squares_ = w * Sqr(dat); - numsamples_ = w; - } - // Copy operator - Stat1(const Self &stat) { - sum_ = stat.sum_; - sum_squares_ = stat.sum_squares_; - numsamples_ = stat.numsamples_; - } - - void Clear() { - numsamples_ = NumType(); - sum_squares_ = sum_ = VType(); - } - - Self &operator=(const Self &stat) { - sum_ = stat.sum_; - sum_squares_ = stat.sum_squares_; - numsamples_ = stat.numsamples_; - return (*this); - } - // Merge statistics from two sample sets. - Self &operator+=(const Self &stat) { - sum_ += stat.sum_; - sum_squares_ += stat.sum_squares_; - numsamples_ += stat.numsamples_; - return (*this); - } - // The operation opposite to += - Self &operator-=(const Self &stat) { - sum_ -= stat.sum_; - sum_squares_ -= stat.sum_squares_; - numsamples_ -= stat.numsamples_; - return (*this); - } - // Multiply the weight of the set of samples by a factor k - Self &operator*=(const VType &k) { - sum_ *= k; - sum_squares_ *= k; - numsamples_ *= k; - return (*this); - } - - // Merge statistics from two sample sets. - Self operator+(const Self &stat) const { return Self(*this) += stat; } - - // The operation opposite to + - Self operator-(const Self &stat) const { return Self(*this) -= stat; } - - // Multiply the weight of the set of samples by a factor k - Self operator*(const VType &k) const { return Self(*this) *= k; } - - // Return the total weight of this sample set - NumType numSamples() const { return numsamples_; } - - // Return the sum of this sample set - VType Sum() const { return sum_; } - - // Return the mean of this sample set - VType Mean() const { - if (numsamples_ == 0) return VType(); - return sum_ * (1.0 / numsamples_); - } - - // Return the mean of this sample set and compute the standard deviation at - // the same time. - VType Mean(VType *stddev) const { - if (numsamples_ == 0) return VType(); - VType mean = sum_ * (1.0 / numsamples_); - if (stddev) { - VType avg_squares = sum_squares_ * (1.0 / numsamples_); - *stddev = Sqrt(avg_squares - Sqr(mean)); - } - return mean; - } - - // Return the standard deviation of the sample set - VType StdDev() const { - if (numsamples_ == 0) return VType(); - VType mean = Mean(); - VType avg_squares = sum_squares_ * (1.0 / numsamples_); - return Sqrt(avg_squares - Sqr(mean)); - } - - private: - static_assert(std::is_integral<NumType>::value && - !std::is_same<NumType, bool>::value, - "NumType must be an integral type that is not bool."); - // Let i be the index of the samples provided (using +=) - // and weight[i],value[i] be the data of sample #i - // then the variables have the following meaning: - NumType numsamples_; // sum of weight[i]; - VType sum_; // sum of weight[i]*value[i]; - VType sum_squares_; // sum of weight[i]*value[i]^2; - - // Template function used to square a number. - // For a vector we square all components - template <typename SType> - static inline SType Sqr(const SType &dat) { - return dat * dat; - } - - template <typename SType> - static inline Vector2<SType> Sqr(const Vector2<SType> &dat) { - return dat.MulComponents(dat); - } - - template <typename SType> - static inline Vector3<SType> Sqr(const Vector3<SType> &dat) { - return dat.MulComponents(dat); - } - - template <typename SType> - static inline Vector4<SType> Sqr(const Vector4<SType> &dat) { - return dat.MulComponents(dat); - } - - // Template function used to take the square root of a number. - // For a vector we square all components - template <typename SType> - static inline SType Sqrt(const SType &dat) { - // Avoid NaN due to imprecision in the calculations - if (dat < 0) return 0; - return sqrt(dat); - } - - template <typename SType> - static inline Vector2<SType> Sqrt(const Vector2<SType> &dat) { - // Avoid NaN due to imprecision in the calculations - return Max(dat, Vector2<SType>()).Sqrt(); - } - - template <typename SType> - static inline Vector3<SType> Sqrt(const Vector3<SType> &dat) { - // Avoid NaN due to imprecision in the calculations - return Max(dat, Vector3<SType>()).Sqrt(); - } - - template <typename SType> - static inline Vector4<SType> Sqrt(const Vector4<SType> &dat) { - // Avoid NaN due to imprecision in the calculations - return Max(dat, Vector4<SType>()).Sqrt(); - } -}; - -// Useful printing function -template <typename VType, typename NumType> -std::ostream &operator<<(std::ostream &out, const Stat1<VType, NumType> &s) { - out << "{ avg = " << s.Mean() << " std = " << s.StdDev() - << " nsamples = " << s.NumSamples() << "}"; - return out; -} - -// Stat1MinMax: same as Stat1, but it also -// keeps the Min and Max values; the "-" -// operator is disabled because it cannot be implemented -// efficiently -template <typename VType, typename NumType> -class Stat1MinMax : public Stat1<VType, NumType> { - public: - typedef Stat1MinMax<VType, NumType> Self; - - Stat1MinMax() { Clear(); } - // Create a sample of value dat and weight 1 - explicit Stat1MinMax(const VType &dat) : Stat1<VType, NumType>(dat) { - max_ = dat; - min_ = dat; - } - // Create statistics for all the samples between begin (included) - // and end(excluded) - explicit Stat1MinMax(const VType *begin, const VType *end) { - Clear(); - for (const VType *item = begin; item < end; ++item) { - (*this) += Stat1MinMax(*item); - } - } - // Create a sample of value dat and weight w - Stat1MinMax(const VType &dat, const NumType &w) - : Stat1<VType, NumType>(dat, w) { - max_ = dat; - min_ = dat; - } - // Copy operator - Stat1MinMax(const Self &stat) : Stat1<VType, NumType>(stat) { - max_ = stat.max_; - min_ = stat.min_; - } - - void Clear() { - Stat1<VType, NumType>::Clear(); - if (std::numeric_limits<VType>::has_infinity) { - min_ = std::numeric_limits<VType>::infinity(); - max_ = -std::numeric_limits<VType>::infinity(); - } else { - min_ = std::numeric_limits<VType>::max(); - max_ = std::numeric_limits<VType>::min(); - } - } - - Self &operator=(const Self &stat) { - this->Stat1<VType, NumType>::operator=(stat); - max_ = stat.max_; - min_ = stat.min_; - return (*this); - } - // Merge statistics from two sample sets. - Self &operator+=(const Self &stat) { - this->Stat1<VType, NumType>::operator+=(stat); - if (stat.max_ > max_) max_ = stat.max_; - if (stat.min_ < min_) min_ = stat.min_; - return (*this); - } - // Multiply the weight of the set of samples by a factor k - Self &operator*=(const VType &stat) { - this->Stat1<VType, NumType>::operator*=(stat); - return (*this); - } - // Merge statistics from two sample sets. - Self operator+(const Self &stat) const { return Self(*this) += stat; } - // Multiply the weight of the set of samples by a factor k - Self operator*(const VType &k) const { return Self(*this) *= k; } - - // Return the maximal value in this sample set - VType Max() const { return max_; } - // Return the minimal value in this sample set - VType Min() const { return min_; } - - private: - // The - operation makes no sense with Min/Max - // unless we keep the full list of values (but we don't) - // make it private, and let it undefined so nobody can call it - Self &operator-=(const Self &stat); // senseless. let it undefined. - - // The operation opposite to - - Self operator-(const Self &stat) const; // senseless. let it undefined. - - // Let i be the index of the samples provided (using +=) - // and weight[i],value[i] be the data of sample #i - // then the variables have the following meaning: - VType max_; // max of value[i] - VType min_; // min of value[i] -}; - -// Useful printing function -template <typename VType, typename NumType> -std::ostream &operator<<(std::ostream &out, - const Stat1MinMax<VType, NumType> &s) { - out << "{ avg = " << s.Mean() << " std = " << s.StdDev() - << " nsamples = " << s.NumSamples() << " min = " << s.Min() - << " max = " << s.Max() << "}"; - return out; -} -} // end namespace benchmark - -#endif // BENCHMARK_STAT_H_ diff --git a/lib/libcxx/utils/google-benchmark/src/sysinfo.h b/lib/libcxx/utils/google-benchmark/src/sysinfo.h deleted file mode 100644 index c5d9916d2dd..00000000000 --- a/lib/libcxx/utils/google-benchmark/src/sysinfo.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef BENCHMARK_SYSINFO_H_ -#define BENCHMARK_SYSINFO_H_ - -namespace benchmark { -int NumCPUs(); -double CyclesPerSecond(); -bool CpuScalingEnabled(); -} // end namespace benchmark - -#endif // BENCHMARK_SYSINFO_H_ diff --git a/lib/libcxx/utils/libcxx/test/config.py b/lib/libcxx/utils/libcxx/test/config.py index dbdb670460e..8007b4ee00b 100644 --- a/lib/libcxx/utils/libcxx/test/config.py +++ b/lib/libcxx/utils/libcxx/test/config.py @@ -50,6 +50,11 @@ def loadSiteConfig(lit_config, config, param_name, env_name): ld_fn(config, site_cfg) lit_config.load_config = ld_fn +# Extract the value of a numeric macro such as __cplusplus or a feature-test +# macro. +def intMacroValue(token): + return int(token.rstrip('LlUu')) + class Configuration(object): # pylint: disable=redefined-outer-name def __init__(self, lit_config, config): @@ -463,7 +468,8 @@ class Configuration(object): if '__cpp_structured_bindings' not in macros: self.config.available_features.add('libcpp-no-structured-bindings') - if '__cpp_deduction_guides' not in macros: + if '__cpp_deduction_guides' not in macros or \ + intMacroValue(macros['__cpp_deduction_guides']) < 201611: self.config.available_features.add('libcpp-no-deduction-guides') if self.is_windows: @@ -509,6 +515,9 @@ class Configuration(object): # and so that those tests don't have to be changed to tolerate # this insanity. self.cxx.compile_flags += ['-DNOMINMAX'] + additional_flags = self.get_lit_conf('test_compiler_flags') + if additional_flags: + self.cxx.compile_flags += shlex.split(additional_flags) def configure_default_compile_flags(self): # Try and get the std version from the command line. Fall back to @@ -668,7 +677,8 @@ class Configuration(object): if feature_macros[m]: define += '=%s' % (feature_macros[m]) self.cxx.compile_flags += [define] - if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS': + if m == '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS' or \ + m == '_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT': continue if m == '_LIBCPP_ABI_VERSION': self.config.available_features.add('libcpp-abi-version-v%s' @@ -711,13 +721,9 @@ class Configuration(object): enable_fs = self.get_lit_bool('enable_filesystem', default=False) if not enable_fs: return - enable_experimental = self.get_lit_bool('enable_experimental', default=False) - if not enable_experimental: - self.lit_config.fatal( - 'filesystem is enabled but libc++experimental.a is not.') self.config.available_features.add('c++filesystem') static_env = os.path.join(self.libcxx_src_root, 'test', 'std', - 'experimental', 'filesystem', 'Inputs', 'static_test_env') + 'input.output', 'filesystems', 'Inputs', 'static_test_env') static_env = os.path.realpath(static_env) assert os.path.isdir(static_env) self.cxx.compile_flags += ['-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="%s"' % static_env] @@ -793,6 +799,9 @@ class Configuration(object): self.use_system_cxx_lib] if self.is_windows and self.link_shared: self.add_path(self.cxx.compile_env, self.use_system_cxx_lib) + additional_flags = self.get_lit_conf('test_linker_flags') + if additional_flags: + self.cxx.link_flags += shlex.split(additional_flags) def configure_link_flags_abi_library_path(self): # Configure ABI library paths. @@ -809,6 +818,10 @@ class Configuration(object): if libcxx_experimental: self.config.available_features.add('c++experimental') self.cxx.link_flags += ['-lc++experimental'] + libcxx_fs = self.get_lit_bool('enable_filesystem', default=False) + if libcxx_fs: + self.config.available_features.add('c++fs') + self.cxx.link_flags += ['-lc++fs'] if self.link_shared: self.cxx.link_flags += ['-lc++'] else: @@ -921,9 +934,6 @@ class Configuration(object): # FIXME: Enable the two warnings below. self.cxx.addWarningFlagIfSupported('-Wno-conversion') self.cxx.addWarningFlagIfSupported('-Wno-unused-local-typedef') - # FIXME: Remove this warning once the min/max handling patch lands - # See https://reviews.llvm.org/D33080 - self.cxx.addWarningFlagIfSupported('-Wno-#warnings') std = self.get_lit_conf('std', None) if std in ['c++98', 'c++03']: # The '#define static_assert' provided by libc++ in C++03 mode @@ -1005,8 +1015,7 @@ class Configuration(object): '__cpp_coroutines is not defined') # Consider coroutines supported only when the feature test macro # reflects a recent value. - val = macros['__cpp_coroutines'].replace('L', '') - if int(val) >= 201703: + if intMacroValue(macros['__cpp_coroutines']) >= 201703: self.config.available_features.add('fcoroutines-ts') def configure_modules(self): diff --git a/lib/libunwind/include/__libunwind_config.h b/lib/libunwind/include/__libunwind_config.h index 2b7158c36ef..9effc8ac58a 100644 --- a/lib/libunwind/include/__libunwind_config.h +++ b/lib/libunwind/include/__libunwind_config.h @@ -18,10 +18,10 @@ #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 8 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 32 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC 112 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 110 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 116 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287 -#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 32 @@ -43,8 +43,8 @@ # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64 # elif defined(__powerpc64__) # define _LIBUNWIND_TARGET_PPC64 1 -# define _LIBUNWIND_CONTEXT_SIZE 136 -# define _LIBUNWIND_CURSOR_SIZE 148 +# define _LIBUNWIND_CONTEXT_SIZE 167 +# define _LIBUNWIND_CURSOR_SIZE 179 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64 # elif defined(__ppc__) # define _LIBUNWIND_TARGET_PPC 1 @@ -72,7 +72,7 @@ # define _LIBUNWIND_CURSOR_SIZE 24 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K # elif defined(__mips__) -# if defined(_ABIO32) +# if defined(_ABIO32) && _MIPS_SIM == _ABIO32 # define _LIBUNWIND_TARGET_MIPS_O32 1 # if defined(__mips_hard_float) # define _LIBUNWIND_CONTEXT_SIZE 50 @@ -81,8 +81,17 @@ # define _LIBUNWIND_CONTEXT_SIZE 18 # define _LIBUNWIND_CURSOR_SIZE 24 # endif -# elif defined(_ABI64) -# define _LIBUNWIND_TARGET_MIPS_N64 1 +# elif defined(_ABIN32) && _MIPS_SIM == _ABIN32 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +# if defined(__mips_hard_float) +# define _LIBUNWIND_CONTEXT_SIZE 67 +# define _LIBUNWIND_CURSOR_SIZE 74 +# else +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 42 +# endif +# elif defined(_ABI64) && _MIPS_SIM == _ABI64 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 # if defined(__mips_hard_float) # define _LIBUNWIND_CONTEXT_SIZE 67 # define _LIBUNWIND_CURSOR_SIZE 79 @@ -111,10 +120,10 @@ # define _LIBUNWIND_TARGET_ARM 1 # define _LIBUNWIND_TARGET_OR1K 1 # define _LIBUNWIND_TARGET_MIPS_O32 1 -# define _LIBUNWIND_TARGET_MIPS_N64 1 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 # define _LIBUNWIND_TARGET_SPARC64 1 -# define _LIBUNWIND_CONTEXT_SIZE 136 -# define _LIBUNWIND_CURSOR_SIZE 148 +# define _LIBUNWIND_CONTEXT_SIZE 167 +# define _LIBUNWIND_CURSOR_SIZE 179 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 #endif // _LIBUNWIND_IS_NATIVE_ONLY diff --git a/lib/libunwind/include/libunwind.h b/lib/libunwind/include/libunwind.h index 6598a3216e1..97d2b82290c 100644 --- a/lib/libunwind/include/libunwind.h +++ b/lib/libunwind/include/libunwind.h @@ -327,116 +327,186 @@ enum { // 64-bit ppc register numbers enum { - UNW_PPC64_R0 = 0, - UNW_PPC64_R1 = 1, - UNW_PPC64_R2 = 2, - UNW_PPC64_R3 = 3, - UNW_PPC64_R4 = 4, - UNW_PPC64_R5 = 5, - UNW_PPC64_R6 = 6, - UNW_PPC64_R7 = 7, - UNW_PPC64_R8 = 8, - UNW_PPC64_R9 = 9, - UNW_PPC64_R10 = 10, - UNW_PPC64_R11 = 11, - UNW_PPC64_R12 = 12, - UNW_PPC64_R13 = 13, - UNW_PPC64_R14 = 14, - UNW_PPC64_R15 = 15, - UNW_PPC64_R16 = 16, - UNW_PPC64_R17 = 17, - UNW_PPC64_R18 = 18, - UNW_PPC64_R19 = 19, - UNW_PPC64_R20 = 20, - UNW_PPC64_R21 = 21, - UNW_PPC64_R22 = 22, - UNW_PPC64_R23 = 23, - UNW_PPC64_R24 = 24, - UNW_PPC64_R25 = 25, - UNW_PPC64_R26 = 26, - UNW_PPC64_R27 = 27, - UNW_PPC64_R28 = 28, - UNW_PPC64_R29 = 29, - UNW_PPC64_R30 = 30, - UNW_PPC64_R31 = 31, - UNW_PPC64_F0 = 32, - UNW_PPC64_F1 = 33, - UNW_PPC64_F2 = 34, - UNW_PPC64_F3 = 35, - UNW_PPC64_F4 = 36, - UNW_PPC64_F5 = 37, - UNW_PPC64_F6 = 38, - UNW_PPC64_F7 = 39, - UNW_PPC64_F8 = 40, - UNW_PPC64_F9 = 41, - UNW_PPC64_F10 = 42, - UNW_PPC64_F11 = 43, - UNW_PPC64_F12 = 44, - UNW_PPC64_F13 = 45, - UNW_PPC64_F14 = 46, - UNW_PPC64_F15 = 47, - UNW_PPC64_F16 = 48, - UNW_PPC64_F17 = 49, - UNW_PPC64_F18 = 50, - UNW_PPC64_F19 = 51, - UNW_PPC64_F20 = 52, - UNW_PPC64_F21 = 53, - UNW_PPC64_F22 = 54, - UNW_PPC64_F23 = 55, - UNW_PPC64_F24 = 56, - UNW_PPC64_F25 = 57, - UNW_PPC64_F26 = 58, - UNW_PPC64_F27 = 59, - UNW_PPC64_F28 = 60, - UNW_PPC64_F29 = 61, - UNW_PPC64_F30 = 62, - UNW_PPC64_F31 = 63, - UNW_PPC64_LR = 64, - UNW_PPC64_CTR = 65, - UNW_PPC64_CR0 = 66, - UNW_PPC64_CR1 = 67, - UNW_PPC64_CR2 = 68, - UNW_PPC64_CR3 = 69, - UNW_PPC64_CR4 = 70, - UNW_PPC64_CR5 = 71, - UNW_PPC64_CR6 = 72, - UNW_PPC64_CR7 = 73, - UNW_PPC64_XER = 74, - UNW_PPC64_V0 = 75, - UNW_PPC64_V1 = 76, - UNW_PPC64_V2 = 77, - UNW_PPC64_V3 = 78, - UNW_PPC64_V4 = 79, - UNW_PPC64_V5 = 80, - UNW_PPC64_V6 = 81, - UNW_PPC64_V7 = 82, - UNW_PPC64_V8 = 83, - UNW_PPC64_V9 = 84, - UNW_PPC64_V10 = 85, - UNW_PPC64_V11 = 86, - UNW_PPC64_V12 = 87, - UNW_PPC64_V13 = 88, - UNW_PPC64_V14 = 89, - UNW_PPC64_V15 = 90, - UNW_PPC64_V16 = 91, - UNW_PPC64_V17 = 92, - UNW_PPC64_V18 = 93, - UNW_PPC64_V19 = 94, - UNW_PPC64_V20 = 95, - UNW_PPC64_V21 = 96, - UNW_PPC64_V22 = 97, - UNW_PPC64_V23 = 98, - UNW_PPC64_V24 = 99, - UNW_PPC64_V25 = 100, - UNW_PPC64_V26 = 101, - UNW_PPC64_V27 = 102, - UNW_PPC64_V28 = 103, - UNW_PPC64_V29 = 104, - UNW_PPC64_V30 = 105, - UNW_PPC64_V31 = 106, - UNW_PPC64_VRSAVE = 107, - UNW_PPC64_VSCR = 108, - UNW_PPC64_FPSCR = 109 + UNW_PPC64_R0 = 0, + UNW_PPC64_R1 = 1, + UNW_PPC64_R2 = 2, + UNW_PPC64_R3 = 3, + UNW_PPC64_R4 = 4, + UNW_PPC64_R5 = 5, + UNW_PPC64_R6 = 6, + UNW_PPC64_R7 = 7, + UNW_PPC64_R8 = 8, + UNW_PPC64_R9 = 9, + UNW_PPC64_R10 = 10, + UNW_PPC64_R11 = 11, + UNW_PPC64_R12 = 12, + UNW_PPC64_R13 = 13, + UNW_PPC64_R14 = 14, + UNW_PPC64_R15 = 15, + UNW_PPC64_R16 = 16, + UNW_PPC64_R17 = 17, + UNW_PPC64_R18 = 18, + UNW_PPC64_R19 = 19, + UNW_PPC64_R20 = 20, + UNW_PPC64_R21 = 21, + UNW_PPC64_R22 = 22, + UNW_PPC64_R23 = 23, + UNW_PPC64_R24 = 24, + UNW_PPC64_R25 = 25, + UNW_PPC64_R26 = 26, + UNW_PPC64_R27 = 27, + UNW_PPC64_R28 = 28, + UNW_PPC64_R29 = 29, + UNW_PPC64_R30 = 30, + UNW_PPC64_R31 = 31, + UNW_PPC64_F0 = 32, + UNW_PPC64_F1 = 33, + UNW_PPC64_F2 = 34, + UNW_PPC64_F3 = 35, + UNW_PPC64_F4 = 36, + UNW_PPC64_F5 = 37, + UNW_PPC64_F6 = 38, + UNW_PPC64_F7 = 39, + UNW_PPC64_F8 = 40, + UNW_PPC64_F9 = 41, + UNW_PPC64_F10 = 42, + UNW_PPC64_F11 = 43, + UNW_PPC64_F12 = 44, + UNW_PPC64_F13 = 45, + UNW_PPC64_F14 = 46, + UNW_PPC64_F15 = 47, + UNW_PPC64_F16 = 48, + UNW_PPC64_F17 = 49, + UNW_PPC64_F18 = 50, + UNW_PPC64_F19 = 51, + UNW_PPC64_F20 = 52, + UNW_PPC64_F21 = 53, + UNW_PPC64_F22 = 54, + UNW_PPC64_F23 = 55, + UNW_PPC64_F24 = 56, + UNW_PPC64_F25 = 57, + UNW_PPC64_F26 = 58, + UNW_PPC64_F27 = 59, + UNW_PPC64_F28 = 60, + UNW_PPC64_F29 = 61, + UNW_PPC64_F30 = 62, + UNW_PPC64_F31 = 63, + // 64: reserved + UNW_PPC64_LR = 65, + UNW_PPC64_CTR = 66, + // 67: reserved + UNW_PPC64_CR0 = 68, + UNW_PPC64_CR1 = 69, + UNW_PPC64_CR2 = 70, + UNW_PPC64_CR3 = 71, + UNW_PPC64_CR4 = 72, + UNW_PPC64_CR5 = 73, + UNW_PPC64_CR6 = 74, + UNW_PPC64_CR7 = 75, + UNW_PPC64_XER = 76, + UNW_PPC64_V0 = 77, + UNW_PPC64_V1 = 78, + UNW_PPC64_V2 = 79, + UNW_PPC64_V3 = 80, + UNW_PPC64_V4 = 81, + UNW_PPC64_V5 = 82, + UNW_PPC64_V6 = 83, + UNW_PPC64_V7 = 84, + UNW_PPC64_V8 = 85, + UNW_PPC64_V9 = 86, + UNW_PPC64_V10 = 87, + UNW_PPC64_V11 = 88, + UNW_PPC64_V12 = 89, + UNW_PPC64_V13 = 90, + UNW_PPC64_V14 = 91, + UNW_PPC64_V15 = 92, + UNW_PPC64_V16 = 93, + UNW_PPC64_V17 = 94, + UNW_PPC64_V18 = 95, + UNW_PPC64_V19 = 96, + UNW_PPC64_V20 = 97, + UNW_PPC64_V21 = 98, + UNW_PPC64_V22 = 99, + UNW_PPC64_V23 = 100, + UNW_PPC64_V24 = 101, + UNW_PPC64_V25 = 102, + UNW_PPC64_V26 = 103, + UNW_PPC64_V27 = 104, + UNW_PPC64_V28 = 105, + UNW_PPC64_V29 = 106, + UNW_PPC64_V30 = 107, + UNW_PPC64_V31 = 108, + // 109, 111-113: OpenPOWER ELF V2 ABI: reserved + // Borrowing VRSAVE number from PPC32. + UNW_PPC64_VRSAVE = 109, + UNW_PPC64_VSCR = 110, + UNW_PPC64_TFHAR = 114, + UNW_PPC64_TFIAR = 115, + UNW_PPC64_TEXASR = 116, + UNW_PPC64_VS0 = UNW_PPC64_F0, + UNW_PPC64_VS1 = UNW_PPC64_F1, + UNW_PPC64_VS2 = UNW_PPC64_F2, + UNW_PPC64_VS3 = UNW_PPC64_F3, + UNW_PPC64_VS4 = UNW_PPC64_F4, + UNW_PPC64_VS5 = UNW_PPC64_F5, + UNW_PPC64_VS6 = UNW_PPC64_F6, + UNW_PPC64_VS7 = UNW_PPC64_F7, + UNW_PPC64_VS8 = UNW_PPC64_F8, + UNW_PPC64_VS9 = UNW_PPC64_F9, + UNW_PPC64_VS10 = UNW_PPC64_F10, + UNW_PPC64_VS11 = UNW_PPC64_F11, + UNW_PPC64_VS12 = UNW_PPC64_F12, + UNW_PPC64_VS13 = UNW_PPC64_F13, + UNW_PPC64_VS14 = UNW_PPC64_F14, + UNW_PPC64_VS15 = UNW_PPC64_F15, + UNW_PPC64_VS16 = UNW_PPC64_F16, + UNW_PPC64_VS17 = UNW_PPC64_F17, + UNW_PPC64_VS18 = UNW_PPC64_F18, + UNW_PPC64_VS19 = UNW_PPC64_F19, + UNW_PPC64_VS20 = UNW_PPC64_F20, + UNW_PPC64_VS21 = UNW_PPC64_F21, + UNW_PPC64_VS22 = UNW_PPC64_F22, + UNW_PPC64_VS23 = UNW_PPC64_F23, + UNW_PPC64_VS24 = UNW_PPC64_F24, + UNW_PPC64_VS25 = UNW_PPC64_F25, + UNW_PPC64_VS26 = UNW_PPC64_F26, + UNW_PPC64_VS27 = UNW_PPC64_F27, + UNW_PPC64_VS28 = UNW_PPC64_F28, + UNW_PPC64_VS29 = UNW_PPC64_F29, + UNW_PPC64_VS30 = UNW_PPC64_F30, + UNW_PPC64_VS31 = UNW_PPC64_F31, + UNW_PPC64_VS32 = UNW_PPC64_V0, + UNW_PPC64_VS33 = UNW_PPC64_V1, + UNW_PPC64_VS34 = UNW_PPC64_V2, + UNW_PPC64_VS35 = UNW_PPC64_V3, + UNW_PPC64_VS36 = UNW_PPC64_V4, + UNW_PPC64_VS37 = UNW_PPC64_V5, + UNW_PPC64_VS38 = UNW_PPC64_V6, + UNW_PPC64_VS39 = UNW_PPC64_V7, + UNW_PPC64_VS40 = UNW_PPC64_V8, + UNW_PPC64_VS41 = UNW_PPC64_V9, + UNW_PPC64_VS42 = UNW_PPC64_V10, + UNW_PPC64_VS43 = UNW_PPC64_V11, + UNW_PPC64_VS44 = UNW_PPC64_V12, + UNW_PPC64_VS45 = UNW_PPC64_V13, + UNW_PPC64_VS46 = UNW_PPC64_V14, + UNW_PPC64_VS47 = UNW_PPC64_V15, + UNW_PPC64_VS48 = UNW_PPC64_V16, + UNW_PPC64_VS49 = UNW_PPC64_V17, + UNW_PPC64_VS50 = UNW_PPC64_V18, + UNW_PPC64_VS51 = UNW_PPC64_V19, + UNW_PPC64_VS52 = UNW_PPC64_V20, + UNW_PPC64_VS53 = UNW_PPC64_V21, + UNW_PPC64_VS54 = UNW_PPC64_V22, + UNW_PPC64_VS55 = UNW_PPC64_V23, + UNW_PPC64_VS56 = UNW_PPC64_V24, + UNW_PPC64_VS57 = UNW_PPC64_V25, + UNW_PPC64_VS58 = UNW_PPC64_V26, + UNW_PPC64_VS59 = UNW_PPC64_V27, + UNW_PPC64_VS60 = UNW_PPC64_V28, + UNW_PPC64_VS61 = UNW_PPC64_V29, + UNW_PPC64_VS62 = UNW_PPC64_V30, + UNW_PPC64_VS63 = UNW_PPC64_V31 }; // 64-bit ARM64 registers @@ -675,6 +745,7 @@ enum { UNW_OR1K_R29 = 29, UNW_OR1K_R30 = 30, UNW_OR1K_R31 = 31, + UNW_OR1K_EPCR = 32, }; // MIPS registers diff --git a/lib/libunwind/include/mach-o/compact_unwind_encoding.h b/lib/libunwind/include/mach-o/compact_unwind_encoding.h index b71c2c8f5b7..de14fd51e53 100644 --- a/lib/libunwind/include/mach-o/compact_unwind_encoding.h +++ b/lib/libunwind/include/mach-o/compact_unwind_encoding.h @@ -6,7 +6,7 @@ // Source Licenses. See LICENSE.TXT for details. // // -// Darwin's alternative to dwarf based unwind encodings. +// Darwin's alternative to DWARF based unwind encodings. // //===----------------------------------------------------------------------===// @@ -17,7 +17,7 @@ #include <stdint.h> // -// Compilers can emit standard Dwarf FDEs in the __TEXT,__eh_frame section +// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section // of object files. Or compilers can emit compact unwind information in // the __LD,__compact_unwind section. // @@ -26,10 +26,10 @@ // runtime to access unwind info for any given function. If the compiler // emitted compact unwind info for the function, that compact unwind info will // be encoded in the __TEXT,__unwind_info section. If the compiler emitted -// dwarf unwind info, the __TEXT,__unwind_info section will contain the offset +// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset // of the FDE in the __TEXT,__eh_frame section in the final linked image. // -// Note: Previously, the linker would transform some dwarf unwind infos into +// Note: Previously, the linker would transform some DWARF unwind infos into // compact unwind info. But that is fragile and no longer done. @@ -58,7 +58,7 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=dwarf +// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF // ebp based: // 15-bits (5*3-bits per reg) register permutation // 8-bits for stack offset @@ -128,9 +128,9 @@ enum { // UNWIND_X86_FRAMELESS_STACK_SIZE. // UNWIND_X86_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the dwarf FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only dwarf unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // // The permutation encoding is a Lehmer code sequence encoded into a @@ -193,7 +193,7 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=dwarf +// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF // rbp based: // 15-bits (5*3-bits per reg) register permutation // 8-bits for stack offset @@ -262,9 +262,9 @@ enum { // UNWIND_X86_64_FRAMELESS_STACK_SIZE. // UNWIND_X86_64_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the dwarf FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only dwarf unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // @@ -275,14 +275,14 @@ enum { // 1-bit: has lsda // 2-bit: personality index // -// 4-bits: 4=frame-based, 3=dwarf, 2=frameless +// 4-bits: 4=frame-based, 3=DWARF, 2=frameless // frameless: // 12-bits of stack size // frame-based: // 4-bits D reg pairs saved // 5-bits X reg pairs saved -// dwarf: -// 24-bits offset of dwarf FDE in __eh_frame section +// DWARF: +// 24-bits offset of DWARF FDE in __eh_frame section // enum { UNWIND_ARM64_MODE_MASK = 0x0F000000, @@ -320,9 +320,9 @@ enum { // UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK. // UNWIND_ARM64_MODE_DWARF: // No compact unwind encoding is available. Instead the low 24-bits of the -// compact encoding is the offset of the dwarf FDE in the __eh_frame section. +// compact encoding is the offset of the DWARF FDE in the __eh_frame section. // This mode is never used in object files. It is only generated by the -// linker in final linked images which have only dwarf unwind info for a +// linker in final linked images which have only DWARF unwind info for a // function. // @@ -385,7 +385,7 @@ enum { // saved at that range of the function. // // If a particular function is so wacky that there is no compact unwind way -// to encode it, then the compiler can emit traditional dwarf unwind info. +// to encode it, then the compiler can emit traditional DWARF unwind info. // The runtime will use which ever is available. // // Runtime support for compact unwind encodings are only available on 10.6 diff --git a/lib/libunwind/src/AddressSpace.hpp b/lib/libunwind/src/AddressSpace.hpp index 17145755747..7d1c5249cc9 100644 --- a/lib/libunwind/src/AddressSpace.hpp +++ b/lib/libunwind/src/AddressSpace.hpp @@ -18,7 +18,15 @@ #include <stdlib.h> #include <string.h> -#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) +#ifndef _LIBUNWIND_USE_DLADDR + #if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) + #define _LIBUNWIND_USE_DLADDR 1 + #else + #define _LIBUNWIND_USE_DLADDR 0 + #endif +#endif + +#if _LIBUNWIND_USE_DLADDR #include <dlfcn.h> #endif @@ -207,6 +215,7 @@ public: return val; } uintptr_t getP(pint_t addr); + uint64_t getRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -228,6 +237,14 @@ inline uintptr_t LocalAddressSpace::getP(pint_t addr) { #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if __SIZEOF_POINTER__ == 8 || defined(__mips64) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -571,7 +588,7 @@ inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, size_t bufLen, unw_word_t *offset) { -#if !defined(_LIBUNWIND_IS_BAREMETAL) && !defined(_WIN32) +#if _LIBUNWIND_USE_DLADDR Dl_info dyldInfo; if (dladdr((void *)addr, &dyldInfo)) { if (dyldInfo.dli_sname != NULL) { @@ -604,6 +621,7 @@ public: uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_t getP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -640,7 +658,12 @@ typename P::uint_t RemoteAddressSpace<P>::getP(pint_t addr) { } template <typename P> -uint64_t RemoteAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace<P>::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template <typename P> +uint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; diff --git a/lib/libunwind/src/DwarfInstructions.hpp b/lib/libunwind/src/DwarfInstructions.hpp index eff054e7a06..93de0c0ea57 100644 --- a/lib/libunwind/src/DwarfInstructions.hpp +++ b/lib/libunwind/src/DwarfInstructions.hpp @@ -82,14 +82,14 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser<A>::kRegisterInCFA: - return addressSpace.getP(cfa + (pint_t)savedReg.value); + return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser<A>::kRegisterInCFADecrypt: return addressSpace.getP( cfa + (pint_t)savedReg.value) ^ registers.getWCookie(); case CFI_Parser<A>::kRegisterAtExpression: - return addressSpace.getP( + return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); diff --git a/lib/libunwind/src/Registers.hpp b/lib/libunwind/src/Registers.hpp index 6676daa1b09..5696357855d 100644 --- a/lib/libunwind/src/Registers.hpp +++ b/lib/libunwind/src/Registers.hpp @@ -1110,7 +1110,7 @@ inline const char *Registers_ppc::getRegisterName(int regNum) { #endif // _LIBUNWIND_TARGET_PPC #if defined(_LIBUNWIND_TARGET_PPC64) -/// Registers_ppc holds the register state of a thread in a 64-bit PowerPC +/// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC /// process. class _LIBUNWIND_HIDDEN Registers_ppc64 { public: @@ -1137,8 +1137,8 @@ public: private: struct ppc64_thread_state_t { - uint64_t __srr0; /* Instruction address register (PC) */ - uint64_t __srr1; /* Machine state register (supervisor) */ + uint64_t __srr0; // Instruction address register (PC) + uint64_t __srr1; // Machine state register (supervisor) uint64_t __r0; uint64_t __r1; uint64_t __r2; @@ -1171,21 +1171,25 @@ private: uint64_t __r29; uint64_t __r30; uint64_t __r31; - uint64_t __cr; /* Condition register */ - uint64_t __xer; /* User's integer exception register */ - uint64_t __lr; /* Link register */ - uint64_t __ctr; /* Count register */ - uint64_t __vrsave; /* Vector Save Register */ + uint64_t __cr; // Condition register + uint64_t __xer; // User's integer exception register + uint64_t __lr; // Link register + uint64_t __ctr; // Count register + uint64_t __vrsave; // Vector Save Register }; - struct ppc64_float_state_t { - double __fpregs[32]; - uint64_t __fpscr; /* floating point status register */ + union ppc64_vsr_t { + struct asfloat_s { + double f; + uint64_t v2; + } asfloat; + v128 v; }; ppc64_thread_state_t _registers; - ppc64_float_state_t _floatRegisters; - v128 _vectorRegisters[32]; + ppc64_vsr_t _vectorScalarRegisters[64]; + + static int getVectorRegNum(int num); }; inline Registers_ppc64::Registers_ppc64(const void *registers) { @@ -1193,32 +1197,29 @@ inline Registers_ppc64::Registers_ppc64(const void *registers) { "ppc64 registers do not fit into unw_context_t"); memcpy(&_registers, static_cast<const uint8_t *>(registers), sizeof(_registers)); - static_assert(sizeof(ppc64_thread_state_t) == 312, - "expected float register offset to be 312"); - memcpy(&_floatRegisters, - static_cast<const uint8_t *>(registers) + sizeof(ppc64_thread_state_t), - sizeof(_floatRegisters)); - static_assert(sizeof(ppc64_thread_state_t) + sizeof(ppc64_float_state_t) == 576, - "expected vector register offset to be 576 bytes"); - memcpy(_vectorRegisters, - static_cast<const uint8_t *>(registers) + sizeof(ppc64_thread_state_t) + - sizeof(ppc64_float_state_t), - sizeof(_vectorRegisters)); + static_assert(sizeof(_registers) == 312, + "expected vector scalar register offset to be 312"); + memcpy(&_vectorScalarRegisters, + static_cast<const uint8_t *>(registers) + sizeof(_registers), + sizeof(_vectorScalarRegisters)); + static_assert(sizeof(_registers) + + sizeof(_vectorScalarRegisters) == 1336, + "expected vector register offset to be 1336 bytes"); } inline Registers_ppc64::Registers_ppc64() { memset(&_registers, 0, sizeof(_registers)); - memset(&_floatRegisters, 0, sizeof(_floatRegisters)); - memset(&_vectorRegisters, 0, sizeof(_vectorRegisters)); + memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters)); } inline bool Registers_ppc64::validRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: case UNW_REG_SP: - case UNW_PPC64_VRSAVE: + case UNW_PPC64_XER: case UNW_PPC64_LR: case UNW_PPC64_CTR: + case UNW_PPC64_VRSAVE: return true; } @@ -1234,11 +1235,10 @@ inline uint64_t Registers_ppc64::getRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: return _registers.__srr0; - case UNW_REG_SP: - return _registers.__r1; case UNW_PPC64_R0: return _registers.__r0; case UNW_PPC64_R1: + case UNW_REG_SP: return _registers.__r1; case UNW_PPC64_R2: return _registers.__r2; @@ -1300,10 +1300,6 @@ inline uint64_t Registers_ppc64::getRegister(int regNum) const { return _registers.__r30; case UNW_PPC64_R31: return _registers.__r31; - case UNW_PPC64_LR: - return _registers.__lr; - case UNW_PPC64_CTR: - return _registers.__ctr; case UNW_PPC64_CR0: return (_registers.__cr & 0xF0000000); case UNW_PPC64_CR1: @@ -1320,10 +1316,14 @@ inline uint64_t Registers_ppc64::getRegister(int regNum) const { return (_registers.__cr & 0x000000F0); case UNW_PPC64_CR7: return (_registers.__cr & 0x0000000F); + case UNW_PPC64_XER: + return _registers.__xer; + case UNW_PPC64_LR: + return _registers.__lr; + case UNW_PPC64_CTR: + return _registers.__ctr; case UNW_PPC64_VRSAVE: return _registers.__vrsave; - case UNW_PPC64_FPSCR: - return _floatRegisters.__fpscr; } _LIBUNWIND_ABORT("unsupported ppc64 register"); } @@ -1333,13 +1333,11 @@ inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { case UNW_REG_IP: _registers.__srr0 = value; return; - case UNW_REG_SP: - _registers.__r1 = value; - return; case UNW_PPC64_R0: _registers.__r0 = value; return; case UNW_PPC64_R1: + case UNW_REG_SP: _registers.__r1 = value; return; case UNW_PPC64_R2: @@ -1432,12 +1430,6 @@ inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { case UNW_PPC64_R31: _registers.__r31 = value; return; - case UNW_PPC64_LR: - _registers.__lr = value; - return; - case UNW_PPC64_CTR: - _registers.__ctr = value; - return; case UNW_PPC64_CR0: _registers.__cr &= 0x0FFFFFFF; _registers.__cr |= (value & 0xF0000000); @@ -1470,54 +1462,65 @@ inline void Registers_ppc64::setRegister(int regNum, uint64_t value) { _registers.__cr &= 0xFFFFFFF0; _registers.__cr |= (value & 0x0000000F); return; - case UNW_PPC64_VRSAVE: - _registers.__vrsave = value; - return; case UNW_PPC64_XER: _registers.__xer = value; return; - case UNW_PPC64_VSCR: - // not saved + case UNW_PPC64_LR: + _registers.__lr = value; + return; + case UNW_PPC64_CTR: + _registers.__ctr = value; + return; + case UNW_PPC64_VRSAVE: + _registers.__vrsave = value; return; } _LIBUNWIND_ABORT("unsupported ppc64 register"); } inline bool Registers_ppc64::validFloatRegister(int regNum) const { - if (regNum < UNW_PPC64_F0) - return false; - if (regNum > UNW_PPC64_F31) - return false; - return true; + return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31; } inline double Registers_ppc64::getFloatRegister(int regNum) const { assert(validFloatRegister(regNum)); - return _floatRegisters.__fpregs[regNum - UNW_PPC64_F0]; + return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f; } inline void Registers_ppc64::setFloatRegister(int regNum, double value) { assert(validFloatRegister(regNum)); - _floatRegisters.__fpregs[regNum - UNW_PPC64_F0] = value; + _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value; } inline bool Registers_ppc64::validVectorRegister(int regNum) const { - if (regNum < UNW_PPC64_V0) - return false; - if (regNum > UNW_PPC64_V31) - return false; - return true; +#ifdef PPC64_HAS_VMX + if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31) + return true; + if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63) + return true; +#else + if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31) + return true; +#endif + return false; +} + +inline int Registers_ppc64::getVectorRegNum(int num) +{ + if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31) + return num - UNW_PPC64_VS0; + else + return num - UNW_PPC64_VS32 + 32; } inline v128 Registers_ppc64::getVectorRegister(int regNum) const { assert(validVectorRegister(regNum)); - v128 result = _vectorRegisters[regNum - UNW_PPC64_V0]; - return result; + return _vectorScalarRegisters[getVectorRegNum(regNum)].v; } inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) { assert(validVectorRegister(regNum)); - _vectorRegisters[regNum - UNW_PPC64_V0] = value; + _vectorScalarRegisters[getVectorRegNum(regNum)].v = value; } inline const char *Registers_ppc64::getRegisterName(int regNum) { @@ -1590,6 +1593,30 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) { return "r30"; case UNW_PPC64_R31: return "r31"; + case UNW_PPC64_CR0: + return "cr0"; + case UNW_PPC64_CR1: + return "cr1"; + case UNW_PPC64_CR2: + return "cr2"; + case UNW_PPC64_CR3: + return "cr3"; + case UNW_PPC64_CR4: + return "cr4"; + case UNW_PPC64_CR5: + return "cr5"; + case UNW_PPC64_CR6: + return "cr6"; + case UNW_PPC64_CR7: + return "cr7"; + case UNW_PPC64_XER: + return "xer"; + case UNW_PPC64_LR: + return "lr"; + case UNW_PPC64_CTR: + return "ctr"; + case UNW_PPC64_VRSAVE: + return "vrsave"; case UNW_PPC64_F0: return "fp0"; case UNW_PPC64_F1: @@ -1654,35 +1681,72 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) { return "fp30"; case UNW_PPC64_F31: return "fp31"; - case UNW_PPC64_LR: - return "lr"; - case UNW_PPC64_CTR: - return "ctr"; - case UNW_PPC64_CR0: - return "cr0"; - case UNW_PPC64_CR1: - return "cr1"; - case UNW_PPC64_CR2: - return "cr2"; - case UNW_PPC64_CR3: - return "cr3"; - case UNW_PPC64_CR4: - return "cr4"; - case UNW_PPC64_CR5: - return "cr5"; - case UNW_PPC64_CR6: - return "cr6"; - case UNW_PPC64_CR7: - return "cr7"; - case UNW_PPC64_XER: - return "xer"; - case UNW_PPC64_VRSAVE: - return "vrsave"; - case UNW_PPC64_FPSCR: - return "fpscr"; - default: - return "unknown register"; + case UNW_PPC64_V0: + return "v0"; + case UNW_PPC64_V1: + return "v1"; + case UNW_PPC64_V2: + return "v2"; + case UNW_PPC64_V3: + return "v3"; + case UNW_PPC64_V4: + return "v4"; + case UNW_PPC64_V5: + return "v5"; + case UNW_PPC64_V6: + return "v6"; + case UNW_PPC64_V7: + return "v7"; + case UNW_PPC64_V8: + return "v8"; + case UNW_PPC64_V9: + return "v9"; + case UNW_PPC64_V10: + return "v10"; + case UNW_PPC64_V11: + return "v11"; + case UNW_PPC64_V12: + return "v12"; + case UNW_PPC64_V13: + return "v13"; + case UNW_PPC64_V14: + return "v14"; + case UNW_PPC64_V15: + return "v15"; + case UNW_PPC64_V16: + return "v16"; + case UNW_PPC64_V17: + return "v17"; + case UNW_PPC64_V18: + return "v18"; + case UNW_PPC64_V19: + return "v19"; + case UNW_PPC64_V20: + return "v20"; + case UNW_PPC64_V21: + return "v21"; + case UNW_PPC64_V22: + return "v22"; + case UNW_PPC64_V23: + return "v23"; + case UNW_PPC64_V24: + return "v24"; + case UNW_PPC64_V25: + return "v25"; + case UNW_PPC64_V26: + return "v26"; + case UNW_PPC64_V27: + return "v27"; + case UNW_PPC64_V28: + return "v28"; + case UNW_PPC64_V29: + return "v29"; + case UNW_PPC64_V30: + return "v30"; + case UNW_PPC64_V31: + return "v31"; } + return "unknown register"; } #endif // _LIBUNWIND_TARGET_PPC64 @@ -2462,13 +2526,15 @@ public: uint64_t getSP() const { return _registers.__r[1]; } void setSP(uint32_t value) { _registers.__r[1] = value; } - uint64_t getIP() const { return _registers.__r[9]; } - void setIP(uint32_t value) { _registers.__r[9] = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint32_t value) { _registers.__pc = value; } uint64_t getWCookie() const { return 0; } private: struct or1k_thread_state_t { - unsigned int __r[32]; + unsigned int __r[32]; // r0-r31 + unsigned int __pc; // Program counter + unsigned int __epcr; // Program counter at exception }; or1k_thread_state_t _registers; @@ -2494,6 +2560,8 @@ inline bool Registers_or1k::validRegister(int regNum) const { return false; if (regNum <= UNW_OR1K_R31) return true; + if (regNum == UNW_OR1K_EPCR) + return true; return false; } @@ -2503,9 +2571,11 @@ inline uint32_t Registers_or1k::getRegister(int regNum) const { switch (regNum) { case UNW_REG_IP: - return _registers.__r[9]; + return _registers.__pc; case UNW_REG_SP: return _registers.__r[1]; + case UNW_OR1K_EPCR: + return _registers.__epcr; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2518,11 +2588,14 @@ inline void Registers_or1k::setRegister(int regNum, uint32_t value) { switch (regNum) { case UNW_REG_IP: - _registers.__r[9] = value; + _registers.__pc = value; return; case UNW_REG_SP: _registers.__r[1] = value; return; + case UNW_OR1K_EPCR: + _registers.__epcr = value; + return; } _LIBUNWIND_ABORT("unsupported or1k register"); } @@ -2618,6 +2691,8 @@ inline const char *Registers_or1k::getRegisterName(int regNum) { return "r30"; case UNW_OR1K_R31: return "r31"; + case UNW_OR1K_EPCR: + return "EPCR"; default: return "unknown register"; } @@ -3088,13 +3163,13 @@ inline const char *Registers_mips_o32::getRegisterName(int regNum) { } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a +/// MIPS process using NEWABI (the N32 or N64 ABIs). +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); bool validRegister(int num) const; uint64_t getRegister(int num) const; @@ -3116,31 +3191,31 @@ public: uint32_t getWCookie() const { return 0; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; #ifdef __mips_hard_float double _floats[32]; #endif }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit<Registers_mips_n64, unw_context_t>::does_fit), - "mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit), + "mips_newabi registers do not fit into unw_context_t"); memcpy(&_registers, static_cast<const uint8_t *>(registers), sizeof(_registers)); } -inline Registers_mips_n64::Registers_mips_n64() { +inline Registers_mips_newabi::Registers_mips_newabi() { memset(&_registers, 0, sizeof(_registers)); } -inline bool Registers_mips_n64::validRegister(int regNum) const { +inline bool Registers_mips_newabi::validRegister(int regNum) const { if (regNum == UNW_REG_IP) return true; if (regNum == UNW_REG_SP) @@ -3157,7 +3232,7 @@ inline bool Registers_mips_n64::validRegister(int regNum) const { return false; } -inline uint64_t Registers_mips_n64::getRegister(int regNum) const { +inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) return _registers.__r[regNum - UNW_MIPS_R0]; @@ -3171,10 +3246,10 @@ inline uint64_t Registers_mips_n64::getRegister(int regNum) const { case UNW_MIPS_LO: return _registers.__lo; } - _LIBUNWIND_ABORT("unsupported mips_n64 register"); + _LIBUNWIND_ABORT("unsupported mips_newabi register"); } -inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) { +inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { _registers.__r[regNum - UNW_MIPS_R0] = value; return; @@ -3194,10 +3269,10 @@ inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) { _registers.__lo = value; return; } - _LIBUNWIND_ABORT("unsupported mips_n64 register"); + _LIBUNWIND_ABORT("unsupported mips_newabi register"); } -inline bool Registers_mips_n64::validFloatRegister(int regNum) const { +inline bool Registers_mips_newabi::validFloatRegister(int regNum) const { #ifdef __mips_hard_float if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) return true; @@ -3205,38 +3280,38 @@ inline bool Registers_mips_n64::validFloatRegister(int regNum) const { return false; } -inline double Registers_mips_n64::getFloatRegister(int regNum) const { +inline double Registers_mips_newabi::getFloatRegister(int regNum) const { #ifdef __mips_hard_float assert(validFloatRegister(regNum)); return _floats[regNum - UNW_MIPS_F0]; #else - _LIBUNWIND_ABORT("mips_n64 float support not implemented"); + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); #endif } -inline void Registers_mips_n64::setFloatRegister(int regNum, - double value) { +inline void Registers_mips_newabi::setFloatRegister(int regNum, + double value) { #ifdef __mips_hard_float assert(validFloatRegister(regNum)); _floats[regNum - UNW_MIPS_F0] = value; #else - _LIBUNWIND_ABORT("mips_n64 float support not implemented"); + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); #endif } -inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const { +inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const { return false; } -inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); +inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); } -inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); +inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); } -inline const char *Registers_mips_n64::getRegisterName(int regNum) { +inline const char *Registers_mips_newabi::getRegisterName(int regNum) { switch (regNum) { case UNW_MIPS_R0: return "$0"; @@ -3374,7 +3449,7 @@ inline const char *Registers_mips_n64::getRegisterName(int regNum) { return "unknown register"; } } -#endif // _LIBUNWIND_TARGET_MIPS_N64 +#endif // _LIBUNWIND_TARGET_MIPS_NEWABI } // namespace libunwind #endif // __REGISTERS_HPP__ diff --git a/lib/libunwind/src/UnwindCursor.hpp b/lib/libunwind/src/UnwindCursor.hpp index df12a16d5d7..3268bbbedcc 100644 --- a/lib/libunwind/src/UnwindCursor.hpp +++ b/lib/libunwind/src/UnwindCursor.hpp @@ -521,8 +521,8 @@ private: } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -583,8 +583,8 @@ private: } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -644,8 +644,8 @@ private: } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif @@ -1417,8 +1417,6 @@ int UnwindCursor<A, R>::step() { this->setInfoBasedOnIPRegister(true); if (_unwindInfoMissing) return UNW_STEP_END; - if (_info.gp) - setReg(UNW_REG_SP, getReg(UNW_REG_SP) + _info.gp); } return result; diff --git a/lib/libunwind/src/UnwindRegistersRestore.S b/lib/libunwind/src/UnwindRegistersRestore.S index f73b51acf46..92a3f8bb433 100644 --- a/lib/libunwind/src/UnwindRegistersRestore.S +++ b/lib/libunwind/src/UnwindRegistersRestore.S @@ -138,89 +138,259 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) // thread_state pointer is in r3 // +// load register (GPR) +#define PPC64_LR(n) \ + ld %r##n, (8 * (n + 2))(%r3) + // restore integral registers // skip r0 for now // skip r1 for now - ld %r2, 32(%r3) + PPC64_LR(2) // skip r3 for now // skip r4 for now // skip r5 for now - ld %r6, 64(%r3) - ld %r7, 72(%r3) - ld %r8, 80(%r3) - ld %r9, 88(%r3) - ld %r10, 96(%r3) - ld %r11, 104(%r3) - ld %r12, 112(%r3) - ld %r13, 120(%r3) - ld %r14, 128(%r3) - ld %r15, 136(%r3) - ld %r16, 144(%r3) - ld %r17, 152(%r3) - ld %r18, 160(%r3) - ld %r19, 168(%r3) - ld %r20, 176(%r3) - ld %r21, 184(%r3) - ld %r22, 192(%r3) - ld %r23, 200(%r3) - ld %r24, 208(%r3) - ld %r25, 216(%r3) - ld %r26, 224(%r3) - ld %r27, 232(%r3) - ld %r28, 240(%r3) - ld %r29, 248(%r3) - ld %r30, 256(%r3) - ld %r31, 264(%r3) - - //restore float registers - lfd %f0, 312(%r3) - lfd %f1, 320(%r3) - lfd %f2, 328(%r3) - lfd %f3, 336(%r3) - lfd %f4, 344(%r3) - lfd %f5, 352(%r3) - lfd %f6, 360(%r3) - lfd %f7, 368(%r3) - lfd %f8, 376(%r3) - lfd %f9, 384(%r3) - lfd %f10, 392(%r3) - lfd %f11, 400(%r3) - lfd %f12, 408(%r3) - lfd %f13, 416(%r3) - lfd %f14, 424(%r3) - lfd %f15, 432(%r3) - lfd %f16, 440(%r3) - lfd %f17, 448(%r3) - lfd %f18, 456(%r3) - lfd %f19, 464(%r3) - lfd %f20, 472(%r3) - lfd %f21, 480(%r3) - lfd %f22, 488(%r3) - lfd %f23, 496(%r3) - lfd %f24, 504(%r3) - lfd %f25, 512(%r3) - lfd %f26, 520(%r3) - lfd %f27, 528(%r3) - lfd %f28, 536(%r3) - lfd %f29, 544(%r3) - lfd %f30, 552(%r3) - lfd %f31, 560(%r3) - - //TODO: restore vector registers - - // Lnovec: - ld %r0, 272(%r3) // __cr + PPC64_LR(6) + PPC64_LR(7) + PPC64_LR(8) + PPC64_LR(9) + PPC64_LR(10) + PPC64_LR(11) + PPC64_LR(12) + PPC64_LR(13) + PPC64_LR(14) + PPC64_LR(15) + PPC64_LR(16) + PPC64_LR(17) + PPC64_LR(18) + PPC64_LR(19) + PPC64_LR(20) + PPC64_LR(21) + PPC64_LR(22) + PPC64_LR(23) + PPC64_LR(24) + PPC64_LR(25) + PPC64_LR(26) + PPC64_LR(27) + PPC64_LR(28) + PPC64_LR(29) + PPC64_LR(30) + PPC64_LR(31) + +#ifdef PPC64_HAS_VMX + + // restore VS registers + // (note that this also restores floating point registers and V registers, + // because part of VS is mapped to these registers) + + addi %r4, %r3, PPC64_OFFS_FP + +// load VS register +#define PPC64_LVS(n) \ + lxvd2x %vs##n, 0, %r4 ;\ + addi %r4, %r4, 16 + + // restore the first 32 VS regs (and also all floating point regs) + PPC64_LVS(0) + PPC64_LVS(1) + PPC64_LVS(2) + PPC64_LVS(3) + PPC64_LVS(4) + PPC64_LVS(5) + PPC64_LVS(6) + PPC64_LVS(7) + PPC64_LVS(8) + PPC64_LVS(9) + PPC64_LVS(10) + PPC64_LVS(11) + PPC64_LVS(12) + PPC64_LVS(13) + PPC64_LVS(14) + PPC64_LVS(15) + PPC64_LVS(16) + PPC64_LVS(17) + PPC64_LVS(18) + PPC64_LVS(19) + PPC64_LVS(20) + PPC64_LVS(21) + PPC64_LVS(22) + PPC64_LVS(23) + PPC64_LVS(24) + PPC64_LVS(25) + PPC64_LVS(26) + PPC64_LVS(27) + PPC64_LVS(28) + PPC64_LVS(29) + PPC64_LVS(30) + PPC64_LVS(31) + + // use VRSAVE to conditionally restore the remaining VS regs, + // that are where the V regs are mapped + + ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave + cmpwi %r5, 0 + beq Lnovec + +// conditionally load VS +#define PPC64_CLVS_BOTTOM(n) \ + beq Ldone##n ;\ + addi %r4, %r3, PPC64_OFFS_FP + n * 16 ;\ + lxvd2x %vs##n, 0, %r4 ;\ +Ldone##n: + +#define PPC64_CLVSl(n) \ + andis. %r0, %r5, (1<<(47-n)) ;\ +PPC64_CLVS_BOTTOM(n) + +#define PPC64_CLVSh(n) \ + andi. %r0, %r5, (1<<(63-n)) ;\ +PPC64_CLVS_BOTTOM(n) + + PPC64_CLVSl(32) + PPC64_CLVSl(33) + PPC64_CLVSl(34) + PPC64_CLVSl(35) + PPC64_CLVSl(36) + PPC64_CLVSl(37) + PPC64_CLVSl(38) + PPC64_CLVSl(39) + PPC64_CLVSl(40) + PPC64_CLVSl(41) + PPC64_CLVSl(42) + PPC64_CLVSl(43) + PPC64_CLVSl(44) + PPC64_CLVSl(45) + PPC64_CLVSl(46) + PPC64_CLVSl(47) + PPC64_CLVSh(48) + PPC64_CLVSh(49) + PPC64_CLVSh(50) + PPC64_CLVSh(51) + PPC64_CLVSh(52) + PPC64_CLVSh(53) + PPC64_CLVSh(54) + PPC64_CLVSh(55) + PPC64_CLVSh(56) + PPC64_CLVSh(57) + PPC64_CLVSh(58) + PPC64_CLVSh(59) + PPC64_CLVSh(60) + PPC64_CLVSh(61) + PPC64_CLVSh(62) + PPC64_CLVSh(63) + +#else + +// load FP register +#define PPC64_LF(n) \ + lfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3) + + // restore float registers + PPC64_LF(0) + PPC64_LF(1) + PPC64_LF(2) + PPC64_LF(3) + PPC64_LF(4) + PPC64_LF(5) + PPC64_LF(6) + PPC64_LF(7) + PPC64_LF(8) + PPC64_LF(9) + PPC64_LF(10) + PPC64_LF(11) + PPC64_LF(12) + PPC64_LF(13) + PPC64_LF(14) + PPC64_LF(15) + PPC64_LF(16) + PPC64_LF(17) + PPC64_LF(18) + PPC64_LF(19) + PPC64_LF(20) + PPC64_LF(21) + PPC64_LF(22) + PPC64_LF(23) + PPC64_LF(24) + PPC64_LF(25) + PPC64_LF(26) + PPC64_LF(27) + PPC64_LF(28) + PPC64_LF(29) + PPC64_LF(30) + PPC64_LF(31) + + // restore vector registers if any are in use + ld %r5, PPC64_OFFS_VRSAVE(%r3) // test VRsave + cmpwi %r5, 0 + beq Lnovec + + subi %r4, %r1, 16 + // r4 is now a 16-byte aligned pointer into the red zone + // the _vectorScalarRegisters may not be 16-byte aligned + // so copy via red zone temp buffer + +#define PPC64_CLV_UNALIGNED_BOTTOM(n) \ + beq Ldone##n ;\ + ld %r0, (PPC64_OFFS_V + n * 16)(%r3) ;\ + std %r0, 0(%r4) ;\ + ld %r0, (PPC64_OFFS_V + n * 16 + 8)(%r3) ;\ + std %r0, 8(%r4) ;\ + lvx %v##n, 0, %r4 ;\ +Ldone ## n: + +#define PPC64_CLV_UNALIGNEDl(n) \ + andis. %r0, %r5, (1<<(15-n)) ;\ +PPC64_CLV_UNALIGNED_BOTTOM(n) + +#define PPC64_CLV_UNALIGNEDh(n) \ + andi. %r0, %r5, (1<<(31-n)) ;\ +PPC64_CLV_UNALIGNED_BOTTOM(n) + + PPC64_CLV_UNALIGNEDl(0) + PPC64_CLV_UNALIGNEDl(1) + PPC64_CLV_UNALIGNEDl(2) + PPC64_CLV_UNALIGNEDl(3) + PPC64_CLV_UNALIGNEDl(4) + PPC64_CLV_UNALIGNEDl(5) + PPC64_CLV_UNALIGNEDl(6) + PPC64_CLV_UNALIGNEDl(7) + PPC64_CLV_UNALIGNEDl(8) + PPC64_CLV_UNALIGNEDl(9) + PPC64_CLV_UNALIGNEDl(10) + PPC64_CLV_UNALIGNEDl(11) + PPC64_CLV_UNALIGNEDl(12) + PPC64_CLV_UNALIGNEDl(13) + PPC64_CLV_UNALIGNEDl(14) + PPC64_CLV_UNALIGNEDl(15) + PPC64_CLV_UNALIGNEDh(16) + PPC64_CLV_UNALIGNEDh(17) + PPC64_CLV_UNALIGNEDh(18) + PPC64_CLV_UNALIGNEDh(19) + PPC64_CLV_UNALIGNEDh(20) + PPC64_CLV_UNALIGNEDh(21) + PPC64_CLV_UNALIGNEDh(22) + PPC64_CLV_UNALIGNEDh(23) + PPC64_CLV_UNALIGNEDh(24) + PPC64_CLV_UNALIGNEDh(25) + PPC64_CLV_UNALIGNEDh(26) + PPC64_CLV_UNALIGNEDh(27) + PPC64_CLV_UNALIGNEDh(28) + PPC64_CLV_UNALIGNEDh(29) + PPC64_CLV_UNALIGNEDh(30) + PPC64_CLV_UNALIGNEDh(31) + +#endif + +Lnovec: + ld %r0, PPC64_OFFS_CR(%r3) mtcr %r0 - ld %r0, 296(%r3) // __ctr - mtctr %r0 - ld %r0, 0(%r3) // __ssr0 + ld %r0, PPC64_OFFS_SRR0(%r3) mtctr %r0 - ld %r0, 16(%r3) - ld %r5, 56(%r3) - ld %r4, 48(%r3) - ld %r1, 24(%r3) - ld %r3, 40(%r3) + PPC64_LR(0) + PPC64_LR(5) + PPC64_LR(4) + PPC64_LR(1) + PPC64_LR(3) bctr #elif defined(__ppc__) @@ -588,7 +758,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # thread_state pointer is in r3 # - # restore integral registerrs + # restore integral registers l.lwz r0, 0(r3) l.lwz r1, 4(r3) l.lwz r2, 8(r3) @@ -598,7 +768,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) l.lwz r6, 24(r3) l.lwz r7, 28(r3) l.lwz r8, 32(r3) - l.lwz r9, 36(r3) + # skip r9 l.lwz r10, 40(r3) l.lwz r11, 44(r3) l.lwz r12, 48(r3) @@ -625,6 +795,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv) # at last, restore r3 l.lwz r3, 12(r3) + # load new pc into ra + l.lwz r9, 128(r3) # jump to pc l.jr r9 l.nop @@ -672,7 +844,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv) jmpl %o7 + 8, %g0 ldx [%o0 + 0x40], %o0 -#elif defined(__mips__) && defined(_ABIO32) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 // // void libunwind::Registers_mips_o32::jumpto() @@ -781,15 +953,15 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv) lw $4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) +#elif defined(__mips64) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder diff --git a/lib/libunwind/src/UnwindRegistersSave.S b/lib/libunwind/src/UnwindRegistersSave.S index bf951d642c1..0df3d5b17a2 100644 --- a/lib/libunwind/src/UnwindRegistersSave.S +++ b/lib/libunwind/src/UnwindRegistersSave.S @@ -116,7 +116,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) xorl %eax, %eax # return UNW_ESUCCESS ret -#elif defined(__mips__) && defined(_ABIO32) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 # # extern int unw_getcontext(unw_context_t* thread_state) @@ -225,7 +225,7 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) or $2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) +#elif defined(__mips64) # # extern int unw_getcontext(unw_context_t* thread_state) @@ -333,95 +333,223 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) // thread_state pointer is in r3 // DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) - std %r0, 16(%r3) + +// store register (GPR) +#define PPC64_STR(n) \ + std %r##n, (8 * (n + 2))(%r3) + + // save GPRs + PPC64_STR(0) mflr %r0 - std %r0, 0(%r3) // store lr as ssr0 - std %r1, 24(%r3) - std %r2, 32(%r3) - std %r3, 40(%r3) - std %r4, 48(%r3) - std %r5, 56(%r3) - std %r6, 64(%r3) - std %r7, 72(%r3) - std %r8, 80(%r3) - std %r9, 88(%r3) - std %r10, 96(%r3) - std %r11, 104(%r3) - std %r12, 112(%r3) - std %r13, 120(%r3) - std %r14, 128(%r3) - std %r15, 136(%r3) - std %r16, 144(%r3) - std %r17, 152(%r3) - std %r18, 160(%r3) - std %r19, 168(%r3) - std %r20, 176(%r3) - std %r21, 184(%r3) - std %r22, 192(%r3) - std %r23, 200(%r3) - std %r24, 208(%r3) - std %r25, 216(%r3) - std %r26, 224(%r3) - std %r27, 232(%r3) - std %r28, 240(%r3) - std %r29, 248(%r3) - std %r30, 256(%r3) - std %r31, 264(%r3) + std %r0, PPC64_OFFS_SRR0(%r3) // store lr as ssr0 + PPC64_STR(1) + PPC64_STR(2) + PPC64_STR(3) + PPC64_STR(4) + PPC64_STR(5) + PPC64_STR(6) + PPC64_STR(7) + PPC64_STR(8) + PPC64_STR(9) + PPC64_STR(10) + PPC64_STR(11) + PPC64_STR(12) + PPC64_STR(13) + PPC64_STR(14) + PPC64_STR(15) + PPC64_STR(16) + PPC64_STR(17) + PPC64_STR(18) + PPC64_STR(19) + PPC64_STR(20) + PPC64_STR(21) + PPC64_STR(22) + PPC64_STR(23) + PPC64_STR(24) + PPC64_STR(25) + PPC64_STR(26) + PPC64_STR(27) + PPC64_STR(28) + PPC64_STR(29) + PPC64_STR(30) + PPC64_STR(31) mfcr %r0 - std %r0, 272(%r3) - + std %r0, PPC64_OFFS_CR(%r3) mfxer %r0 - std %r0, 280(%r3) - + std %r0, PPC64_OFFS_XER(%r3) mflr %r0 - std %r0, 288(%r3) - + std %r0, PPC64_OFFS_LR(%r3) mfctr %r0 - std %r0, 296(%r3) - + std %r0, PPC64_OFFS_CTR(%r3) mfvrsave %r0 - std %r0, 304(%r3) + std %r0, PPC64_OFFS_VRSAVE(%r3) + +#ifdef PPC64_HAS_VMX + // save VS registers + // (note that this also saves floating point registers and V registers, + // because part of VS is mapped to these registers) + + addi %r4, %r3, PPC64_OFFS_FP + +// store VS register +#define PPC64_STVS(n) \ + stxvd2x %vs##n, 0, %r4 ;\ + addi %r4, %r4, 16 + + PPC64_STVS(0) + PPC64_STVS(1) + PPC64_STVS(2) + PPC64_STVS(3) + PPC64_STVS(4) + PPC64_STVS(5) + PPC64_STVS(6) + PPC64_STVS(7) + PPC64_STVS(8) + PPC64_STVS(9) + PPC64_STVS(10) + PPC64_STVS(11) + PPC64_STVS(12) + PPC64_STVS(13) + PPC64_STVS(14) + PPC64_STVS(15) + PPC64_STVS(16) + PPC64_STVS(17) + PPC64_STVS(18) + PPC64_STVS(19) + PPC64_STVS(20) + PPC64_STVS(21) + PPC64_STVS(22) + PPC64_STVS(23) + PPC64_STVS(24) + PPC64_STVS(25) + PPC64_STVS(26) + PPC64_STVS(27) + PPC64_STVS(28) + PPC64_STVS(29) + PPC64_STVS(30) + PPC64_STVS(31) + PPC64_STVS(32) + PPC64_STVS(33) + PPC64_STVS(34) + PPC64_STVS(35) + PPC64_STVS(36) + PPC64_STVS(37) + PPC64_STVS(38) + PPC64_STVS(39) + PPC64_STVS(40) + PPC64_STVS(41) + PPC64_STVS(42) + PPC64_STVS(43) + PPC64_STVS(44) + PPC64_STVS(45) + PPC64_STVS(46) + PPC64_STVS(47) + PPC64_STVS(48) + PPC64_STVS(49) + PPC64_STVS(50) + PPC64_STVS(51) + PPC64_STVS(52) + PPC64_STVS(53) + PPC64_STVS(54) + PPC64_STVS(55) + PPC64_STVS(56) + PPC64_STVS(57) + PPC64_STVS(58) + PPC64_STVS(59) + PPC64_STVS(60) + PPC64_STVS(61) + PPC64_STVS(62) + PPC64_STVS(63) + +#else + +// store FP register +#define PPC64_STF(n) \ + stfd %f##n, (PPC64_OFFS_FP + n * 16)(%r3) // save float registers - stfd %f0, 312(%r3) - stfd %f1, 320(%r3) - stfd %f2, 328(%r3) - stfd %f3, 336(%r3) - stfd %f4, 344(%r3) - stfd %f5, 352(%r3) - stfd %f6, 360(%r3) - stfd %f7, 368(%r3) - stfd %f8, 376(%r3) - stfd %f9, 384(%r3) - stfd %f10, 392(%r3) - stfd %f11, 400(%r3) - stfd %f12, 408(%r3) - stfd %f13, 416(%r3) - stfd %f14, 424(%r3) - stfd %f15, 432(%r3) - stfd %f16, 440(%r3) - stfd %f17, 448(%r3) - stfd %f18, 456(%r3) - stfd %f19, 464(%r3) - stfd %f20, 472(%r3) - stfd %f21, 480(%r3) - stfd %f22, 488(%r3) - stfd %f23, 496(%r3) - stfd %f24, 504(%r3) - stfd %f25, 512(%r3) - stfd %f26, 520(%r3) - stfd %f27, 528(%r3) - stfd %f28, 536(%r3) - stfd %f29, 544(%r3) - stfd %f30, 552(%r3) - stfd %f31, 560(%r3) - - mffs %f0 - stfd %f0, 568(%r3) - - //TODO: save vector registers + PPC64_STF(0) + PPC64_STF(1) + PPC64_STF(2) + PPC64_STF(3) + PPC64_STF(4) + PPC64_STF(5) + PPC64_STF(6) + PPC64_STF(7) + PPC64_STF(8) + PPC64_STF(9) + PPC64_STF(10) + PPC64_STF(11) + PPC64_STF(12) + PPC64_STF(13) + PPC64_STF(14) + PPC64_STF(15) + PPC64_STF(16) + PPC64_STF(17) + PPC64_STF(18) + PPC64_STF(19) + PPC64_STF(20) + PPC64_STF(21) + PPC64_STF(22) + PPC64_STF(23) + PPC64_STF(24) + PPC64_STF(25) + PPC64_STF(26) + PPC64_STF(27) + PPC64_STF(28) + PPC64_STF(29) + PPC64_STF(30) + PPC64_STF(31) + + // save vector registers + + // Use 16-bytes below the stack pointer as an + // aligned buffer to save each vector register. + // Note that the stack pointer is always 16-byte aligned. + subi %r4, %r1, 16 + +#define PPC64_STV_UNALIGNED(n) \ + stvx %v##n, 0, %r4 ;\ + ld %r5, 0(%r4) ;\ + std %r5, (PPC64_OFFS_V + n * 16)(%r3) ;\ + ld %r5, 8(%r4) ;\ + std %r5, (PPC64_OFFS_V + n * 16 + 8)(%r3) + + PPC64_STV_UNALIGNED(0) + PPC64_STV_UNALIGNED(1) + PPC64_STV_UNALIGNED(2) + PPC64_STV_UNALIGNED(3) + PPC64_STV_UNALIGNED(4) + PPC64_STV_UNALIGNED(5) + PPC64_STV_UNALIGNED(6) + PPC64_STV_UNALIGNED(7) + PPC64_STV_UNALIGNED(8) + PPC64_STV_UNALIGNED(9) + PPC64_STV_UNALIGNED(10) + PPC64_STV_UNALIGNED(11) + PPC64_STV_UNALIGNED(12) + PPC64_STV_UNALIGNED(13) + PPC64_STV_UNALIGNED(14) + PPC64_STV_UNALIGNED(15) + PPC64_STV_UNALIGNED(16) + PPC64_STV_UNALIGNED(17) + PPC64_STV_UNALIGNED(18) + PPC64_STV_UNALIGNED(19) + PPC64_STV_UNALIGNED(20) + PPC64_STV_UNALIGNED(21) + PPC64_STV_UNALIGNED(22) + PPC64_STV_UNALIGNED(23) + PPC64_STV_UNALIGNED(24) + PPC64_STV_UNALIGNED(25) + PPC64_STV_UNALIGNED(26) + PPC64_STV_UNALIGNED(27) + PPC64_STV_UNALIGNED(28) + PPC64_STV_UNALIGNED(29) + PPC64_STV_UNALIGNED(30) + PPC64_STV_UNALIGNED(31) +#endif li %r3, 0 // return UNW_ESUCCESS blr @@ -810,6 +938,10 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext) l.sw 116(r3), r29 l.sw 120(r3), r30 l.sw 124(r3), r31 + # store ra to pc + l.sw 128(r3), r9 + # zero epcr + l.sw 132(r3), r0 #elif defined(__sparc__) && defined(__arch64__) diff --git a/lib/libunwind/src/libunwind.cpp b/lib/libunwind/src/libunwind.cpp index 632535ac470..20067994e7a 100644 --- a/lib/libunwind/src/libunwind.cpp +++ b/lib/libunwind/src/libunwind.cpp @@ -61,10 +61,10 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor, # define REGISTER_KIND Registers_arm #elif defined(__or1k__) # define REGISTER_KIND Registers_or1k -#elif defined(__mips__) && defined(_ABIO32) +#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips64) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #elif defined(__sparc__) && defined(__arch64__) @@ -190,8 +190,20 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, co->setReg(regNum, (pint_t)value); // specical case altering IP to re-find info (being called by personality // function) - if (regNum == UNW_REG_IP) + if (regNum == UNW_REG_IP) { + unw_proc_info_t info; + // First, get the FDE for the old location and then update it. + co->getInfo(&info); co->setInfoBasedOnIPRegister(false); + // If the original call expects stack adjustment, perform this now. + // Normal frame unwinding would have included the offset already in the + // CFA computation. + // Note: for PA-RISC and other platforms where the stack grows up, + // this should actually be - info.gp. LLVM doesn't currently support + // any such platforms and Clang doesn't export a macro for them. + if (info.gp) + co->setReg(UNW_REG_SP, co->getReg(UNW_REG_SP) + info.gp); + } return UNW_ESUCCESS; } return UNW_EBADREG; |