diff --git a/include/__config b/include/__config index 6f983223a..315cec9df 100644 --- a/include/__config +++ b/include/__config @@ -305,11 +305,11 @@ template struct __static_assert_check {}; #define __has_feature(__x) 0 #endif -#if __APPLE__ || __FreeBSD__ +#if __APPLE__ || __FreeBSD__ || _WIN32 #define _LIBCPP_LOCALE__L_EXTENSIONS 1 #endif -#ifdef __APPLE__ +#if __APPLE__ || _WIN32 #define _LIBCPP_STABLE_APPLE_ABI #endif diff --git a/include/cwchar b/include/cwchar index ce71782c8..0a67fe8bb 100644 --- a/include/cwchar +++ b/include/cwchar @@ -106,6 +106,9 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, #include <__config> #include #include +#if _WIN32 +#include // pull in *swprintf defines +#endif // _WIN32 #pragma GCC system_header diff --git a/include/locale b/include/locale index 81c489187..c0724a503 100644 --- a/include/locale +++ b/include/locale @@ -187,7 +187,8 @@ template class messages_byname; #include #include #if _WIN32 -#include // vasprintf +#include +#include #else // _WIN32 #include #endif // !_WIN32 diff --git a/include/support/win32/locale.h b/include/support/win32/locale.h index 6be80acec..dd56a0490 100644 --- a/include/support/win32/locale.h +++ b/include/support/win32/locale.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- support/win32/locale.h --------------------------===// +//===------------------------ support/win32/locale.h ----------------------===// // // The LLVM Compiler Infrastructure // @@ -8,10 +8,56 @@ // //===----------------------------------------------------------------------===// -// Locale stuff -// FIXME: the *_l functions are fairly new, only available on Vista?/7+ -#include // +#ifndef _LIBCPP_SUPPORT_WIN32_LOCALE_H +#define _LIBCPP_SUPPORT_WIN32_LOCALE_H + +#include "support/win32/support.h" +#include +#include // _locale_t #define locale_t _locale_t +#define LC_COLLATE_MASK _M_COLLATE +#define LC_CTYPE_MASK _M_CTYPE +#define LC_MONETARY_MASK _M_MONETARY +#define LC_NUMERIC_MASK _M_NUMERIC +#define LC_TIME_MASK _M_TIME +#define LC_MESSAGES_MASK _M_MESSAGES +#define LC_ALL_MASK ( LC_COLLATE_MASK \ + | LC_CTYPE_MASK \ + | LC_MESSAGES_MASK \ + | LC_MONETARY_MASK \ + | LC_NUMERIC_MASK \ + | LC_TIME_MASK ) +#define freelocale _free_locale +// FIXME: base currently unused. Needs manual work to construct the new locale +locale_t newlocale( int mask, const char * locale, locale_t base ); +locale_t uselocale( locale_t newloc ); +lconv *localeconv_l( locale_t loc ); +size_t mbrlen_l( const char *__restrict__ s, size_t n, + mbstate_t *__restrict__ ps, locale_t loc); +size_t mbsrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src, + size_t len, mbstate_t *__restrict__ ps, locale_t loc ); +size_t wcrtomb_l( char *__restrict__ s, wchar_t wc, mbstate_t *__restrict__ ps, + locale_t loc); +size_t mbrtowc_l( wchar_t *__restrict__ pwc, const char *__restrict__ s, + size_t n, mbstate_t *__restrict__ ps, locale_t loc); +size_t mbsnrtowcs_l( wchar_t *__restrict__ dst, const char **__restrict__ src, + size_t nms, size_t len, mbstate_t *__restrict__ ps, locale_t loc); +size_t wcsnrtombs_l( char *__restrict__ dst, const wchar_t **__restrict__ src, + size_t nwc, size_t len, mbstate_t *__restrict__ ps, locale_t loc); +wint_t btowc_l( int c, locale_t loc ); +int wctob_l( wint_t c, locale_t loc ); +typedef _VSTD::remove_pointer::type __locale_struct; +typedef _VSTD::unique_ptr<__locale_struct, decltype(&uselocale)> __locale_raii; +_LIBCPP_ALWAYS_INLINE inline +decltype(MB_CUR_MAX) MB_CUR_MAX_L( locale_t __l ) +{ + __locale_raii __current( uselocale(__l), uselocale ); + return MB_CUR_MAX; +} + +// the *_l functions are prefixed on Windows, only available for msvcr80+, VS2005+ +#include +#define mbtowc_l _mbtowc_l #define strtoll_l _strtoi64_l #define strtoull_l _strtoui64_l // FIXME: current msvcrt does not know about long double @@ -36,6 +82,17 @@ #define towupper_l _towupper_l #define towlower_l _towlower_l #define strftime_l _strftime_l +#define sscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) +#define vsscanf_l( __s, __l, __f, ...) _sscanf_l( __s, __f, __l, __VA_ARGS__ ) +#define sprintf_l( __s, __l, __f, ... ) _sprintf_l( __s, __f, __l, __VA_ARGS__ ) +#define snprintf_l( __s, __n, __l, __f, ... ) _snprintf_l( __s, __n, __f, __l, __VA_ARGS__ ) +#define vsprintf_l( __s, __l, __f, ... ) _vsprintf_l( __s, __f, __l, __VA_ARGS__ ) +#define vsnprintf_l( __s, __n, __l, __f, ... ) _vsnprintf_l( __s, __n, __f, __l, __VA_ARGS__ ) +int asprintf_l( char **ret, locale_t loc, const char *format, ... ); +int vasprintf_l( char **ret, locale_t loc, const char *format, va_list ap ); + + +// not-so-pressing FIXME: use locale to determine blank characters inline int isblank_l( int c, locale_t /*loc*/ ) { return ( c == ' ' || c == '\t' ); @@ -44,29 +101,5 @@ inline int iswblank_l( wint_t c, locale_t /*loc*/ ) { return ( c == L' ' || c == L'\t' ); } -#define freelocale _free_locale -// ignore base; it is always 0 in libc++ code -inline locale_t newlocale( int mask, const char * locale, locale_t /*base*/ ) -{ - return _create_locale( mask, locale ); -} -// FIXME: first call _configthreadlocale(_ENABLE_PER_THREAD_LOCALE) somewhere -// FIXME: return types are different, need to make locale_t from char* -inline locale_t uselocale(locale_t newloc) -{ - return _create_locale( LC_ALL, setlocale(LC_ALL, newloc->locinfo->lc_category[LC_ALL].locale) ); -} - -#define LC_COLLATE_MASK _M_COLLATE -#define LC_CTYPE_MASK _M_CTYPE -#define LC_MONETARY_MASK _M_MONETARY -#define LC_NUMERIC_MASK _M_NUMERIC -#define LC_TIME_MASK _M_TIME -#define LC_MESSAGES_MASK _M_MESSAGES -#define LC_ALL_MASK ( LC_COLLATE_MASK \ - | LC_CTYPE_MASK \ - | LC_MESSAGES_MASK \ - | LC_MONETARY_MASK \ - | LC_NUMERIC_MASK \ - | LC_TIME_MASK ) +#endif // _LIBCPP_SUPPORT_WIN32_LOCALE_H \ No newline at end of file diff --git a/include/support/win32/support.h b/include/support/win32/support.h index 48225690d..8ce947a16 100644 --- a/include/support/win32/support.h +++ b/include/support/win32/support.h @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- support/win32/support.h --------------------------===// +//===----------------------- support/win32/support.h ----------------------===// // // The LLVM Compiler Infrastructure // @@ -8,16 +8,24 @@ // //===----------------------------------------------------------------------===// +#ifndef _LIBCPP_SUPPORT_WIN32_SUPPORT_H +#define _LIBCPP_SUPPORT_WIN32_SUPPORT_H + /* Functions and constants used in libc++ that are missing from the Windows C library. */ -#if __MINGW32__ -#include -#define swprintf snwprintf -#endif // __MINGW32__ +#include // mbstate_t +#include // _snwprintf +#define swprintf _snwprintf +#define vswprintf _vsnwprintf + int vasprintf( char **sptr, const char *__restrict__ fmt , va_list ap ); +int asprintf(char **sptr, const char *__restrict__ fmt, ...); + size_t mbsnrtowcs( wchar_t *__restrict__ dst, const char **__restrict__ src, size_t nmc, size_t len, mbstate_t *__restrict__ ps ); size_t wcsnrtombs( char *__restrict__ dst, const wchar_t **__restrict__ src, size_t nwc, size_t len, mbstate_t *__restrict__ ps ); + +#endif // _LIBCPP_SUPPORT_WIN32_SUPPORT_H \ No newline at end of file diff --git a/lib/buildit b/lib/buildit index 16df7c51d..13d6f8e07 100755 --- a/lib/buildit +++ b/lib/buildit @@ -78,6 +78,13 @@ case $TRIPLE in -Wl,-force_symbols_not_weak_list,notweak.exp " fi ;; + *-*-mingw*) + # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt + SOEXT=dll + LDSHARED_FLAGS="-o libc++.dll \ + -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++.dll.a \ + -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt" + ;; *) RC_CFLAGS="-fPIC" SOEXT=so @@ -97,8 +104,13 @@ set -x for FILE in ../src/*.cpp; do $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -nostdinc++ -I../include $FILE done - - +case $TRIPLE in + *-*-mingw*) + for FILE in ../src/support/win32/*.cpp; do + $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -nostdinc++ -I../include $FILE + done + ;; +esac $CC *.o $RC_CFLAGS $LDSHARED_FLAGS $EXTRA_FLAGS #libtool -static -o libc++.a *.o diff --git a/src/support/win32/support.cpp b/src/support/win32/support.cpp index db80063c6..8ed2921d2 100644 --- a/src/support/win32/support.cpp +++ b/src/support/win32/support.cpp @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- support/win32/support.h --------------------------===// +//===----------------------- support/win32/support.h ----------------------===// // // The LLVM Compiler Infrastructure // @@ -8,12 +8,21 @@ // //===----------------------------------------------------------------------===// +#include +#include // va_start, va_end #include // size_t #include // malloc #include // vsprintf, vsnprintf #include // strcpy, wcsncpy -#include // mbstate_t +int asprintf(char **sptr, const char *__restrict__ fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int result = vasprintf(sptr, fmt, ap); + va_end(ap); + return result; +} int vasprintf( char **sptr, const char *__restrict__ fmt, va_list ap ) { *sptr = NULL;