summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2019-02-04 17:04:38 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2019-02-04 17:04:38 +0000
commit6a74f946b99e0ce22e541b8abfaace449427f306 (patch)
tree260de92ee877be516f4f4182ae6ed25b90678bfb /lib
parent56b1e941d7292e371f158d5216935f49c4dcd9b2 (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')
-rw-r--r--lib/libcxx/Makefile11
-rw-r--r--lib/libcxx/include/__config957
-rw-r--r--lib/libcxx/include/__locale174
-rw-r--r--lib/libcxx/include/stdio.h7
-rw-r--r--lib/libcxx/include/support/newlib/xlocale.h2
-rw-r--r--lib/libcxx/shlib_version2
-rw-r--r--lib/libcxx/src/experimental/filesystem/directory_iterator.cpp256
-rw-r--r--lib/libcxx/src/experimental/filesystem/filesystem_time_helper.h173
-rw-r--r--lib/libcxx/src/experimental/filesystem/operations.cpp794
-rw-r--r--lib/libcxx/src/experimental/filesystem/path.cpp391
-rw-r--r--lib/libcxx/utils/google-benchmark/include/benchmark/benchmark_api.h915
-rw-r--r--lib/libcxx/utils/google-benchmark/include/benchmark/macros.h66
-rw-r--r--lib/libcxx/utils/google-benchmark/include/benchmark/reporter.h230
-rw-r--r--lib/libcxx/utils/google-benchmark/mingw.py320
-rw-r--r--lib/libcxx/utils/google-benchmark/src/stat.h306
-rw-r--r--lib/libcxx/utils/google-benchmark/src/sysinfo.h10
-rw-r--r--lib/libcxx/utils/libcxx/test/config.py33
-rw-r--r--lib/libunwind/include/__libunwind_config.h29
-rw-r--r--lib/libunwind/include/libunwind.h291
-rw-r--r--lib/libunwind/include/mach-o/compact_unwind_encoding.h32
-rw-r--r--lib/libunwind/src/AddressSpace.hpp29
-rw-r--r--lib/libunwind/src/DwarfInstructions.hpp4
-rw-r--r--lib/libunwind/src/Registers.hpp329
-rw-r--r--lib/libunwind/src/UnwindCursor.hpp14
-rw-r--r--lib/libunwind/src/UnwindRegistersRestore.S332
-rw-r--r--lib/libunwind/src/UnwindRegistersSave.S294
-rw-r--r--lib/libunwind/src/libunwind.cpp20
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;