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..54d41e61b 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) && !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;