commit dd464574836354941b4404a501e1ed03d0ec0690
Author: Timur Iskhodzhanov <timurrrr@google.com>
Date:   Fri May 11 13:16:31 2012 +0400

    Fix? http://llvm.org/bugs/show_bug.cgi?id=12785 (thiscall)

diff --git lib/CodeGen/CGCall.cpp lib/CodeGen/CGCall.cpp
index 3ad1df1..fbc1e4c 100644
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -84,14 +84,19 @@ CodeGenTypes::arrangeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
 /// stored.
 static const CGFunctionInfo &arrangeFunctionType(CodeGenTypes &CGT,
                                   SmallVectorImpl<CanQualType> &argTypes,
-                                             CanQual<FunctionProtoType> FTP) {
+                                             CanQual<FunctionProtoType> FTP,
+                                             CallingConv overrideDefaultCC = CC_Default) {
   RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size());
   // FIXME: Kill copy.
   for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
     argTypes.push_back(FTP->getArgType(i));
   CanQualType resultType = FTP->getResultType().getUnqualifiedType();
-  return CGT.arrangeFunctionType(resultType, argTypes,
-                                 FTP->getExtInfo(), required);
+
+  FunctionType::ExtInfo ext_info = FTP->getExtInfo();
+  if (overrideDefaultCC != CC_Default && ext_info.getCC() == CC_Default) {
+    ext_info = ext_info.withCallingConv(overrideDefaultCC);
+  }
+  return CGT.arrangeFunctionType(resultType, argTypes, ext_info, required);
 }
 
 /// Arrange the argument and result information for a value of the
@@ -135,7 +140,8 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
   argTypes.push_back(GetThisType(Context, RD));
 
   return ::arrangeFunctionType(*this, argTypes,
-              FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
+              FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>(),
+              Context.getDefaultMethodCallConv());
 }
 
 /// Arrange the argument and result information for a declaration or
diff --git lib/CodeGen/CGExprCXX.cpp lib/CodeGen/CGExprCXX.cpp
index dc318be..148ed9f 100644
--- lib/CodeGen/CGExprCXX.cpp
+++ lib/CodeGen/CGExprCXX.cpp
@@ -50,8 +50,15 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD,
   // And the rest of the call args.
   EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
 
+
+  CallingConv overrideDefaultCC = getContext().getDefaultMethodCallConv();
+  FunctionType::ExtInfo ext_info = FPT->getExtInfo();
+  if (overrideDefaultCC != CC_Default && ext_info.getCC() == CC_Default) {
+    ext_info = ext_info.withCallingConv(overrideDefaultCC);
+  }
+
   return EmitCall(CGM.getTypes().arrangeFunctionCall(FPT->getResultType(), Args,
-                                                     FPT->getExtInfo(),
+                                                     ext_info,
                                                      required),
                   Callee, ReturnValue, Args, MD);
 }
diff --git test/CodeGenCXX/microsoft-abi-thiscall.cpp test/CodeGenCXX/microsoft-abi-thiscall.cpp
new file mode 100644
index 0000000..cdc6cbd
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-thiscall.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+class C {
+ public:
+  void foo() {}
+};
+
+void thiscall() {
+  C instance;
+  instance.foo();
+
+// Make sure that the call uses the right calling convention:
+// CHECK: call x86_thiscallcc void @"\01?foo@C@@QAEXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define {{.*}} x86_thiscallcc {{.*}} @"\01?foo@C@@QAEXXZ"
+// CHECK: ret
+}
