diff options
-rw-r--r-- | libcxx/CMakeLists.txt | 159 | ||||
-rw-r--r-- | libcxx/cmake/Modules/GetTriple.cmake | 53 | ||||
-rw-r--r-- | libcxx/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake | 18 | ||||
-rw-r--r-- | libcxx/cmake/config-ix.cmake | 37 | ||||
-rw-r--r-- | libcxx/include/__config | 1 | ||||
-rw-r--r-- | libcxx/include/__split_buffer | 6 | ||||
-rw-r--r-- | libcxx/include/locale | 20 | ||||
-rw-r--r-- | libcxx/include/memory | 6 | ||||
-rw-r--r-- | libcxx/include/utility | 8 | ||||
-rw-r--r-- | libcxx/lib/CMakeLists.txt | 56 | ||||
-rwxr-xr-x | libcxx/lib/buildit | 4 | ||||
-rw-r--r-- | libcxx/src/locale.cpp | 121 | ||||
-rw-r--r-- | libcxx/test/CMakeLists.txt | 44 | ||||
-rw-r--r-- | libcxx/test/lit.cfg | 43 | ||||
-rw-r--r-- | libcxx/test/lit.site.cfg.in | 10 |
15 files changed, 562 insertions, 24 deletions
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt new file mode 100644 index 00000000000..a7429f67553 --- /dev/null +++ b/libcxx/CMakeLists.txt @@ -0,0 +1,159 @@ +# See www/CMake.html for instructions on how to build libcxx with CMake. + +#=============================================================================== +# Setup Project +#=============================================================================== + +project(libcxx CXX C) +cmake_minimum_required(VERSION 2.8) + +set(PACKAGE_NAME libcxx) +set(PACKAGE_VERSION trunk-svn) +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu") + +# Add path for custom modules +set(CMAKE_MODULE_PATH + ${CMAKE_MODULE_PATH} + "${CMAKE_CURRENT_SOURCE_DIR}/cmake" + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" + ) + +# Require out of source build. +include(MacroEnsureOutOfSourceBuild) +MACRO_ENSURE_OUT_OF_SOURCE_BUILD( + "${PROJECT_NAME} requires an out of source build. Please create a separate + build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." + ) + +#=============================================================================== +# Setup CMake Options +#=============================================================================== + +# Define options. +option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON) +option(LIBCXX_ENABLE_RTTI "Use run time type information." ON) +option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON) +option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) +option(LIBCXX_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF) +option(LIBCXX_ENABLE_CXX0X "Enable -std=c++0x and use of c++0x language features if the compiler supports it." ON) +option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) + +#=============================================================================== +# Configure System +#=============================================================================== + +# Get triples. +include(GetTriple) +get_host_triple(LIBCXX_HOST_TRIPLE + LIBCXX_HOST_ARCH + LIBCXX_HOST_VENDOR + LIBCXX_HOST_OS + ) +set(LIBCXX_HOST_TRIPLE ${LIBCXX_HOST_TRIPLE} CACHE STRING "Host triple.") +get_target_triple(LIBCXX_TARGET_TRIPLE + LIBCXX_TARGET_ARCH + LIBCXX_TARGET_VENDOR + LIBCXX_TARGET_OS + ) +set(LIBCXX_TARGET_TRIPLE ${LIBCXX_TARGET_TRIPLE} CACHE STRING "Target triple.") + +# Configure compiler. +include(config-ix) + +#=============================================================================== +# Setup Compiler Flags +#=============================================================================== + +# Get required flags. +# On all systems the system c++ standard library headers need to be excluded. +if (MSVC) + # MSVC only has -X, which disables all default includes; including the crt. + # Thus, we do nothing and hope we don't accidentally include any of the C++ + # headers. +else() + if (LIBCXX_HAS_NOSTDINCXX_FLAG) + set(LIBCXX_CXX_REQUIRED_FLAGS -nostdinc++) + endif() + if (LIBCXX_ENABLE_CXX0X AND LIBCXX_HAS_STDCXX0X_FLAG) + list(APPEND LIBCXX_CXX_REQUIRED_FLAGS -std=c++0x) + endif() +endif() + +macro(append_if list condition var) + if (${condition}) + list(APPEND ${list} ${var}) + endif() +endmacro() + +# Get warning flags +append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WALL_FLAG -Wall) +append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_W_FLAG -W) +append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG -Wno-unused-parameter) +append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings) +append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WNO_LONG_LONG_FLAG -Wno-long-long) +if (LIBCXX_ENABLE_WERROR) + append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WERROR_FLAG -Werror) + append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_WX_FLAG -WX) +endif() +if (LIBCXX_ENABLE_PEDANTIC) + append_if(LIBCXX_WARNING_FLAGS LIBCXX_HAS_PEDANTIC_FLAG -pedantic) +endif() + +# Get feature flags. +# Exceptions +if (LIBCXX_ENABLE_EXCEPTIONS) + # Catches C++ exceptions only and tells the compiler to assume that extern C + # functions never throw a C++ exception. + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_EHSC_FLAG -EHsc) +else() + list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_NO_EXCEPTIONS) + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_EHS_FLAG -EHs-) + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_EHA_FLAG -EHa-) + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions) +endif() +# RTTI +if (NOT LIBCXX_ENABLE_RTTI) + list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_LIBCPP_NO_RTTI) + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_NO_GR_FLAG -GR-) + append_if(LIBCXX_CXX_FEATURE_FLAGS LIBCXX_HAS_FNO_RTTI_FLAG -fno-rtti) +endif() +# Assert +if (LLVM_ENABLE_ASSERTIONS) + # MSVC doesn't like _DEBUG on release builds. See PR 4379. + if (NOT MSVC) + list(APPEND LIBCXX_CXX_FEATURE_FLAGS -D_DEBUG) + endif() + # On Release builds cmake automatically defines NDEBUG, so we + # explicitly undefine it: + if (uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") + list(APPEND LIBCXX_CXX_FEATURE_FLAGS -UNDEBUG) + endif() +else() + if (NOT uppercase_CMAKE_BUILD_TYPE STREQUAL "RELEASE") + list(APPEND LIBCXX_CXX_FEATURE_FLAGS -DNDEBUG) + endif() +endif() + +# This is the _ONLY_ place where add_definitions is called. +add_definitions( + ${LIBCXX_CXX_REQUIRED_FLAGS} + ${LIBCXX_CXX_WARNING_FLAGS} + ${LIBCXX_CXX_FEATURE_FLAGS} + ) + +#=============================================================================== +# Setup Source Code +#=============================================================================== + +include_directories(include) + +# Add source code. This also contains all of the logic for deciding linker flags +# soname, etc... +add_subdirectory(lib) + +#=============================================================================== +# Setup Tests +#=============================================================================== + +add_subdirectory(test) diff --git a/libcxx/cmake/Modules/GetTriple.cmake b/libcxx/cmake/Modules/GetTriple.cmake new file mode 100644 index 00000000000..c555931ded5 --- /dev/null +++ b/libcxx/cmake/Modules/GetTriple.cmake @@ -0,0 +1,53 @@ +# Define functions to get the host and target triple. + +function(get_host_triple out out_arch out_vendor out_os) + # Get the architecture. + set(arch ${CMAKE_HOST_SYSTEM_PROCESSOR}) + if (arch STREQUAL "x86") + set(arch "i686") + endif() + # Get the vendor. + if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin") + set(vendor "apple") + else() + set(vendor "pc") + endif() + # Get os. + if (${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + set(os "win32") + else() + string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} os) + endif() + set(triple "${arch}-${vendor}-${os}") + set(${out} ${triple} PARENT_SCOPE) + set(${out_arch} ${arch} PARENT_SCOPE) + set(${out_vendor} ${vendor} PARENT_SCOPE) + set(${out_os} ${os} PARENT_SCOPE) + message(STATUS "Host triple: ${triple}") +endfunction() + +function(get_target_triple out out_arch out_vendor out_os) + # Get the architecture. + set(arch ${CMAKE_SYSTEM_PROCESSOR}) + if (arch STREQUAL "x86") + set(arch "i686") + endif() + # Get the vendor. + if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(vendor "apple") + else() + set(vendor "pc") + endif() + # Get os. + if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(os "win32") + else() + string(TOLOWER ${CMAKE_SYSTEM_NAME} os) + endif() + set(triple "${arch}-${vendor}-${os}") + set(${out} ${triple} PARENT_SCOPE) + set(${out_arch} ${arch} PARENT_SCOPE) + set(${out_vendor} ${vendor} PARENT_SCOPE) + set(${out_os} ${os} PARENT_SCOPE) + message(STATUS "Target triple: ${triple}") +endfunction() diff --git a/libcxx/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake b/libcxx/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake new file mode 100644 index 00000000000..a0669365bf9 --- /dev/null +++ b/libcxx/cmake/Modules/MacroEnsureOutOfSourceBuild.cmake @@ -0,0 +1,18 @@ +# MACRO_ENSURE_OUT_OF_SOURCE_BUILD(<errorMessage>) + +macro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage ) + +string( COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource ) +if( _insource ) + message( SEND_ERROR "${_errorMessage}" ) + message( FATAL_ERROR + "In-source builds are not allowed. + CMake would overwrite the makefiles distributed with Compiler-RT. + Please create a directory and run cmake from there, passing the path + to this source directory as the last argument. + This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. + Please delete them." + ) +endif( _insource ) + +endmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD ) diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake new file mode 100644 index 00000000000..118d82fe8b2 --- /dev/null +++ b/libcxx/cmake/config-ix.cmake @@ -0,0 +1,37 @@ +include(CheckLibraryExists) +include(CheckCXXCompilerFlag) + +# Check compiler flags +check_cxx_compiler_flag(-std=c++0x LIBCXX_HAS_STDCXX0X_FLAG) +check_cxx_compiler_flag(-fPIC LIBCXX_HAS_FPIC_FLAG) +check_cxx_compiler_flag(-nodefaultlibs LIBCXX_HAS_NODEFAULTLIBS_FLAG) +check_cxx_compiler_flag(-nostdinc++ LIBCXX_HAS_NOSTDINCXX_FLAG) +check_cxx_compiler_flag(-Wall LIBCXX_HAS_WALL_FLAG) +check_cxx_compiler_flag(-W LIBCXX_HAS_W_FLAG) +check_cxx_compiler_flag(-Wno-unused-parameter LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG) +check_cxx_compiler_flag(-Wwrite-strings LIBCXX_HAS_WWRITE_STRINGS_FLAG) +check_cxx_compiler_flag(-Wno-long-long LIBCXX_HAS_WNO_LONG_LONG_FLAG) +check_cxx_compiler_flag(-pedantic LIBCXX_HAS_PEDANTIC_FLAG) +check_cxx_compiler_flag(-Werror LIBCXX_HAS_WERROR_FLAG) +check_cxx_compiler_flag(-fno-exceptions LIBCXX_HAS_FNO_EXCEPTIONS_FLAG) +check_cxx_compiler_flag(-fno-rtti LIBCXX_HAS_FNO_RTTI_FLAG) +check_cxx_compiler_flag(/WX LIBCXX_HAS_WX_FLAG) +check_cxx_compiler_flag(/EHsc LIBCXX_HAS_EHSC_FLAG) +check_cxx_compiler_flag(/EHs- LIBCXX_HAS_NO_EHS_FLAG) +check_cxx_compiler_flag(/EHa- LIBCXX_HAS_NO_EHA_FLAG) +check_cxx_compiler_flag(/GR- LIBCXX_HAS_NO_GR_FLAG) + +# Check libraries +check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB) +check_library_exists(c printf "" LIBCXX_HAS_C_LIB) +check_library_exists(m ccos "" LIBCXX_HAS_M_LIB) +check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB) + +# Check C++0x features +if (LIBCXX_ENABLE_CXX0X) + if (LIBCXX_HAS_STDCXX0X_FLAG) + set(CMAKE_REQUIRED_DEFINITIONS -std=c++0x) + endif() +else() + set(LIBCXX_HAS_STDCXX0X_FLAG FALSE) +endif() diff --git a/libcxx/include/__config b/libcxx/include/__config index f2460665f72..4af9bec7741 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -214,6 +214,7 @@ using namespace _LIBCPP_NAMESPACE; #endif // !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 4) #if !(__GNUC__ >= 4 && __GNUC_MINOR__ >= 6) +#define _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS #define _LIBCPP_HAS_NO_NULLPTR #endif diff --git a/libcxx/include/__split_buffer b/libcxx/include/__split_buffer index 88e2c837503..718fd88716c 100644 --- a/libcxx/include/__split_buffer +++ b/libcxx/include/__split_buffer @@ -85,12 +85,14 @@ public: void shrink_to_fit(); void push_front(const_reference __x); void push_back(const_reference __x); -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) void push_front(value_type&& __x); void push_back(value_type&& __x); +#if !defined(_LIBCPP_HAS_NO_VARIADICS) template <class... _Args> void emplace_back(_Args&&... __args); -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +#endif // !defined(_LIBCPP_HAS_NO_VARIADICS) +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) _LIBCPP_INLINE_VISIBILITY void pop_front() {__destruct_at_begin(__begin_+1);} _LIBCPP_INLINE_VISIBILITY void pop_back() {__destruct_at_end(__end_-1);} diff --git a/libcxx/include/locale b/libcxx/include/locale index 6e807fb765d..60aab1d84bf 100644 --- a/libcxx/include/locale +++ b/libcxx/include/locale @@ -265,7 +265,10 @@ __nolocale_isdigit(int __c) } #else // __APPLE__ -inline _LIBCPP_INLINE_VISIBILITY +inline +#ifndef _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +_LIBCPP_INLINE_VISIBILITY +#endif int __nolocale_sprintf(char* __restrict __str, const char* __restrict __format, ...) @@ -276,7 +279,10 @@ __nolocale_sprintf(char* __restrict __str, va_end(__ap); return __result; } -inline _LIBCPP_INLINE_VISIBILITY +inline +#ifndef _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +_LIBCPP_INLINE_VISIBILITY +#endif int __nolocale_snprintf(char* __restrict __str, size_t __size, const char* __restrict __format, ...) @@ -287,7 +293,10 @@ __nolocale_snprintf(char* __restrict __str, size_t __size, va_end(__ap); return __result; } -inline _LIBCPP_INLINE_VISIBILITY +inline +#ifndef _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +_LIBCPP_INLINE_VISIBILITY +#endif int __nolocale_asprintf(char** __ret, const char* __restrict __format, ...) @@ -298,7 +307,10 @@ __nolocale_asprintf(char** __ret, va_end(__ap); return __result; } -inline _LIBCPP_INLINE_VISIBILITY +inline +#ifndef _LIBCPP_HAS_NO_ALWAYS_INLINE_VARIADICS +_LIBCPP_INLINE_VISIBILITY +#endif int __nolocale_sscanf(const char* __restrict __str, const char* __restrict __format, ...) diff --git a/libcxx/include/memory b/libcxx/include/memory index c20e1a0c615..90cf3e6f610 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -1487,7 +1487,7 @@ struct _LIBCPP_VISIBLE uses_allocator { }; -#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) // uses-allocator construction @@ -1505,7 +1505,7 @@ struct __uses_alloc_ctor : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> {}; -#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) +#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS) // allocator @@ -1546,6 +1546,7 @@ public: { ::new((void*)__p) _Tp(); } +# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) template <class _A0> _LIBCPP_INLINE_VISIBILITY typename enable_if @@ -1579,6 +1580,7 @@ public: { ::new((void*)__p) _Tp(_STD::move(__a0)); } +# endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) template <class _A0, class _A1> _LIBCPP_INLINE_VISIBILITY void diff --git a/libcxx/include/utility b/libcxx/include/utility index f8a8fc529a9..c65b59e3f69 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -222,6 +222,8 @@ struct _LIBCPP_VISIBLE pair second(_STD::forward<_U2>(__u2)) {} +#ifndef _LIBCPP_HAS_NO_VARIADICS + template<class _Tuple, class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type> _LIBCPP_INLINE_VISIBILITY @@ -232,7 +234,7 @@ struct _LIBCPP_VISIBLE pair typename __make_tuple_types<_Tuple>::type>::type>(get<1>(__p))) {} -#ifndef _LIBCPP_HAS_NO_VARIADICS + template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> _LIBCPP_INLINE_VISIBILITY @@ -243,8 +245,6 @@ struct _LIBCPP_VISIBLE pair typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} -#endif // _LIBCPP_HAS_NO_VARIADICS - template <class _Tuple, class = typename enable_if<__tuple_assignable<_Tuple, pair>::value>::type> _LIBCPP_INLINE_VISIBILITY @@ -259,6 +259,8 @@ struct _LIBCPP_VISIBLE pair return *this; } +#endif // _LIBCPP_HAS_NO_VARIADICS + #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES template<class _U1, class _U2> _LIBCPP_INLINE_VISIBILITY pair(const pair<_U1, _U2>& __p) diff --git a/libcxx/lib/CMakeLists.txt b/libcxx/lib/CMakeLists.txt new file mode 100644 index 00000000000..d8617842b9d --- /dev/null +++ b/libcxx/lib/CMakeLists.txt @@ -0,0 +1,56 @@ +# Get sources +file(GLOB_RECURSE sources ../src/*.cpp) + +# Add all the headers to the project for IDEs. +if (MSVC_IDE OR XCODE) + file(GLOB_RECURSE headers ../include/*) + # Force them all into the headers dir on MSVC, otherwise they end up at + # project scope because they don't have extensions. + if (MSVC_IDE) + source_group("Header Files" FILES ${headers}) + endif() +endif() + +if (LIBCXX_ENABLE_SHARED) + add_library(cxx SHARED + ${sources} + ${headers} + ) +else() + add_library(cxx STATIC + ${sources} + ${headers} + ) +endif() + +# Generate library list. +append_if(libraries LIBCXX_HAS_PTHREAD_LIB pthread) +append_if(libraries LIBCXX_HAS_C_LIB c) +append_if(libraries LIBCXX_HAS_M_LIB m) +append_if(libraries LIBCXX_HAS_GCC_S_LIB gcc_s) + +target_link_libraries(cxx ${libraries}) + +# Setup flags. +append_if(compile_flags LIBCXX_HAS_FPIC_FLAG -fPIC) +append_if(link_flags LIBCXX_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs) + +set_target_properties(cxx + PROPERTIES + COMPILE_FLAGS "${compile_flags}" + LINK_FLAGS "${link_flags}" + OUTPUT_NAME "c++" + VERSION "1.0" + SOVERSION "1" + ) + +install(TARGETS cxx + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + ) + +install(DIRECTORY ../include/ + DESTINATION include/c++/v1 + FILES_MATCHING + PATTERN "*" + ) diff --git a/libcxx/lib/buildit b/libcxx/lib/buildit index 737595f72d2..db22942831b 100755 --- a/libcxx/lib/buildit +++ b/libcxx/lib/buildit @@ -2,7 +2,7 @@ # # Set the $TRIPLE environment variable to your system's triple before # running this script. If you set $CXX, that will be used to compile -# the library. Otherwise we'll use g++. +# the library. Otherwise we'll use clang++. set -e @@ -74,7 +74,7 @@ for FILE in ../src/*.cpp; do done -cc *.o $RC_CFLAGS $LDSHARED_FLAGS +cc *.o $RC_CFLAGS $LDSHARED_FLAGS #libtool -static -o libc++.a *.o diff --git a/libcxx/src/locale.cpp b/libcxx/src/locale.cpp index 344f8df3009..4bd77cac0c7 100644 --- a/libcxx/src/locale.cpp +++ b/libcxx/src/locale.cpp @@ -21,8 +21,6 @@ #include <langinfo.h> #include <stdlib.h> -// FIXME: Locales are hard. -#if __APPLE__ _LIBCPP_BEGIN_NAMESPACE_STD namespace { @@ -676,61 +674,93 @@ ctype<wchar_t>::~ctype() bool ctype<wchar_t>::do_is(mask m, char_type c) const { +#ifdef __APPLE__ return isascii(c) ? _DefaultRuneLocale.__runetype[c] & m : false; +#else + return false; +#endif } const wchar_t* ctype<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const { +#ifdef __APPLE__ for (; low != high; ++low, ++vec) *vec = static_cast<mask>(isascii(*low) ? _DefaultRuneLocale.__runetype[*low] : 0); return low; +#else + return NULL; +#endif } const wchar_t* ctype<wchar_t>::do_scan_is(mask m, const char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) if (isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m)) break; return low; +#else + return NULL; +#endif } const wchar_t* ctype<wchar_t>::do_scan_not(mask m, const char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) if (!(isascii(*low) && (_DefaultRuneLocale.__runetype[*low] & m))) break; return low; +#else + return NULL; +#endif } wchar_t ctype<wchar_t>::do_toupper(char_type c) const { +#ifdef __APPLE__ return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; +#else + return 0; +#endif } const wchar_t* ctype<wchar_t>::do_toupper(char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; return low; +#else + return NULL; +#endif } wchar_t ctype<wchar_t>::do_tolower(char_type c) const { +#ifdef __APPLE__ return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; +#else + return 0; +#endif } const wchar_t* ctype<wchar_t>::do_tolower(char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; return low; +#else + return NULL; +#endif } wchar_t @@ -775,8 +805,10 @@ ctype<char>::ctype(const mask* tab, bool del, size_t refs) __tab_(tab), __del_(del) { +#ifdef __APPLE__ if (__tab_ == 0) __tab_ = _DefaultRuneLocale.__runetype; +#endif } ctype<char>::~ctype() @@ -788,29 +820,45 @@ ctype<char>::~ctype() char ctype<char>::do_toupper(char_type c) const { +#ifdef __APPLE__ return isascii(c) ? _DefaultRuneLocale.__mapupper[c] : c; +#else + return 0; +#endif } const char* ctype<char>::do_toupper(char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) *low = isascii(*low) ? _DefaultRuneLocale.__mapupper[*low] : *low; return low; +#else + return NULL; +#endif } char ctype<char>::do_tolower(char_type c) const { +#ifdef __APPLE__ return isascii(c) ? _DefaultRuneLocale.__maplower[c] : c; +#else + return 0; +#endif } const char* ctype<char>::do_tolower(char_type* low, const char_type* high) const { +#ifdef __APPLE__ for (; low != high; ++low) *low = isascii(*low) ? _DefaultRuneLocale.__maplower[*low] : *low; return low; +#else + return NULL; +#endif } char @@ -849,7 +897,11 @@ ctype<char>::do_narrow(const char_type* low, const char_type* high, char dfault, const ctype<char>::mask* ctype<char>::classic_table() throw() { +#ifdef __APPLE__ return _DefaultRuneLocale.__runetype; +#else + return NULL; +#endif } // template <> class ctype_byname<char> @@ -947,6 +999,7 @@ ctype_byname<wchar_t>::do_is(mask m, char_type c) const const wchar_t* ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* vec) const { +#ifdef __APPLE__ for (; low != high; ++low, ++vec) { if (isascii(*low)) @@ -975,6 +1028,9 @@ ctype_byname<wchar_t>::do_is(const char_type* low, const char_type* high, mask* } } return low; +#else + return NULL; +#endif } const wchar_t* @@ -1026,33 +1082,49 @@ ctype_byname<wchar_t>::do_tolower(char_type* low, const char_type* high) const wchar_t ctype_byname<wchar_t>::do_widen(char c) const { +#ifdef __APPLE__ return btowc_l(c, __l); +#else + return 0; +#endif } const char* ctype_byname<wchar_t>::do_widen(const char* low, const char* high, char_type* dest) const { +#ifdef __APPLE__ for (; low != high; ++low, ++dest) *dest = btowc_l(*low, __l); return low; +#else + return NULL; +#endif } char ctype_byname<wchar_t>::do_narrow(char_type c, char dfault) const { +#ifdef __APPLE__ int r = wctob_l(c, __l); return r != WEOF ? static_cast<char>(r) : dfault; +#else + return 0; +#endif } const wchar_t* ctype_byname<wchar_t>::do_narrow(const char_type* low, const char_type* high, char dfault, char* dest) const { +#ifdef __APPLE__ for (; low != high; ++low, ++dest) { int r = wctob_l(*low, __l); *dest = r != WEOF ? static_cast<char>(r) : dfault; } return low; +#else + return NULL; +#endif } // template <> class codecvt<char, char, mbstate_t> @@ -1148,6 +1220,7 @@ codecvt<wchar_t, char, mbstate_t>::do_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 { +#ifdef __APPLE__ // look for first internal null in frm const intern_type* fend = frm; for (; fend != frm_end; ++fend) @@ -1197,6 +1270,9 @@ codecvt<wchar_t, char, mbstate_t>::do_out(state_type& st, } } return frm_nxt == frm_end ? ok : partial; +#else + return error; +#endif } codecvt<wchar_t, char, mbstate_t>::result @@ -1204,6 +1280,7 @@ codecvt<wchar_t, char, mbstate_t>::do_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 { +#ifdef __APPLE__ // look for first internal null in frm const extern_type* fend = frm; for (; fend != frm_end; ++fend) @@ -1261,12 +1338,16 @@ codecvt<wchar_t, char, mbstate_t>::do_in(state_type& st, } } return frm_nxt == frm_end ? ok : partial; +#else + return error; +#endif } codecvt<wchar_t, char, mbstate_t>::result codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, extern_type* to, extern_type* to_end, extern_type*& to_nxt) const { +#ifdef __APPLE__ to_nxt = to; extern_type tmp[MB_LEN_MAX]; size_t n = wcrtomb_l(tmp, intern_type(), &st, __l); @@ -1278,11 +1359,15 @@ codecvt<wchar_t, char, mbstate_t>::do_unshift(state_type& st, for (extern_type* p = tmp; n; --n) // write it *to_nxt++ = *p++; return ok; +#else + return error; +#endif } int codecvt<wchar_t, char, mbstate_t>::do_encoding() const throw() { +#ifdef __APPLE__ if (mbtowc_l(0, 0, MB_LEN_MAX, __l) == 0) { // stateless encoding @@ -1291,6 +1376,9 @@ codecvt<wchar_t, char, mbstate_t>::do_encoding() const throw() return 0; } return -1; +#else + return 0; +#endif } bool @@ -1303,6 +1391,7 @@ int codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, const extern_type* frm, const extern_type* frm_end, size_t mx) const { +#ifdef __APPLE__ int nbytes = 0; for (size_t nwchar_t = 0; nwchar_t < mx && frm != frm_end; ++nwchar_t) { @@ -1323,12 +1412,19 @@ codecvt<wchar_t, char, mbstate_t>::do_length(state_type& st, } } return nbytes; +#else + return 0; +#endif } int codecvt<wchar_t, char, mbstate_t>::do_max_length() const throw() { +#ifdef __APPLE__ return __l == 0 ? 1 : MB_CUR_MAX_L(__l); +#else + return 0; +#endif } // Valid UTF ranges @@ -3869,6 +3965,7 @@ numpunct_byname<char>::~numpunct_byname() void numpunct_byname<char>::__init(const char* nm) { +#ifdef __APPLE__ if (strcmp(nm, "C") != 0) { unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); @@ -3885,6 +3982,7 @@ numpunct_byname<char>::__init(const char* nm) __grouping_ = lc->grouping; // locallization for truename and falsename is not available } +#endif } // numpunct_byname<wchar_t> @@ -3908,6 +4006,7 @@ numpunct_byname<wchar_t>::~numpunct_byname() void numpunct_byname<wchar_t>::__init(const char* nm) { +#ifdef __APPLE__ if (strcmp(nm, "C") != 0) { unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); @@ -3924,6 +4023,7 @@ numpunct_byname<wchar_t>::__init(const char* nm) __grouping_ = lc->grouping; // locallization for truename and falsename is not available } +#endif } // num_get helpers @@ -4488,6 +4588,7 @@ template <> wstring __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) { +#ifdef __APPLE__ tm t; t.tm_sec = 59; t.tm_min = 55; @@ -4632,6 +4733,9 @@ __time_get_storage<wchar_t>::__analyze(char fmt, const ctype<wchar_t>& ct) ++wbb; } return result; +#else + return wstring(); +#endif } template <> @@ -4675,6 +4779,7 @@ template <> void __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) { +#ifdef __APPLE__ tm t = {0}; char buf[100]; size_t be; @@ -4746,6 +4851,7 @@ __time_get_storage<wchar_t>::init(const ctype<wchar_t>& ct) __r_ = __analyze('r', ct); __x_ = __analyze('x', ct); __X_ = __analyze('X', ct); +#endif } template <class CharT> @@ -5007,6 +5113,7 @@ void __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, char __fmt, char __mod) const { +#ifdef __APPLE__ char __nar[100]; char* __ne = __nar + 100; __do_put(__nar, __ne, __tm, __fmt, __mod); @@ -5016,6 +5123,7 @@ __time_put::__do_put(wchar_t* __wb, wchar_t*& __we, const tm* __tm, if (j == -1) __throw_runtime_error("locale not supported"); __we = __wb + j; +#endif } // moneypunct_byname @@ -5260,6 +5368,7 @@ template<> void moneypunct_byname<char, false>::init(const char* nm) { +#ifdef __APPLE__ typedef moneypunct<char, false> base; unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -5292,12 +5401,14 @@ moneypunct_byname<char, false>::init(const char* nm) __negative_sign_ = lc->negative_sign; __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); +#endif } template<> void moneypunct_byname<char, true>::init(const char* nm) { +#ifdef __APPLE__ typedef moneypunct<char, true> base; unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -5330,12 +5441,14 @@ moneypunct_byname<char, true>::init(const char* nm) __negative_sign_ = lc->negative_sign; __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn); __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn); +#endif } template<> void moneypunct_byname<wchar_t, false>::init(const char* nm) { +#ifdef __APPLE__ typedef moneypunct<wchar_t, false> base; unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -5391,12 +5504,14 @@ moneypunct_byname<wchar_t, false>::init(const char* nm) } __init_pat(__pos_format_, lc->p_cs_precedes, lc->p_sep_by_space, lc->p_sign_posn); __init_pat(__neg_format_, lc->n_cs_precedes, lc->n_sep_by_space, lc->n_sign_posn); +#endif } template<> void moneypunct_byname<wchar_t, true>::init(const char* nm) { +#ifdef __APPLE__ typedef moneypunct<wchar_t, true> base; unique_ptr<_xlocale, int(*)(locale_t)> loc(newlocale(LC_ALL_MASK, nm, 0), freelocale); #ifndef _LIBCPP_NO_EXCEPTIONS @@ -5452,6 +5567,7 @@ moneypunct_byname<wchar_t, true>::init(const char* nm) } __init_pat(__pos_format_, lc->int_p_cs_precedes, lc->int_p_sep_by_space, lc->int_p_sign_posn); __init_pat(__neg_format_, lc->int_n_cs_precedes, lc->int_n_sep_by_space, lc->int_n_sign_posn); +#endif } void __do_nothing(void*) {} @@ -5526,4 +5642,3 @@ template class codecvt_byname<char32_t, char, mbstate_t>; template class __vector_base_common<true>; _LIBCPP_END_NAMESPACE_STD -#endif // __APPLE__ diff --git a/libcxx/test/CMakeLists.txt b/libcxx/test/CMakeLists.txt new file mode 100644 index 00000000000..86f94cd062b --- /dev/null +++ b/libcxx/test/CMakeLists.txt @@ -0,0 +1,44 @@ +macro(pythonize_bool var) + if (${var}) + set(${var} True) + else() + set(${var} False) + endif() +endmacro() + +include(FindPythonInterp) +if(PYTHONINTERP_FOUND) + set(LIT_EXECUTABLE "" CACHE FILEPATH "Path to LLVM's lit.py.") + set(LIT_ARGS_DEFAULT "-sv") + if (MSVC OR XCODE) + set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") + endif() + set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" + CACHE STRING "Default options for lit") + set(LIT_ARGS "${LLVM_LIT_ARGS}") + separate_arguments(LIT_ARGS) + + set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER}) + set(LIBCXX_SOURCE_DIR ${CMAKE_SOURCE_DIR}) + set(LIBCXX_BINARY_DIR ${CMAKE_BINARY_DIR}) + set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) + pythonize_bool(LIBCXX_ENABLE_SHARED) + pythonize_bool(LIBCXX_HAS_STDCXX0X_FLAG) + + set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!") + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + @ONLY) + + add_custom_target(check + COMMAND ${PYTHON_EXECUTABLE} + ${LIT_EXECUTABLE} + ${LIT_ARGS} + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS + COMMENT "Running libcxx tests") +else() + message(WARNING "Could not find Python, no check target will be available!") +endif() diff --git a/libcxx/test/lit.cfg b/libcxx/test/lit.cfg index f70d595ab2e..9feeee2f91a 100644 --- a/libcxx/test/lit.cfg +++ b/libcxx/test/lit.cfg @@ -3,6 +3,7 @@ # Configuration file for the 'lit' test runner. import os +import sys import platform import tempfile import signal @@ -66,8 +67,9 @@ class LibcxxTestFormat(lit.formats.FileBasedTest): exec_file.close() try: - cmd = [self.cxx_under_test, '-o', exec_path, + compile_cmd = [self.cxx_under_test, '-o', exec_path, source_path] + self.cpp_flags + self.ld_flags + cmd = compile_cmd out, err, exitCode = self.execute_command(cmd) if exitCode != 0: report = """Command: %s\n""" % ' '.join(["'%s'" % a @@ -83,7 +85,9 @@ class LibcxxTestFormat(lit.formats.FileBasedTest): cmd = [exec_path] out, err, exitCode = self.execute_command(cmd) if exitCode != 0: - report = """Command: %s\n""" % ' '.join(["'%s'" % a + report = """Compiled With: %s\n""" % ' '.join(["'%s'" % a + for a in compile_cmd]) + report += """Command: %s\n""" % ' '.join(["'%s'" % a for a in cmd]) report += """Exit Code: %d\n""" % exitCode if out: @@ -111,12 +115,35 @@ config.test_source_root = os.path.dirname(__file__) # FIXME: Would be nice to Use -stdlib=libc++ option with Clang's that accept it. cxx_under_test = lit.params.get('cxx_under_test', None) if cxx_under_test is None: - lit.fatal('must specify user parameter cxx_under_test ' - '(e.g., --param=cxx_under_test=clang++)') + cxx_under_test = getattr(config, 'cxx_under_test', None) + if cxx_under_test is None: + lit.fatal('must specify user parameter cxx_under_test ' + '(e.g., --param=cxx_under_test=clang++)') +include_paths = [] +library_paths = [] + +libcxx_src_root = getattr(config, 'libcxx_src_root', None) +if libcxx_src_root is not None: + include_paths += ['-I' + libcxx_src_root + '/include'] +else: + include_paths += ['-I/usr/include/c++/v1'] + +libcxx_obj_root = getattr(config, 'libcxx_obj_root', None) +if libcxx_obj_root is not None: + library_paths += ['-L' + libcxx_obj_root + '/lib'] +else: + libcxx_obj_root = "/usr" + +# Configure extra libraries. +libraries = [] +if sys.platform == 'darwin': + libraries += ['-lSystem'] +if sys.platform == 'linux2': + libraries += ['-lgcc_eh', '-lsupc++', '-lc', '-lm', '-lgcc_s'] + libraries += ['-Wl,-R', libcxx_obj_root + '/lib'] + config.test_format = LibcxxTestFormat(cxx_under_test, - cpp_flags = ['-nostdinc++', - '-I/usr/include/c++/v1'], - ld_flags = ['-nodefaultlibs', '-lc++', - '-lSystem']) + cpp_flags = ['-nostdinc++'] + include_paths, + ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + libraries) config.target_triple = None diff --git a/libcxx/test/lit.site.cfg.in b/libcxx/test/lit.site.cfg.in new file mode 100644 index 00000000000..57a83df5aa4 --- /dev/null +++ b/libcxx/test/lit.site.cfg.in @@ -0,0 +1,10 @@ +@AUTO_GEN_COMMENT@ +config.cxx_under_test = "@LIBCXX_COMPILER@" +config.cxx_has_stdcxx0x_flag = @LIBCXX_HAS_STDCXX0X_FLAG@ +config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@" +config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@" +config.python_executable = "@PYTHON_EXECUTABLE@" +config.enable_shared = @LIBCXX_ENABLE_SHARED@ + +# Let the main config do the real work. +lit.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg") |