diff --git a/libcxx/include/__config b/libcxx/include/__config index c8224b07a6b8..070298301b0d 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -577,15 +577,27 @@ typedef __char32_t char32_t; # define _LIBCPP_POP_EXTENSION_DIAGNOSTICS # endif -// Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect. // clang-format off -# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS \ - namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { \ - inline namespace _LIBCPP_ABI_NAMESPACE { -# define _LIBCPP_END_NAMESPACE_STD }} _LIBCPP_POP_EXTENSION_DIAGNOSTICS -#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL namespace std { namespace experimental { -#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL }} +// The unversioned namespace is used when we want to be ABI compatible with other standard libraries in some way. There +// are two main categories where that's the case: +// - Historically, we have made exception types ABI compatible with libstdc++ to allow throwing them between libstdc++ +// and libc++. This is not used anymore for new exception types, since there is no use-case for it anymore. +// - Types and functions which are used by the compiler are in the unversioned namespace, since the compiler has to know +// their mangling without the appropriate declaration in some cases. +// If it's not clear whether using the unversioned namespace is the correct thing to do, it's not. The versioned +// namespace (_LIBCPP_BEGIN_NAMESPACE_STD) should almost always be used. +# define _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD \ + _LIBCPP_PUSH_EXTENSION_DIAGNOSTICS namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std { + +# define _LIBCPP_END_UNVERSIONED_NAMESPACE_STD } _LIBCPP_POP_EXTENSION_DIAGNOSTICS + +# define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD inline namespace _LIBCPP_ABI_NAMESPACE { +# define _LIBCPP_END_NAMESPACE_STD } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD + +// TODO: This should really be in the versioned namespace +#define _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL _LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD namespace experimental { +#define _LIBCPP_END_NAMESPACE_EXPERIMENTAL } _LIBCPP_END_UNVERSIONED_NAMESPACE_STD #define _LIBCPP_BEGIN_NAMESPACE_LFTS _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace fundamentals_v1 { #define _LIBCPP_END_NAMESPACE_LFTS } _LIBCPP_END_NAMESPACE_EXPERIMENTAL diff --git a/libcxx/include/__cstddef/byte.h b/libcxx/include/__cstddef/byte.h index 09e1d75e0b41..3d97db1bea29 100644 --- a/libcxx/include/__cstddef/byte.h +++ b/libcxx/include/__cstddef/byte.h @@ -19,7 +19,7 @@ #endif #if _LIBCPP_STD_VER >= 17 -namespace std { // purposefully not versioned +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD enum class byte : unsigned char {}; @@ -79,7 +79,7 @@ template ::value, int> = 0> return static_cast<_Integer>(__b); } -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___CSTDDEF_BYTE_H diff --git a/libcxx/include/__exception/exception.h b/libcxx/include/__exception/exception.h index e724e1b99bd1..f7dab6e83ad1 100644 --- a/libcxx/include/__exception/exception.h +++ b/libcxx/include/__exception/exception.h @@ -21,7 +21,7 @@ # pragma GCC system_header #endif -namespace std { // purposefully not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD #if defined(_LIBCPP_ABI_VCRUNTIME) && (!defined(_HAS_EXCEPTIONS) || _HAS_EXCEPTIONS != 0) // The std::exception class was already included above, but we're explicit about this condition here for clarity. @@ -89,6 +89,6 @@ public: }; #endif // !_LIBCPP_ABI_VCRUNTIME -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___EXCEPTION_EXCEPTION_H diff --git a/libcxx/include/__exception/exception_ptr.h b/libcxx/include/__exception/exception_ptr.h index 6257e6f729bf..dac5b00b57fe 100644 --- a/libcxx/include/__exception/exception_ptr.h +++ b/libcxx/include/__exception/exception_ptr.h @@ -52,7 +52,7 @@ _LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception( #endif -namespace std { // purposefully not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD #ifndef _LIBCPP_ABI_MICROSOFT @@ -171,6 +171,6 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { } #endif // _LIBCPP_ABI_MICROSOFT -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H diff --git a/libcxx/include/__exception/nested_exception.h b/libcxx/include/__exception/nested_exception.h index d560b6bbc35a..90b14158d57a 100644 --- a/libcxx/include/__exception/nested_exception.h +++ b/libcxx/include/__exception/nested_exception.h @@ -27,7 +27,7 @@ # pragma GCC system_header #endif -namespace std { // purposefully not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD class _LIBCPP_EXPORTED_FROM_ABI nested_exception { exception_ptr __ptr_; @@ -95,6 +95,6 @@ inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep& __e) { template ::value, int> = 0> inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep&) {} -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H diff --git a/libcxx/include/__exception/operations.h b/libcxx/include/__exception/operations.h index 15520c558a0b..29d5c698a96d 100644 --- a/libcxx/include/__exception/operations.h +++ b/libcxx/include/__exception/operations.h @@ -15,7 +15,7 @@ # pragma GCC system_header #endif -namespace std { // purposefully not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD #if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS) || \ defined(_LIBCPP_BUILDING_LIBRARY) using unexpected_handler = void (*)(); @@ -37,6 +37,6 @@ class _LIBCPP_EXPORTED_FROM_ABI exception_ptr; _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; [[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___EXCEPTION_OPERATIONS_H diff --git a/libcxx/include/__exception/terminate.h b/libcxx/include/__exception/terminate.h index 0bfc3506d379..955a49c2b00c 100644 --- a/libcxx/include/__exception/terminate.h +++ b/libcxx/include/__exception/terminate.h @@ -15,8 +15,8 @@ # pragma GCC system_header #endif -namespace std { // purposefully not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD [[__noreturn__]] _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___EXCEPTION_TERMINATE_H diff --git a/libcxx/include/__fwd/byte.h b/libcxx/include/__fwd/byte.h index 0301833d93cf..6f2d6ae254a2 100644 --- a/libcxx/include/__fwd/byte.h +++ b/libcxx/include/__fwd/byte.h @@ -16,11 +16,11 @@ #endif #if _LIBCPP_STD_VER >= 17 -namespace std { // purposefully not versioned +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD enum class byte : unsigned char; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 #endif // _LIBCPP___FWD_BYTE_H diff --git a/libcxx/include/__new/align_val_t.h b/libcxx/include/__new/align_val_t.h index ffb4e36a8bcd..03ab7cb143a2 100644 --- a/libcxx/include/__new/align_val_t.h +++ b/libcxx/include/__new/align_val_t.h @@ -16,8 +16,7 @@ # pragma GCC system_header #endif -// purposefully not using versioning namespace -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD #if _LIBCPP_HAS_LIBRARY_ALIGNED_ALLOCATION && !defined(_LIBCPP_ABI_VCRUNTIME) # ifndef _LIBCPP_CXX03_LANG enum class align_val_t : size_t {}; @@ -25,6 +24,6 @@ enum class align_val_t : size_t {}; enum align_val_t { __zero = 0, __max = (size_t)-1 }; # endif #endif -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___NEW_ALIGN_VAL_T_H diff --git a/libcxx/include/__new/destroying_delete_t.h b/libcxx/include/__new/destroying_delete_t.h index 7fca4f6c68b2..1d06d912b44e 100644 --- a/libcxx/include/__new/destroying_delete_t.h +++ b/libcxx/include/__new/destroying_delete_t.h @@ -16,15 +16,14 @@ #endif #if _LIBCPP_STD_VER >= 20 -// purposefully not using versioning namespace -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD // Enable the declaration even if the compiler doesn't support the language // feature. struct destroying_delete_t { explicit destroying_delete_t() = default; }; inline constexpr destroying_delete_t destroying_delete{}; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif #endif // _LIBCPP___NEW_DESTROYING_DELETE_T_H diff --git a/libcxx/include/__new/exceptions.h b/libcxx/include/__new/exceptions.h index 053feecb0367..86951818b7aa 100644 --- a/libcxx/include/__new/exceptions.h +++ b/libcxx/include/__new/exceptions.h @@ -17,8 +17,7 @@ # pragma GCC system_header #endif -// purposefully not using versioning namespace -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD #if !defined(_LIBCPP_ABI_VCRUNTIME) class _LIBCPP_EXPORTED_FROM_ABI bad_alloc : public exception { @@ -69,6 +68,6 @@ public: _LIBCPP_VERBOSE_ABORT("bad_array_new_length was thrown in -fno-exceptions mode"); #endif } -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP___NEW_EXCEPTIONS_H diff --git a/libcxx/include/__new/new_handler.h b/libcxx/include/__new/new_handler.h index c9afdab45afc..05f4e846c3ef 100644 --- a/libcxx/include/__new/new_handler.h +++ b/libcxx/include/__new/new_handler.h @@ -18,12 +18,11 @@ #if defined(_LIBCPP_ABI_VCRUNTIME) # include #else -// purposefully not using versioning namespace -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD typedef void (*new_handler)(); _LIBCPP_EXPORTED_FROM_ABI new_handler set_new_handler(new_handler) _NOEXCEPT; _LIBCPP_EXPORTED_FROM_ABI new_handler get_new_handler() _NOEXCEPT; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP_ABI_VCRUNTIME #endif // _LIBCPP___NEW_NEW_HANDLER_H diff --git a/libcxx/include/__new/nothrow_t.h b/libcxx/include/__new/nothrow_t.h index 09c2d03f66cc..a286bf7af628 100644 --- a/libcxx/include/__new/nothrow_t.h +++ b/libcxx/include/__new/nothrow_t.h @@ -18,13 +18,12 @@ #if defined(_LIBCPP_ABI_VCRUNTIME) # include #else -// purposefully not using versioning namespace -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD struct _LIBCPP_EXPORTED_FROM_ABI nothrow_t { explicit nothrow_t() = default; }; extern _LIBCPP_EXPORTED_FROM_ABI const nothrow_t nothrow; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD #endif // _LIBCPP_ABI_VCRUNTIME #endif // _LIBCPP___NEW_NOTHROW_T_H diff --git a/libcxx/include/any b/libcxx/include/any index b1df494d3db8..c7d85ba71ac6 100644 --- a/libcxx/include/any +++ b/libcxx/include/any @@ -119,12 +119,12 @@ namespace std { _LIBCPP_PUSH_MACROS # include <__undef_macros> -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_ANY_CAST bad_any_cast : public bad_cast { public: const char* what() const _NOEXCEPT override; }; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo index 799c6ebd5ecb..24aaabf0a87d 100644 --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -354,7 +354,7 @@ public: # if defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 -namespace std { +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD class bad_cast : public exception { public: @@ -372,7 +372,7 @@ private: bad_typeid(const char* const __message) _NOEXCEPT : exception(__message) {} }; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD # endif // defined(_LIBCPP_ABI_VCRUNTIME) && _HAS_EXCEPTIONS == 0 diff --git a/libcxx/include/variant b/libcxx/include/variant index 38c34725d5e0..1c3d1cdc5638 100644 --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -283,14 +283,14 @@ namespace std { _LIBCPP_PUSH_MACROS # include <__undef_macros> -namespace std { // explicitly not using versioning namespace +_LIBCPP_BEGIN_UNVERSIONED_NAMESPACE_STD class _LIBCPP_EXPORTED_FROM_ABI _LIBCPP_AVAILABILITY_BAD_VARIANT_ACCESS bad_variant_access : public exception { public: const char* what() const _NOEXCEPT override; }; -} // namespace std +_LIBCPP_END_UNVERSIONED_NAMESPACE_STD _LIBCPP_BEGIN_NAMESPACE_STD