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

Reply via email to