From 14ca0189987f3ca476d6aa4cd10357040c569a04 Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Sat, 1 Oct 2022 19:10:14 -0400 Subject: [PATCH 1/2] Fix classic COM errors on non-supported compilers Also, enable fast path for Clang and give friendlier errors to MSVC --- strings/base_meta.h | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/strings/base_meta.h b/strings/base_meta.h index f19e0513a..1dc257285 100644 --- a/strings/base_meta.h +++ b/strings/base_meta.h @@ -117,23 +117,40 @@ namespace winrt::impl static constexpr auto data{ category_signature, T>::data }; }; -#if defined(__clang__) template - struct classic_com_guid + struct classic_com_guid_error { -#if __has_declspec_attribute(uuid) && defined(WINRT_IMPL_IUNKNOWN_DEFINED) - static constexpr guid value{ __uuidof(T) }; +#ifdef __clang__ +#if !__has_declspec_attribute(uuid) + static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must compile with -fms-extensions."); +#endif +#endif + +#if defined(_MSC_VER) || defined(__clang__) +#ifndef WINRT_IMPL_IUNKNOWN_DEFINED + static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must include before including C++/WinRT headers."); +#endif #else - static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must compile with -fms-extensions and include before including C++/WinRT headers."); + static_assert(std::is_void_v /* dependent_false */, "Classic COM interfaces are not supported with this compiler."); #endif }; template - inline constexpr guid guid_v = classic_com_guid::value; +#ifdef WINRT_IMPL_IUNKNOWN_DEFINED +#ifdef __clang__ +#if __has_declspec_attribute(uuid) + inline constexpr guid guid_v{ __uuidof(T) }; #else - template + inline constexpr guid guid_v = classic_com_guid_error::value; +#endif // __has_declspec_attribute(uuid) +#elif defined(_MSC_VER) inline constexpr guid guid_v{ __uuidof(T) }; -#endif +#else + inline constexpr guid guid_v = classic_com_guid_error::value; +#endif // __clang__ +#else + inline constexpr guid guid_v = classic_com_guid_error::value; +#endif // WINRT_IMPL_IUNKNOWN_DEFINED template constexpr auto to_underlying_type(T const value) noexcept From 16ab08b8761ccd78853dfdf13c8a1de014c43edf Mon Sep 17 00:00:00 2001 From: Charles Milette Date: Thu, 6 Oct 2022 19:08:25 -0400 Subject: [PATCH 2/2] Bring back the ability to use guid_v when unknwn.h is included after winrt/base.h in MSVC --- strings/base_meta.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/strings/base_meta.h b/strings/base_meta.h index 1dc257285..0e800c49f 100644 --- a/strings/base_meta.h +++ b/strings/base_meta.h @@ -123,34 +123,28 @@ namespace winrt::impl #ifdef __clang__ #if !__has_declspec_attribute(uuid) static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must compile with -fms-extensions."); -#endif #endif -#if defined(_MSC_VER) || defined(__clang__) #ifndef WINRT_IMPL_IUNKNOWN_DEFINED static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must include before including C++/WinRT headers."); #endif -#else +#else // MSVC won't hit this struct, so we can safely assume everything that isn't Clang isn't supported static_assert(std::is_void_v /* dependent_false */, "Classic COM interfaces are not supported with this compiler."); #endif }; template -#ifdef WINRT_IMPL_IUNKNOWN_DEFINED #ifdef __clang__ -#if __has_declspec_attribute(uuid) +#if __has_declspec_attribute(uuid) && defined(WINRT_IMPL_IUNKNOWN_DEFINED) inline constexpr guid guid_v{ __uuidof(T) }; #else inline constexpr guid guid_v = classic_com_guid_error::value; -#endif // __has_declspec_attribute(uuid) +#endif #elif defined(_MSC_VER) inline constexpr guid guid_v{ __uuidof(T) }; #else inline constexpr guid guid_v = classic_com_guid_error::value; -#endif // __clang__ -#else - inline constexpr guid guid_v = classic_com_guid_error::value; -#endif // WINRT_IMPL_IUNKNOWN_DEFINED +#endif template constexpr auto to_underlying_type(T const value) noexcept