antoniofrighetto updated this revision to Diff 420894. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122808/new/
https://reviews.llvm.org/D122808 Files: clang/include/clang/AST/DeclarationName.h llvm/include/llvm/ADT/STLExtras.h llvm/unittests/ADT/STLExtrasTest.cpp
Index: llvm/unittests/ADT/STLExtrasTest.cpp =================================================================== --- llvm/unittests/ADT/STLExtrasTest.cpp +++ llvm/unittests/ADT/STLExtrasTest.cpp @@ -989,4 +989,26 @@ static_assert(!is_contained({1, 2, 3, 4}, 5), "It's not there :("); } +TEST(STLExtrasTest, addEnumValues) { + enum A { Zero = 0, One = 1 }; + enum B { IntMax = INT_MAX, ULongLongMax = ULLONG_MAX }; + enum class C : unsigned { Two = 2 }; + + // Non-fixed underlying types, with same underlying types + static_assert(addEnumValues(Zero, One) == 1); + static_assert(addEnumValues(IntMax, ULongLongMax) == + INT_MAX + static_cast<unsigned long long>(ULLONG_MAX)); + // Non-fixed underlying types, with different underlying types + static_assert(addEnumValues(Zero, IntMax) == INT_MAX); + static_assert(addEnumValues(One, ULongLongMax) == + 1 + static_cast<unsigned long long>(ULLONG_MAX)); + // Non-fixed underlying type enum and fixed underlying type enum, with same + // underlying types + static_assert(addEnumValues(One, C::Two) == 3); + // Non-fixed underlying type enum and fixed underlying type enum, with + // different underlying types + static_assert(addEnumValues(ULongLongMax, C::Two) == + static_cast<unsigned long long>(ULLONG_MAX) + 2); +} + } // namespace Index: llvm/include/llvm/ADT/STLExtras.h =================================================================== --- llvm/include/llvm/ADT/STLExtras.h +++ llvm/include/llvm/ADT/STLExtras.h @@ -203,6 +203,17 @@ template <size_t I, typename... Ts> using TypeAtIndex = std::tuple_element_t<I, std::tuple<Ts...>>; +/// Helper which adds two underlying types of enumeration type. +/// Implicit conversion to a common type is accepted. +template <typename EnumTy1, typename EnumTy2, + typename UT1 = std::enable_if_t<std::is_enum<EnumTy1>::value, + std::underlying_type_t<EnumTy1>>, + typename UT2 = std::enable_if_t<std::is_enum<EnumTy2>::value, + std::underlying_type_t<EnumTy2>>> +constexpr auto addEnumValues(EnumTy1 LHS, EnumTy2 RHS) { + return static_cast<UT1>(LHS) + static_cast<UT2>(RHS); +} + //===----------------------------------------------------------------------===// // Extra additions to <iterator> //===----------------------------------------------------------------------===// Index: clang/include/clang/AST/DeclarationName.h =================================================================== --- clang/include/clang/AST/DeclarationName.h +++ clang/include/clang/AST/DeclarationName.h @@ -21,6 +21,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include <cassert> @@ -192,6 +193,13 @@ "The various classes that DeclarationName::Ptr can point to" " must be at least aligned to 8 bytes!"); + static_assert( + std::is_same<std::underlying_type_t<StoredNameKind>, + std::underlying_type_t< + detail::DeclarationNameExtra::ExtraKind>>::value, + "The various enums used to compute values for NameKind should " + "all have the same underlying type"); + public: /// The kind of the name stored in this DeclarationName. /// The first 7 enumeration values are stored inline and correspond @@ -205,15 +213,18 @@ CXXDestructorName = StoredCXXDestructorName, CXXConversionFunctionName = StoredCXXConversionFunctionName, CXXOperatorName = StoredCXXOperatorName, - CXXDeductionGuideName = UncommonNameKindOffset + - detail::DeclarationNameExtra::CXXDeductionGuideName, - CXXLiteralOperatorName = - UncommonNameKindOffset + - detail::DeclarationNameExtra::CXXLiteralOperatorName, - CXXUsingDirective = UncommonNameKindOffset + - detail::DeclarationNameExtra::CXXUsingDirective, - ObjCMultiArgSelector = UncommonNameKindOffset + - detail::DeclarationNameExtra::ObjCMultiArgSelector + CXXDeductionGuideName = llvm::addEnumValues( + UncommonNameKindOffset, + detail::DeclarationNameExtra::CXXDeductionGuideName), + CXXLiteralOperatorName = llvm::addEnumValues( + UncommonNameKindOffset, + detail::DeclarationNameExtra::CXXLiteralOperatorName), + CXXUsingDirective = + llvm::addEnumValues(UncommonNameKindOffset, + detail::DeclarationNameExtra::CXXUsingDirective), + ObjCMultiArgSelector = + llvm::addEnumValues(UncommonNameKindOffset, + detail::DeclarationNameExtra::ObjCMultiArgSelector), }; private:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits