From 413d8cac1a6980a3fd26bf12da15e53521507b58 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 26 Feb 2015 19:43:46 +0000 Subject: [PATCH] Win64: Silently ignore __stdcall, __fastcall, and __thiscall MSVC doesn't warn on this. Users are expected to apply the WINAPI macro to functions passed by pointer to the Win32 API, and this macro expands to __stdcall. This means we end up with a lot of useless noisy warnings about ignored calling conventions when compiling code with clang for Win64. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230668 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/TargetInfo.h | 3 ++- lib/Basic/Targets.cpp | 20 ++++++++++++++++---- lib/Sema/SemaDeclAttr.cpp | 7 +++++-- test/Sema/MicrosoftCompatibility-x64.c | 13 +++++++++---- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index e00e0f5a58..bda132e499 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -842,7 +842,8 @@ public: enum CallingConvCheckResult { CCCR_OK, - CCCR_Warning + CCCR_Warning, + CCCR_Ignore, }; /// \brief Determines whether a given calling convention is valid for the diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 03cd853d66..a7c8413dd9 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -3626,19 +3626,31 @@ public: IntPtrType = SignedLongLong; this->UserLabelPrefix = ""; } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { WindowsTargetInfo::getTargetDefines(Opts, Builder); Builder.defineMacro("_WIN64"); } + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_C || - CC == CC_X86VectorCall || - CC == CC_IntelOclBicc || - CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning; + switch (CC) { + case CC_X86StdCall: + case CC_X86ThisCall: + case CC_X86FastCall: + return CCCR_Ignore; + case CC_C: + case CC_X86VectorCall: + case CC_IntelOclBicc: + case CC_X86_64SysV: + return CCCR_OK; + default: + return CCCR_Warning; + } } }; } // end anonymous namespace diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 7af4bd28d5..4552ad9609 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -3393,9 +3393,12 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, const TargetInfo &TI = Context.getTargetInfo(); TargetInfo::CallingConvCheckResult A = TI.checkCallingConvention(CC); - if (A == TargetInfo::CCCR_Warning) { - Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); + if (A != TargetInfo::CCCR_OK) { + if (A == TargetInfo::CCCR_Warning) + Diag(attr.getLoc(), diag::warn_cconv_ignored) << attr.getName(); + // This convention is not valid for the target. Use the default function or + // method calling convention. TargetInfo::CallingConvMethodType MT = TargetInfo::CCMT_Unknown; if (FD) MT = FD->isCXXInstanceMember() ? TargetInfo::CCMT_Member : diff --git a/test/Sema/MicrosoftCompatibility-x64.c b/test/Sema/MicrosoftCompatibility-x64.c index bf595af699..7d1f64996e 100644 --- a/test/Sema/MicrosoftCompatibility-x64.c +++ b/test/Sema/MicrosoftCompatibility-x64.c @@ -1,8 +1,13 @@ -// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-compatibility -triple x86_64-pc-win32 -int __stdcall f(void); /* expected-warning {{calling convention '__stdcall' ignored for this target}} */ +// RUN: %clang_cc1 %s -Wmicrosoft -verify -fms-compatibility -triple x86_64-pc-win32 -/* This should compile without warning because __stdcall is treated -as __cdecl in MS compatibility mode for x64 compiles*/ +// None of these should warn. stdcall is treated as equivalent to cdecl on +// x64. +// expected-no-diagnostics + +int __stdcall f(void); int __cdecl f(void) { return 0; } +int __stdcall func_std(void); +int __thiscall func_this(void); +int __fastcall func_fast(void); -- 2.40.0