Skip to content

Commit 584a9bf

Browse files
authored
[libc++] Reorganize the std::variant macros (#89419)
std::variant uses multiple macros to generate special member functions. These macros were very subtle to read because of e.g. a macro argument appearing in the middle of a macro-ized class definition. In conjunction with clang-format, this could lead to extremely subtle macro expansions that were not easy to parse for humans. By adding semi-colons in macro expansions in judicious places, clang-format does a better job and makes these macros a lot easier to read. As a drive-by fix, I noticed that several of these functions were missing HIDE_FROM_ABI annotations, so I added them.
1 parent fcf8667 commit 584a9bf

File tree

1 file changed

+59
-45
lines changed

1 file changed

+59
-45
lines changed

libcxx/include/variant

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,10 @@ private:
657657

658658
} // namespace __visitation
659659

660+
// Adding semi-colons in macro expansions helps clang-format to do a better job.
661+
// This macro is used to avoid compilation errors due to "stray" semi-colons.
662+
# define _LIBCPP_EAT_SEMICOLON static_assert(true, "")
663+
660664
template <size_t _Index, class _Tp>
661665
struct _LIBCPP_TEMPLATE_VIS __alt {
662666
using __value_type = _Tp;
@@ -691,11 +695,10 @@ union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
691695
__union(const __union&) = default; \
692696
__union(__union&&) = default; \
693697
\
694-
destructor \
698+
destructor; \
695699
\
696-
__union& \
697-
operator=(const __union&) = default; \
698-
__union& operator=(__union&&) = default; \
700+
__union& operator=(const __union&) = default; \
701+
__union& operator=(__union&&) = default; \
699702
\
700703
private: \
701704
char __dummy; \
@@ -705,9 +708,10 @@ union _LIBCPP_TEMPLATE_VIS __union<_DestructibleTrait, _Index> {};
705708
friend struct __access::__union; \
706709
}
707710

708-
_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default;);
709-
_LIBCPP_VARIANT_UNION(_Trait::_Available, ~__union(){});
710-
_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete;);
711+
_LIBCPP_VARIANT_UNION(_Trait::_TriviallyAvailable, ~__union() = default);
712+
_LIBCPP_VARIANT_UNION(
713+
_Trait::_Available, _LIBCPP_HIDE_FROM_ABI ~__union() {} _LIBCPP_EAT_SEMICOLON);
714+
_LIBCPP_VARIANT_UNION(_Trait::_Unavailable, ~__union() = delete);
711715

712716
# undef _LIBCPP_VARIANT_UNION
713717

@@ -761,23 +765,27 @@ class _LIBCPP_TEMPLATE_VIS __dtor;
761765
using __base_type::__base_type; \
762766
using __base_type::operator=; \
763767
\
764-
__dtor(const __dtor&) = default; \
765-
__dtor(__dtor&&) = default; \
766-
destructor __dtor& operator=(const __dtor&) = default; \
767-
__dtor& operator=(__dtor&&) = default; \
768+
__dtor(const __dtor&) = default; \
769+
__dtor(__dtor&&) = default; \
770+
__dtor& operator=(const __dtor&) = default; \
771+
__dtor& operator=(__dtor&&) = default; \
772+
destructor; \
768773
\
769774
protected: \
770-
inline _LIBCPP_HIDE_FROM_ABI destroy \
775+
inline _LIBCPP_HIDE_FROM_ABI destroy; \
771776
}
772777

773778
_LIBCPP_VARIANT_DESTRUCTOR(
774-
_Trait::_TriviallyAvailable, ~__dtor() = default;
775-
, void __destroy() noexcept { this->__index = __variant_npos<__index_t>; });
779+
_Trait::_TriviallyAvailable,
780+
~__dtor() = default, //
781+
_LIBCPP_HIDE_FROM_ABI void __destroy() noexcept {
782+
this->__index = __variant_npos<__index_t>;
783+
} _LIBCPP_EAT_SEMICOLON);
776784

777785
_LIBCPP_VARIANT_DESTRUCTOR(
778786
_Trait::_Available,
779-
~__dtor() { __destroy(); },
780-
void __destroy() noexcept {
787+
_LIBCPP_HIDE_FROM_ABI ~__dtor() { __destroy(); } _LIBCPP_EAT_SEMICOLON,
788+
_LIBCPP_HIDE_FROM_ABI void __destroy() noexcept {
781789
if (!this->valueless_by_exception()) {
782790
__visitation::__base::__visit_alt(
783791
[](auto& __alt) noexcept {
@@ -787,9 +795,9 @@ _LIBCPP_VARIANT_DESTRUCTOR(
787795
*this);
788796
}
789797
this->__index = __variant_npos<__index_t>;
790-
});
798+
} _LIBCPP_EAT_SEMICOLON);
791799

792-
_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, ~__dtor() = delete;, void __destroy() noexcept = delete;);
800+
_LIBCPP_VARIANT_DESTRUCTOR(_Trait::_Unavailable, ~__dtor() = delete, void __destroy() noexcept = delete);
793801

794802
# undef _LIBCPP_VARIANT_DESTRUCTOR
795803

@@ -839,20 +847,24 @@ class _LIBCPP_TEMPLATE_VIS __move_constructor;
839847
using __base_type::operator=; \
840848
\
841849
__move_constructor(const __move_constructor&) = default; \
842-
move_constructor ~__move_constructor() = default; \
850+
~__move_constructor() = default; \
843851
__move_constructor& operator=(const __move_constructor&) = default; \
844852
__move_constructor& operator=(__move_constructor&&) = default; \
853+
move_constructor; \
845854
}
846855

847856
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_TriviallyAvailable,
848-
__move_constructor(__move_constructor&& __that) = default;);
857+
__move_constructor(__move_constructor&& __that) = default);
849858

850859
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(
851860
_Trait::_Available,
852-
__move_constructor(__move_constructor&& __that) noexcept(__all<is_nothrow_move_constructible_v<_Types>...>::value)
853-
: __move_constructor(__valueless_t{}) { this->__generic_construct(*this, std::move(__that)); });
861+
_LIBCPP_HIDE_FROM_ABI __move_constructor(__move_constructor&& __that) noexcept(
862+
__all<is_nothrow_move_constructible_v<_Types>...>::value)
863+
: __move_constructor(__valueless_t{}) {
864+
this->__generic_construct(*this, std::move(__that));
865+
} _LIBCPP_EAT_SEMICOLON);
854866

855-
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_Unavailable, __move_constructor(__move_constructor&&) = delete;);
867+
_LIBCPP_VARIANT_MOVE_CONSTRUCTOR(_Trait::_Unavailable, __move_constructor(__move_constructor&&) = delete);
856868

857869
# undef _LIBCPP_VARIANT_MOVE_CONSTRUCTOR
858870

@@ -869,20 +881,21 @@ class _LIBCPP_TEMPLATE_VIS __copy_constructor;
869881
using __base_type::__base_type; \
870882
using __base_type::operator=; \
871883
\
872-
copy_constructor __copy_constructor(__copy_constructor&&) = default; \
873-
~__copy_constructor() = default; \
874-
__copy_constructor& operator=(const __copy_constructor&) = default; \
875-
__copy_constructor& operator=(__copy_constructor&&) = default; \
876-
}
884+
__copy_constructor(__copy_constructor&&) = default; \
885+
~__copy_constructor() = default; \
886+
__copy_constructor& operator=(const __copy_constructor&) = default; \
887+
__copy_constructor& operator=(__copy_constructor&&) = default; \
888+
copy_constructor; \
889+
} // namespace __variant_detail
877890

878891
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_TriviallyAvailable,
879-
__copy_constructor(const __copy_constructor& __that) = default;);
892+
__copy_constructor(const __copy_constructor& __that) = default);
880893

881894
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(
882-
_Trait::_Available, __copy_constructor(const __copy_constructor& __that)
883-
: __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); });
895+
_Trait::_Available, _LIBCPP_HIDE_FROM_ABI __copy_constructor(const __copy_constructor& __that)
896+
: __copy_constructor(__valueless_t{}) { this->__generic_construct(*this, __that); } _LIBCPP_EAT_SEMICOLON);
884897

885-
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_Unavailable, __copy_constructor(const __copy_constructor&) = delete;);
898+
_LIBCPP_VARIANT_COPY_CONSTRUCTOR(_Trait::_Unavailable, __copy_constructor(const __copy_constructor&) = delete);
886899

887900
# undef _LIBCPP_VARIANT_COPY_CONSTRUCTOR
888901

@@ -955,22 +968,22 @@ class _LIBCPP_TEMPLATE_VIS __move_assignment;
955968
__move_assignment(__move_assignment&&) = default; \
956969
~__move_assignment() = default; \
957970
__move_assignment& operator=(const __move_assignment&) = default; \
958-
move_assignment \
971+
move_assignment; \
959972
}
960973

961974
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_TriviallyAvailable,
962-
__move_assignment& operator=(__move_assignment&& __that) = default;);
975+
__move_assignment& operator=(__move_assignment&& __that) = default);
963976

964977
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(
965978
_Trait::_Available,
966-
__move_assignment&
979+
_LIBCPP_HIDE_FROM_ABI __move_assignment&
967980
operator=(__move_assignment&& __that) noexcept(
968981
__all<(is_nothrow_move_constructible_v<_Types> && is_nothrow_move_assignable_v<_Types>)...>::value) {
969982
this->__generic_assign(std::move(__that));
970983
return *this;
971-
});
984+
} _LIBCPP_EAT_SEMICOLON);
972985

973-
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_Unavailable, __move_assignment& operator=(__move_assignment&&) = delete;);
986+
_LIBCPP_VARIANT_MOVE_ASSIGNMENT(_Trait::_Unavailable, __move_assignment& operator=(__move_assignment&&) = delete);
974987

975988
# undef _LIBCPP_VARIANT_MOVE_ASSIGNMENT
976989

@@ -987,22 +1000,23 @@ class _LIBCPP_TEMPLATE_VIS __copy_assignment;
9871000
using __base_type::__base_type; \
9881001
using __base_type::operator=; \
9891002
\
990-
__copy_assignment(const __copy_assignment&) = default; \
991-
__copy_assignment(__copy_assignment&&) = default; \
992-
~__copy_assignment() = default; \
993-
copy_assignment __copy_assignment& operator=(__copy_assignment&&) = default; \
1003+
__copy_assignment(const __copy_assignment&) = default; \
1004+
__copy_assignment(__copy_assignment&&) = default; \
1005+
~__copy_assignment() = default; \
1006+
__copy_assignment& operator=(__copy_assignment&&) = default; \
1007+
copy_assignment; \
9941008
}
9951009

9961010
_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_TriviallyAvailable,
997-
__copy_assignment& operator=(const __copy_assignment& __that) = default;);
1011+
__copy_assignment& operator=(const __copy_assignment& __that) = default);
9981012

9991013
_LIBCPP_VARIANT_COPY_ASSIGNMENT(
1000-
_Trait::_Available, __copy_assignment& operator=(const __copy_assignment& __that) {
1014+
_Trait::_Available, _LIBCPP_HIDE_FROM_ABI __copy_assignment& operator=(const __copy_assignment& __that) {
10011015
this->__generic_assign(__that);
10021016
return *this;
1003-
});
1017+
} _LIBCPP_EAT_SEMICOLON);
10041018

1005-
_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, __copy_assignment& operator=(const __copy_assignment&) = delete;);
1019+
_LIBCPP_VARIANT_COPY_ASSIGNMENT(_Trait::_Unavailable, __copy_assignment& operator=(const __copy_assignment&) = delete);
10061020

10071021
# undef _LIBCPP_VARIANT_COPY_ASSIGNMENT
10081022

0 commit comments

Comments
 (0)