[cfe-commits] r162639 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CodeGenCXX/microsoft-abi-default-cc.cpp

John McCall rjmccall at apple.com
Fri Aug 24 19:00:03 PDT 2012


Author: rjmccall
Date: Fri Aug 24 21:00:03 2012
New Revision: 162639

URL: http://llvm.org/viewvc/llvm-project?rev=162639&view=rev
Log:
Fix the CC-matching logic for instance methods in the MS ABI.
Patch by Timur Iskhodzhanov!

Added:
    cfe/trunk/test/CodeGenCXX/microsoft-abi-default-cc.cpp
Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=162639&r1=162638&r2=162639&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Aug 24 21:00:03 2012
@@ -1920,6 +1920,19 @@
           FD->getStorageClass() == SC_Extern);
 }
 
+/// Is the given calling convention the ABI default for the given
+/// declaration?
+static bool isABIDefaultCC(Sema &S, CallingConv CC, FunctionDecl *D) {
+  CallingConv ABIDefaultCC;
+  if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) {
+    ABIDefaultCC = S.Context.getDefaultCXXMethodCallConv(D->isVariadic());
+  } else {
+    // Free C function or a static method.
+    ABIDefaultCC = (S.Context.getLangOpts().MRTD ? CC_X86StdCall : CC_C);
+  }
+  return ABIDefaultCC == CC;
+}
+
 /// MergeFunctionDecl - We just parsed a function 'New' from
 /// declarator D which has the same name and scope as a previous
 /// declaration 'Old'.  Figure out how to resolve this situation,
@@ -1988,6 +2001,9 @@
   // later declared or defined without one, the second decl assumes the
   // calling convention of the first.
   //
+  // It's OK if a function is first declared without a calling convention,
+  // but is later declared or defined with the default calling convention.
+  //
   // For the new decl, we have to look at the NON-canonical type to tell the
   // difference between a function that really doesn't have a calling
   // convention and one that is declared cdecl. That's because in
@@ -2001,10 +2017,22 @@
   FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo();
   FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo();
   bool RequiresAdjustment = false;
-  if (OldTypeInfo.getCC() != CC_Default &&
-      NewTypeInfo.getCC() == CC_Default) {
+  if (OldTypeInfo.getCC() == NewTypeInfo.getCC()) {
+    // Fast path: nothing to do.
+
+  // Inherit the CC from the previous declaration if it was specified
+  // there but not here.
+  } else if (NewTypeInfo.getCC() == CC_Default) {
     NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
     RequiresAdjustment = true;
+
+  // Don't complain about mismatches when the default CC is
+  // effectively the same as the explict one.
+  } else if (OldTypeInfo.getCC() == CC_Default &&
+             isABIDefaultCC(*this, NewTypeInfo.getCC(), New)) {
+    NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC());
+    RequiresAdjustment = true;
+
   } else if (!Context.isSameCallConv(OldTypeInfo.getCC(),
                                      NewTypeInfo.getCC())) {
     // Calling conventions really aren't compatible, so complain.

Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-default-cc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-default-cc.cpp?rev=162639&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-default-cc.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-default-cc.cpp Fri Aug 24 21:00:03 2012
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix GCABI %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -DMS_ABI -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck -check-prefix MSABI %s
+
+#ifdef MS_ABI
+# define METHOD_CC __thiscall
+#else
+# define METHOD_CC __attribute__ ((cdecl))
+#endif
+
+// Test that it's OK to have multiple function declarations with the default CC
+// both mentioned explicitly and implied.
+void foo();
+void __cdecl foo();
+void __cdecl foo() {}
+// GCABI: define void @_Z3foov()
+// MSABI: define void @"\01?foo@@YAXXZ"
+
+void __cdecl bar();
+void bar();
+void bar() {}
+// GCABI: define void @_Z3barv()
+// MSABI: define void @"\01?bar@@YAXXZ"
+
+// Test that it's OK to mark either the method declaration or method definition
+// with a default CC explicitly.
+class A {
+public:
+  void baz();
+  void METHOD_CC qux();
+
+  void static_baz();
+  void __cdecl static_qux();
+};
+
+void METHOD_CC A::baz() {}
+// GCABI: define void @_ZN1A3bazEv
+// MSABI: define x86_thiscallcc void @"\01?baz at A@@QAEXXZ"
+void A::qux() {}
+// GCABI: define void @_ZN1A3quxEv
+// MSABI: define x86_thiscallcc void @"\01?qux at A@@QAEXXZ"
+
+void __cdecl static_baz() {}
+// GCABI: define void @_Z10static_bazv
+// MSABI: define void @"\01?static_baz@@YAXXZ"
+void static_qux() {}
+// GCABI: define void @_Z10static_quxv
+// MSABI: define void @"\01?static_qux@@YAXXZ"





More information about the cfe-commits mailing list