#include <iostream>
#include <type_traits>
struct cdecl_tag { typedef void ( __attribute__((cdecl)) *type)(); };
struct stdcall_tag { typedef void ( __attribute__((stdcall)) *type)(); };
struct fastcall_tag { typedef void ( __attribute__((fastcall)) *type)(); };
constexpr void get_func_calling_convention_tag () {};
template<typename R, typename... Args>
constexpr cdecl_tag
get_func_calling_convention_tag (R (__attribute__((cdecl)) *)(Args...))
{ return {}; }
template<typename R, typename... Args>
constexpr stdcall_tag
get_func_calling_convention_tag (R (__attribute__((stdcall)) *)(Args...))
{ return {}; }
template<typename R, typename... Args>
constexpr fastcall_tag
get_func_calling_convention_tag (R (__attribute__((fastcall)) *)(Args...))
{ return {}; }
#define CALLING_CONVENTION_TAG(func) \
decltype(get_func_calling_convention_tag(&func))
int __attribute__((cdecl)) foo (char) { return 0; }
long __attribute__((stdcall)) bar (int) { return 0; }
int main()
{
std::cout << std::is_same<CALLING_CONVENTION_TAG(foo),
cdecl_tag>::value << '\n'
<< std::is_same<CALLING_CONVENTION_TAG(bar),
stdcall_tag>::value << '\n'
<< std::is_same<CALLING_CONVENTION_TAG(foo),
CALLING_CONVENTION_TAG(bar)>::value << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgY2RlY2xfdGFnICAgIHsgdHlwZWRlZiB2b2lkICggX19hdHRyaWJ1dGVfXygoY2RlY2wpKSAgICAqdHlwZSkoKTsgfTsKc3RydWN0IHN0ZGNhbGxfdGFnICB7IHR5cGVkZWYgdm9pZCAoIF9fYXR0cmlidXRlX18oKHN0ZGNhbGwpKSAgKnR5cGUpKCk7IH07CnN0cnVjdCBmYXN0Y2FsbF90YWcgeyB0eXBlZGVmIHZvaWQgKCBfX2F0dHJpYnV0ZV9fKChmYXN0Y2FsbCkpICp0eXBlKSgpOyB9OwoKY29uc3RleHByIHZvaWQgZ2V0X2Z1bmNfY2FsbGluZ19jb252ZW50aW9uX3RhZyAoKSB7fTsKCnRlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEFyZ3M+CmNvbnN0ZXhwciBjZGVjbF90YWcKZ2V0X2Z1bmNfY2FsbGluZ19jb252ZW50aW9uX3RhZyAoUiAoX19hdHRyaWJ1dGVfXygoY2RlY2wpKSAqKShBcmdzLi4uKSkKeyByZXR1cm4ge307IH0KCnRlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEFyZ3M+CmNvbnN0ZXhwciBzdGRjYWxsX3RhZwpnZXRfZnVuY19jYWxsaW5nX2NvbnZlbnRpb25fdGFnIChSIChfX2F0dHJpYnV0ZV9fKChzdGRjYWxsKSkgKikoQXJncy4uLikpCnsgcmV0dXJuIHt9OyB9Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBSLCB0eXBlbmFtZS4uLiBBcmdzPgpjb25zdGV4cHIgZmFzdGNhbGxfdGFnCmdldF9mdW5jX2NhbGxpbmdfY29udmVudGlvbl90YWcgKFIgKF9fYXR0cmlidXRlX18oKGZhc3RjYWxsKSkgKikoQXJncy4uLikpCnsgcmV0dXJuIHt9OyB9CgojZGVmaW5lIENBTExJTkdfQ09OVkVOVElPTl9UQUcoZnVuYykgXApkZWNsdHlwZShnZXRfZnVuY19jYWxsaW5nX2NvbnZlbnRpb25fdGFnKCZmdW5jKSkKCmludCAgX19hdHRyaWJ1dGVfXygoY2RlY2wpKSAgIGZvbyAoY2hhcikgeyByZXR1cm4gMDsgfQpsb25nIF9fYXR0cmlidXRlX18oKHN0ZGNhbGwpKSBiYXIgKGludCkgIHsgcmV0dXJuIDA7IH0KCmludCBtYWluKCkKewoJc3RkOjpjb3V0IDw8IHN0ZDo6aXNfc2FtZTxDQUxMSU5HX0NPTlZFTlRJT05fVEFHKGZvbyksCgkgICAgICAgICAgICAgICAgICAgICAgICAgIGNkZWNsX3RhZz46OnZhbHVlICAgICAgICAgICAgICAgICAgIDw8ICdcbicKCSAgICAgICAgICA8PCBzdGQ6OmlzX3NhbWU8Q0FMTElOR19DT05WRU5USU9OX1RBRyhiYXIpLAoJICAgICAgICAgICAgICAgICAgICAgICAgICBzdGRjYWxsX3RhZz46OnZhbHVlICAgICAgICAgICAgICAgICA8PCAnXG4nCgkgICAgICAgICAgPDwgc3RkOjppc19zYW1lPENBTExJTkdfQ09OVkVOVElPTl9UQUcoZm9vKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgIENBTExJTkdfQ09OVkVOVElPTl9UQUcoYmFyKT46OnZhbHVlIDw8IHN0ZDo6ZW5kbDsKCQoJcmV0dXJuIDA7Cn0=