From 72e36c958e6dfdd216a0ecbcad1ee24f24813da0 Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Fri, 21 Oct 2022 21:13:52 +0800 Subject: [PATCH 1/2] Enable classic COM on mingw-w64 Mingw-w64 does not use `__declspec(uuid(x))` but has its own way of supporting `__uuidof` by defining UUIDs with a special macro `__CRT_UUID_DECL`, which does actually work here. --- strings/base_macros.h | 8 ++++++++ strings/base_meta.h | 16 +++------------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/strings/base_macros.h b/strings/base_macros.h index c4ec6645b..a7d757fad 100644 --- a/strings/base_macros.h +++ b/strings/base_macros.h @@ -59,6 +59,14 @@ #define WINRT_IMPL_NOVTABLE #endif +#if defined(__clang__) +#define WINRT_IMPL_HAS_DECLSPEC_UUID __has_declspec_attribute(uuid) +#elif defined(_MSC_VER) +#define WINRT_IMPL_HAS_DECLSPEC_UUID 1 +#else +#define WINRT_IMPL_HAS_DECLSPEC_UUID 0 +#endif + #ifdef __IUnknown_INTERFACE_DEFINED__ #define WINRT_IMPL_IUNKNOWN_DEFINED #else diff --git a/strings/base_meta.h b/strings/base_meta.h index 061a9f587..72c98c27a 100644 --- a/strings/base_meta.h +++ b/strings/base_meta.h @@ -120,27 +120,17 @@ namespace winrt::impl template struct classic_com_guid_error { -#ifdef __clang__ -#if !__has_declspec_attribute(uuid) +#if !defined(__MINGW32__) && defined(__clang__) && !WINRT_IMPL_HAS_DECLSPEC_UUID static_assert(std::is_void_v /* dependent_false */, "To use classic COM interfaces, you must compile with -fms-extensions."); -#endif - -#ifndef WINRT_IMPL_IUNKNOWN_DEFINED +#elif !defined(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 // 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 __clang__ -#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 -#elif defined(_MSC_VER) +#if defined(_MSC_VER) || ((WINRT_IMPL_HAS_DECLSPEC_UUID || defined(__MINGW32__)) && defined(WINRT_IMPL_IUNKNOWN_DEFINED)) inline constexpr guid guid_v{ __uuidof(T) }; #else inline constexpr guid guid_v = classic_com_guid_error::value; From 0c5d6e5ad6876db3d18a8f0f12ed7385d80cce4d Mon Sep 17 00:00:00 2001 From: Alvin Wong Date: Fri, 21 Oct 2022 21:40:37 +0800 Subject: [PATCH 2/2] Fix Clang-cl config --- strings/base_meta.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/base_meta.h b/strings/base_meta.h index 72c98c27a..54d41e61b 100644 --- a/strings/base_meta.h +++ b/strings/base_meta.h @@ -130,7 +130,7 @@ namespace winrt::impl }; template -#if defined(_MSC_VER) || ((WINRT_IMPL_HAS_DECLSPEC_UUID || defined(__MINGW32__)) && defined(WINRT_IMPL_IUNKNOWN_DEFINED)) +#if (defined(_MSC_VER) && !defined(__clang__)) || ((WINRT_IMPL_HAS_DECLSPEC_UUID || defined(__MINGW32__)) && defined(WINRT_IMPL_IUNKNOWN_DEFINED)) inline constexpr guid guid_v{ __uuidof(T) }; #else inline constexpr guid guid_v = classic_com_guid_error::value;