Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -117,6 +117,7 @@ "LIBCXX_ENABLE_FILESYSTEM;LIBCXX_INSTALL_LIBRARY" OFF) set(LIBCXX_ABI_VERSION "1" CACHE STRING "ABI version of libc++. Can be either 1 or 2, where 2 is currently not stable. Defaults to 1.") +set(LIBCXX_ABI_NAMESPACE "" CACHE STRING "The inline ABI namespace used by libc++. It defaults to __n where `n` is the current ABI version.") option(LIBCXX_ABI_UNSTABLE "Unstable ABI of libc++." OFF) option(LIBCXX_ABI_FORCE_ITANIUM "Ignore auto-detection and force use of the Itanium ABI.") option(LIBCXX_ABI_FORCE_MICROSOFT "Ignore auto-detection and force use of the Microsoft ABI.") @@ -680,6 +681,15 @@ if (NOT LIBCXX_ABI_VERSION EQUAL 1) config_define(${LIBCXX_ABI_VERSION} _LIBCPP_ABI_VERSION) endif() +if (NOT LIBCXX_ABI_NAMESPACE STREQUAL "") + if (NOT LIBCXX_ABI_NAMESPACE MATCHES "__.*") + message(WARNING "LIBCXX_ABI_NAMESPACE must be a reserved identifier.") + endif() + if (LIBCXX_ABI_NAMESPACE MATCHES "__[0-9]+$") + message(FATAL_ERROR "LIBCXX_ABI_NAMESPACE '${LIBCXX_ABI_NAMESPACE}' is reserved for use by libc++.") + endif() + config_define(${LIBCXX_ABI_NAMESPACE} _LIBCPP_ABI_NAMESPACE) +endif() config_define_if(LIBCXX_ABI_UNSTABLE _LIBCPP_ABI_UNSTABLE) config_define_if(LIBCXX_ABI_FORCE_ITANIUM _LIBCPP_ABI_FORCE_ITANIUM) config_define_if(LIBCXX_ABI_FORCE_MICROSOFT _LIBCPP_ABI_FORCE_MICROSOFT) Index: docs/BuildingLibcxx.rst =================================================================== --- docs/BuildingLibcxx.rst +++ docs/BuildingLibcxx.rst @@ -360,6 +360,18 @@ Build the "unstable" ABI version of libc++. Includes all ABI changing features on top of the current stable version. +.. option:: LIBCXX_ABI_NAMESPACE:STRING + + **Default**: ``__n`` where ``n`` is the current ABI version. + + This option defines the name of the inline ABI versioning namespace. It can be used for building + custom versions of libc++ with unique symbol names in order to prevent conflicts or ODR issues + with other libc++ versions. + + .. warning:: + When providing a custom namespace, it's the users responsibility to ensure the name won't cause + conflicts with other names defined by libc++, both now and in the future. + .. option:: LIBCXX_ABI_DEFINES:STRING **Default**: ``""`` Index: include/__config =================================================================== --- include/__config +++ include/__config @@ -119,7 +119,9 @@ #define _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_X##_LIBCPP_Y #define _LIBCPP_CONCAT(_LIBCPP_X,_LIBCPP_Y) _LIBCPP_CONCAT1(_LIBCPP_X,_LIBCPP_Y) -#define _LIBCPP_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#ifndef _LIBCPP_ABI_NAMESPACE +# define _LIBCPP_ABI_NAMESPACE _LIBCPP_CONCAT(__,_LIBCPP_ABI_VERSION) +#endif #if __cplusplus < 201103L #define _LIBCPP_CXX03_LANG @@ -791,9 +793,9 @@ #define _LIBCPP_INLINE_VISIBILITY _LIBCPP_HIDE_FROM_ABI // Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. -#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_NAMESPACE { +#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { inline namespace _LIBCPP_ABI_NAMESPACE { #define _LIBCPP_END_NAMESPACE_STD } } -#define _VSTD std::_LIBCPP_NAMESPACE +#define _VSTD std::_LIBCPP_ABI_NAMESPACE _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD #if _LIBCPP_STD_VER >= 17 Index: include/__config_site.in =================================================================== --- include/__config_site.in +++ include/__config_site.in @@ -28,6 +28,7 @@ #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS #cmakedefine _LIBCPP_NO_VCRUNTIME +#cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ @_LIBCPP_ABI_DEFINES@ Index: src/iostream.cpp =================================================================== --- src/iostream.cpp +++ src/iostream.cpp @@ -13,21 +13,21 @@ #define _str(s) #s #define str(s) _str(s) -#define _LIBCPP_NAMESPACE_STR str(_LIBCPP_NAMESPACE) +#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE) _LIBCPP_BEGIN_NAMESPACE_STD #ifndef _LIBCPP_HAS_NO_STDIN _ALIGNAS_TYPE (istream) _LIBCPP_FUNC_VIS char cin[sizeof(istream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdinbuf ) static char __cin[sizeof(__stdinbuf )]; static mbstate_t mb_cin; _ALIGNAS_TYPE (wistream) _LIBCPP_FUNC_VIS char wcin[sizeof(wistream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcin@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdinbuf ) static char __wcin[sizeof(__stdinbuf )]; @@ -37,14 +37,14 @@ #ifndef _LIBCPP_HAS_NO_STDOUT _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cout[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf) static char __cout[sizeof(__stdoutbuf)]; static mbstate_t mb_cout; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcout[sizeof(wostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcout@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf) static char __wcout[sizeof(__stdoutbuf)]; @@ -53,14 +53,14 @@ _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char cerr[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?cerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf) static char __cerr[sizeof(__stdoutbuf)]; static mbstate_t mb_cerr; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wcerr[sizeof(wostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wcerr@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (__stdoutbuf) static char __wcerr[sizeof(__stdoutbuf)]; @@ -68,12 +68,12 @@ _ALIGNAS_TYPE (ostream) _LIBCPP_FUNC_VIS char clog[sizeof(ostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?clog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ; _ALIGNAS_TYPE (wostream) _LIBCPP_FUNC_VIS char wclog[sizeof(wostream)] #if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__) -__asm__("?wclog@" _LIBCPP_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_NAMESPACE_STR "@std@@@12@A") +__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR "@std@@@12@A") #endif ;