summaryrefslogtreecommitdiffstats
path: root/libcxx
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/CMakeLists.txt8
-rw-r--r--libcxx/include/__config7
-rw-r--r--libcxx/include/__config_site.in3
-rw-r--r--libcxx/include/__locale12
-rw-r--r--libcxx/include/support/musl/xlocale.h58
-rw-r--r--libcxx/src/locale.cpp30
6 files changed, 100 insertions, 18 deletions
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index 6cc36e0161b..8b60fb15e99 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -121,6 +121,7 @@ option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for th
option(LIBCXX_ENABLE_MONOTONIC_CLOCK
"Build libc++ with support for a monotonic clock.
This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
+option(LIBCXX_HAS_MUSL_LIBC "Build libc++ with support for the Musl C library" OFF)
# Misc options ----------------------------------------------------------------
# FIXME: Turn -pedantic back ON. It is currently off because it warns
@@ -200,6 +201,11 @@ if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
LIBCXX_ENABLE_ABI_LINKER_SCRIPT")
endif()
+if (LIBCXX_HAS_MUSL_LIBC AND NOT LIBCXX_INSTALL_SUPPORT_HEADERS)
+ message(FATAL_ERROR "LIBCXX_INSTALL_SUPPORT_HEADERS can not be turned off"
+ "when building for Musl with LIBCXX_HAS_MUSL_LIBC.")
+endif()
+
#===============================================================================
# Configure System
#===============================================================================
@@ -364,6 +370,8 @@ config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS)
config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK)
config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS)
+config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
+
if (LIBCXX_NEEDS_SITE_CONFIG)
configure_file(
include/__config_site.in
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 7f6fbf07b58..795e0845cec 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -386,14 +386,19 @@ typedef __char32_t char32_t;
#elif defined(__ANDROID__)
#define _LIBCPP_HAS_QUICK_EXIT
#elif defined(__linux__)
-#include <features.h>
+#if !defined(_LIBCPP_HAS_MUSL_LIBC)
+# include <features.h>
#if __GLIBC_PREREQ(2, 15)
#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))
diff --git a/libcxx/include/__config_site.in b/libcxx/include/__config_site.in
index 7a1d739f721..ec64485289f 100644
--- a/libcxx/include/__config_site.in
+++ b/libcxx/include/__config_site.in
@@ -18,5 +18,6 @@
#cmakedefine _LIBCPP_HAS_NO_THREADS
#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
+#cmakedefine _LIBCPP_HAS_MUSL_LIBC
-#endif
+#endif // _LIBCPP_CONFIG_SITE
diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index 19895582cac..e525053ca3f 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -37,6 +37,8 @@
#elif (defined(__GLIBC__) || defined(__APPLE__) || defined(__FreeBSD__) \
|| defined(__EMSCRIPTEN__) || defined(__IBMCPP__))
# include <xlocale.h>
+#elif defined(_LIBCPP_HAS_MUSL_LIBC)
+# include <support/musl/xlocale.h>
#endif // __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun__ || __EMSCRIPTEN__ || __IBMCPP__
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -329,7 +331,7 @@ locale::operator()(const basic_string<_CharT, _Traits, _Allocator>& __x,
class _LIBCPP_TYPE_VIS ctype_base
{
public:
-#ifdef __GLIBC__
+#if defined(__GLIBC__)
typedef unsigned short mask;
static const mask space = _ISspace;
static const mask print = _ISprint;
@@ -359,7 +361,7 @@ public:
typedef __uint32_t mask;
# elif defined(__FreeBSD__)
typedef unsigned long mask;
-# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+# elif defined(__EMSCRIPTEN__) || defined(__NetBSD__) || defined(_LIBCPP_HAS_MUSL_LIBC)
typedef unsigned short mask;
# endif
static const mask space = _CTYPE_S;
@@ -406,7 +408,11 @@ public:
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_ALPHA
# define _LIBCPP_CTYPE_MASK_IS_COMPOSITE_XDIGIT
#else
+#if defined(_LIBCPP_HAS_MUSL_LIBC)
+ typedef unsigned short mask;
+#else
typedef unsigned long mask;
+#endif
static const mask space = 1<<0;
static const mask print = 1<<1;
static const mask cntrl = 1<<2;
@@ -628,7 +634,7 @@ public:
#endif
_LIBCPP_ALWAYS_INLINE const mask* table() const _NOEXCEPT {return __tab_;}
static const mask* classic_table() _NOEXCEPT;
-#if defined(__GLIBC__) || defined(__EMSCRIPTEN__)
+#if defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
static const int* __classic_upper_table() _NOEXCEPT;
static const int* __classic_lower_table() _NOEXCEPT;
#endif
diff --git a/libcxx/include/support/musl/xlocale.h b/libcxx/include/support/musl/xlocale.h
new file mode 100644
index 00000000000..3e31c99596c
--- /dev/null
+++ b/libcxx/include/support/musl/xlocale.h
@@ -0,0 +1,58 @@
+// -*- C++ -*-
+//===------------------- support/musl/xlocale.h ------------------------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+// This adds support for the extended locale functions that are currently
+// missing from the Musl C library.
+//
+// This only works when the specified locale is "C" or "POSIX", but that's
+// about as good as we can do without implementing full xlocale support
+// in Musl.
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_MUSL_XLOCALE_H
+#define _LIBCPP_SUPPORT_MUSL_XLOCALE_H
+
+#include <cstdlib>
+#include <cwchar>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline long long strtoll_l(const char *nptr, char **endptr, int base,
+ locale_t) {
+ return strtoll(nptr, endptr, base);
+}
+
+static inline unsigned long long strtoull_l(const char *nptr, char **endptr,
+ int base, locale_t) {
+ return strtoull(nptr, endptr, base);
+}
+
+static inline long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr,
+ int base, locale_t) {
+ return wcstoll(nptr, endptr, base);
+}
+
+static inline unsigned long long wcstoull_l(const wchar_t *nptr,
+ wchar_t **endptr, int base,
+ locale_t) {
+ return wcstoull(nptr, endptr, base);
+}
+
+static inline long double wcstold_l(const wchar_t *nptr, wchar_t **endptr,
+ locale_t) {
+ return wcstold(nptr, endptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBCPP_SUPPORT_MUSL_XLOCALE_H
diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp
index bdc73e1d537..11c266cde2a 100644
--- a/libcxx/src/locale.cpp
+++ b/libcxx/src/locale.cpp
@@ -812,7 +812,8 @@ ctype<wchar_t>::do_toupper(char_type c) const
{
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+ defined(__NetBSD__) || defined(_LIBCPP_HAS_MUSL_LIBC)
return isascii(c) ? ctype<char>::__classic_upper_table()[c] : c;
#else
return (isascii(c) && iswlower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'a'+L'A' : c;
@@ -825,7 +826,8 @@ ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const
for (; low != high; ++low)
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+ defined(__NetBSD__) || defined(_LIBCPP_HAS_MUSL_LIBC)
*low = isascii(*low) ? ctype<char>::__classic_upper_table()[*low]
: *low;
#else
@@ -839,7 +841,8 @@ ctype<wchar_t>::do_tolower(char_type c) const
{
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+ defined(__NetBSD__) || defined(_LIBCPP_HAS_MUSL_LIBC)
return isascii(c) ? ctype<char>::__classic_lower_table()[c] : c;
#else
return (isascii(c) && isupper_l(c, _LIBCPP_GET_C_LOCALE)) ? c-L'A'+'a' : c;
@@ -852,7 +855,8 @@ ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const
for (; low != high; ++low)
#ifdef _LIBCPP_HAS_DEFAULTRUNELOCALE
*low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low;
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || \
+ defined(__NetBSD__) || defined(_LIBCPP_HAS_MUSL_LIBC)
*low = isascii(*low) ? ctype<char>::__classic_lower_table()[*low]
: *low;
#else
@@ -921,8 +925,8 @@ ctype<char>::do_toupper(char_type c) const
static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(c)]) : c;
#elif defined(__NetBSD__)
return static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]);
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
- return isascii(c) ?
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
+ return isascii(c) ?
static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(c)]) : c;
#else
return (isascii(c) && islower_l(c, _LIBCPP_GET_C_LOCALE)) ? c-'a'+'A' : c;
@@ -938,7 +942,7 @@ ctype<char>::do_toupper(char_type* low, const char_type* high) const
static_cast<char>(_DefaultRuneLocale.__mapupper[static_cast<ptrdiff_t>(*low)]) : *low;
#elif defined(__NetBSD__)
*low = static_cast<char>(__classic_upper_table()[static_cast<unsigned char>(*low)]);
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
*low = isascii(*low) ?
static_cast<char>(__classic_upper_table()[static_cast<size_t>(*low)]) : *low;
#else
@@ -955,7 +959,7 @@ ctype<char>::do_tolower(char_type c) const
static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(c)]) : c;
#elif defined(__NetBSD__)
return static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(c)]);
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
return isascii(c) ?
static_cast<char>(__classic_lower_table()[static_cast<size_t>(c)]) : c;
#else
@@ -971,7 +975,7 @@ ctype<char>::do_tolower(char_type* low, const char_type* high) const
*low = isascii(*low) ? static_cast<char>(_DefaultRuneLocale.__maplower[static_cast<ptrdiff_t>(*low)]) : *low;
#elif defined(__NetBSD__)
*low = static_cast<char>(__classic_lower_table()[static_cast<unsigned char>(*low)]);
-#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__)
+#elif defined(__GLIBC__) || defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
*low = isascii(*low) ? static_cast<char>(__classic_lower_table()[static_cast<size_t>(*low)]) : *low;
#else
*low = (isascii(*low) && isupper_l(*low, _LIBCPP_GET_C_LOCALE)) ? *low-'A'+'a' : *low;
@@ -1012,7 +1016,7 @@ ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault,
return low;
}
-#ifdef __EMSCRIPTEN__
+#if defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
extern "C" const unsigned short ** __ctype_b_loc();
extern "C" const int ** __ctype_tolower_loc();
extern "C" const int ** __ctype_toupper_loc();
@@ -1114,7 +1118,7 @@ ctype<char>::classic_table() _NOEXCEPT
return _ctype+1; // internal ctype mask table defined in msvcrt.dll
// This is assumed to be safe, which is a nonsense assumption because we're
// going to end up dereferencing it later...
-#elif defined(__EMSCRIPTEN__)
+#elif defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
return *__ctype_b_loc();
#elif defined(_NEWLIB_VERSION)
// Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
@@ -1157,7 +1161,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT
return _C_toupper_tab_ + 1;
}
-#elif defined(__EMSCRIPTEN__)
+#elif defined(__EMSCRIPTEN__) || defined(_LIBCPP_HAS_MUSL_LIBC)
const int*
ctype<char>::__classic_lower_table() _NOEXCEPT
{
@@ -1169,7 +1173,7 @@ ctype<char>::__classic_upper_table() _NOEXCEPT
{
return *__ctype_toupper_loc();
}
-#endif // __GLIBC__ || __EMSCRIPTEN__ || __NETBSD__
+#endif // __GLIBC__ || __NETBSD__ || __EMSCRIPTEN__ || defined(_LIBCPP_HAS_MUSL_LIBC)
// template <> class ctype_byname<char>
OpenPOWER on IntegriCloud