eandrews created this revision. eandrews added reviewers: rnk, akhuang, dmajor. Herald added a subscriber: mstorsjo. eandrews requested review of this revision.
This patch is a second attempt at fixing a link error for MSVC entry points when calling conventions are specified using a flag. Calling conventions specified using flags should not be applied to MSVC entry points. The default calling convention is set in this case. The default calling convention for MSVC entry points main and wmain is __cdecl. For WinMain, wWinMain and DllMain, the default calling convention is __stdcall. Explicitly specified calling conventions are applied to MSVC entry points. For MinGW, the default calling convention for all MSVC entry points is __cdecl. First attempt: 4cff1b40dacf6 <https://reviews.llvm.org/rG4cff1b40dacf6a5489b09657d94ea4757b8cd3b0> (https://reviews.llvm.org/D87701) Revert of first attempt: bebfc3b92d5e8 <https://reviews.llvm.org/rGbebfc3b92d5e8dd1b1d75d40d5d03975957eec14> https://reviews.llvm.org/D97941 Files: clang/lib/Sema/SemaDecl.cpp clang/test/CodeGenCXX/default_calling_conv.cpp
Index: clang/test/CodeGenCXX/default_calling_conv.cpp =================================================================== --- clang/test/CodeGenCXX/default_calling_conv.cpp +++ clang/test/CodeGenCXX/default_calling_conv.cpp @@ -4,6 +4,8 @@ // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL +// RUN: %clang_cc1 -triple i386-pc-win32 -target-feature +sse4.2 -fdefault-calling-conv=fastcall -emit-llvm -o - %s -DWINDOWS | FileCheck %s --check-prefix=WINDOWS +// RUN: %clang_cc1 -triple i386-pc-win32 -target-feature +sse4.2 -emit-llvm -o - %s -DEXPLICITCC | FileCheck %s --check-prefix=EXPLICITCC // CDECL: define{{.*}} void @_Z5test1v // FASTCALL: define{{.*}} x86_fastcallcc void @_Z5test1v @@ -50,3 +52,41 @@ int main() { return 1; } + +#ifdef WINDOWS +// WINDOWS: define dso_local i32 @wmain +int wmain() { + return 1; +} +// WINDOWS: define dso_local x86_stdcallcc i32 @WinMain +int WinMain() { + return 1; +} +// WINDOWS: define dso_local x86_stdcallcc i32 @wWinMain +int wWinMain() { + return 1; +} +// WINDOWS: define dso_local x86_stdcallcc i32 @DllMain +int DllMain() { + return 1; +} +#endif // Windows + +#ifdef EXPLICITCC +// EXPLICITCC: define dso_local x86_fastcallcc i32 @wmain +int __fastcall wmain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @WinMain +int __fastcall WinMain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @wWinMain +int __fastcall wWinMain() { + return 1; +} +// EXPLICITCC: define dso_local x86_fastcallcc i32 @DllMain +int __fastcall DllMain() { + return 1; +} +#endif // ExplicitCC Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -11169,6 +11169,17 @@ } } +static bool isDefaultCDecl(FunctionDecl *FD, Sema &S) { + // Default calling convention for MinGW is __cdecl + const llvm::Triple &T = S.Context.getTargetInfo().getTriple(); + if (T.isWindowsGNUEnvironment()) + return true; + + return llvm::StringSwitch<bool>(FD->getName()) + .Cases("main", "wmain", true) + .Default(false); +} + void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) { QualType T = FD->getType(); assert(T->isFunctionType() && "function decl is not of function type"); @@ -11183,6 +11194,23 @@ if (FD->getName() != "DllMain") FD->setHasImplicitReturnZero(true); + // Explicity specified calling conventions are applied to MSVC entry points + if (!hasExplicitCallingConv(T)) { + if (isDefaultCDecl(FD, *this)) { + if (FT->getCallConv() != CC_C) { + FT = Context.adjustFunctionType(FT, + FT->getExtInfo().withCallingConv(CC_C)); + FD->setType(QualType(FT, 0)); + } + } else if (FT->getCallConv() != CC_X86StdCall) { + // Default calling convention for WinMain, wWinMain and DllMain is + // __stdcall + FT = Context.adjustFunctionType( + FT, FT->getExtInfo().withCallingConv(CC_X86StdCall)); + FD->setType(QualType(FT, 0)); + } + } + if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD; FD->setInvalidDecl();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits