diff --git a/build.properties b/build.properties
index 8e2ff7d42fb..793e38b1392 100644
--- a/build.properties
+++ b/build.properties
@@ -104,12 +104,12 @@ jfx.gradle.version.min=8.5
# Toolchains
jfx.build.linux.gcc.version=gcc13.2.0-OL6.4+1.0
-jfx.build.windows.msvc.version=VS2022-17.6.5+1.0
+jfx.build.windows.msvc.version=VS2022-17.13.2+1.0
jfx.build.macosx.xcode.version=Xcode14.3.1+1.0
# Build tools
jfx.build.cmake.version=3.22.3
-jfx.build.clang.version=19.1.7
+jfx.build.clang.version=20.1.3
jfx.build.ninja.version=1.8.2
jfx.build.ant.version=1.10.5
diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml
index fb3d03aab7e..deeb07b75b3 100644
--- a/gradle/verification-metadata.xml
+++ b/gradle/verification-metadata.xml
@@ -120,9 +120,9 @@
-
-
-
+
+
+
@@ -135,9 +135,9 @@
-
-
-
+
+
+
diff --git a/modules/javafx.web/src/main/native/Source/WTF/wtf/EnumTraits.h b/modules/javafx.web/src/main/native/Source/WTF/wtf/EnumTraits.h
index f2757bc6969..604ceb3b10d 100644
--- a/modules/javafx.web/src/main/native/Source/WTF/wtf/EnumTraits.h
+++ b/modules/javafx.web/src/main/native/Source/WTF/wtf/EnumTraits.h
@@ -161,6 +161,16 @@ constexpr bool isZeroBasedContiguousEnum()
#pragma clang diagnostic ignored "-Wenum-constexpr-conversion"
#endif
+#if COMPILER(CLANG) && __clang_major__ >= 16
+template
+inline constexpr bool isEnumConstexprStaticCastValid = false;
+template
+inline constexpr bool isEnumConstexprStaticCastValid(V)>>> = true;
+#else
+template
+inline constexpr bool isEnumConstexprStaticCastValid = true;
+#endif
+
template
constexpr std::span enumTypeNameImpl()
{
@@ -224,6 +234,15 @@ constexpr std::span enumName()
return result;
}
+template
+constexpr std::span enumName()
+{
+ if constexpr (isEnumConstexprStaticCastValid)
+ return enumName(V)>();
+ else
+ return { };
+}
+
namespace detail {
template
@@ -237,17 +256,72 @@ constexpr void forConstexpr(const auto& func)
}
-template
-constexpr std::array, limit> enumNames()
+// template
+// constexpr std::array, limit> enumNames()
+// {
+// std::array, limit> names;
+
+// detail::forConstexpr<0, limit>([&] (auto i) {
+// names[i] = enumName(static_cast(i))>();
+// });
+// return names;
+// }
+template
+constexpr std::underlying_type_t enumNamesMin()
{
- std::array, limit> names;
+ using Underlying = std::underlying_type_t;
+
+ if constexpr (requires { EnumTraits::min; }) {
+ static_assert(std::is_same_v::min)>, Underlying>,
+ "EnumTraits::min must have the same type as the underlying type of the enum.");
+ return EnumTraits::min;
+ }
- detail::forConstexpr<0, limit>([&] (auto i) {
- names[i] = enumName(static_cast(i))>();
- });
- return names;
+ // Default for both signed and unsigned enums.
+ return 0;
}
+template
+constexpr std::underlying_type_t enumNamesMax()
+{
+ using Underlying = std::underlying_type_t;
+
+ if constexpr (requires { EnumTraits::max; }) {
+ static_assert(std::is_same_v::max)>, Underlying>,
+ "EnumTraits::max must have the same type as the underlying type of the enum.");
+ return EnumTraits::max;
+ }
+
+ constexpr Underlying defaultMax = std::is_signed_v
+ ? static_cast(INT8_MAX) : static_cast(UINT8_MAX);
+ constexpr Underlying computedMax = (sizeof(E) > 1) ? static_cast(defaultMax << 1) : defaultMax;
+ return computedMax;
+}
+
+template
+constexpr size_t enumNamesSize()
+{
+ constexpr auto min = enumNamesMin();
+ constexpr auto max = enumNamesMax();
+ static_assert(min <= max, "Invalid enum range: min must be <= max.");
+ return static_cast(max - min) + 1;
+}
+
+template
+constexpr auto makeEnumNames(std::index_sequence)
+{
+ constexpr auto min = enumNamesMin();
+ return std::array, sizeof...(Is)> {
+ enumName>(Is) + min>()...
+ };
+}
+
+template
+constexpr auto enumNames()
+{
+ constexpr size_t size = enumNamesSize();
+ return makeEnumNames(std::make_index_sequence { });
+}
template
constexpr std::span enumName(T v)