[cfe-commits] r160121 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/AST/CXXABI.h lib/AST/ItaniumCXXABI.cpp lib/AST/MicrosoftCXXABI.cpp lib/AST/MicrosoftMangle.cpp lib/CodeGen/CGCall.cpp test/CodeGenCXX/microsoft-abi-methods.cpp test/CodeGenCXX/microsoft-abi-static-initializers.cpp
Timur Iskhodzhanov
timurrrr at google.com
Thu Jul 12 02:50:55 PDT 2012
Author: timurrrr
Date: Thu Jul 12 04:50:54 2012
New Revision: 160121
URL: http://llvm.org/viewvc/llvm-project?rev=160121&view=rev
Log:
[Windows] Use thiscall as the default calling convention for class methods. PR12785
Added:
cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp (with props)
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/CXXABI.h
cfe/trunk/lib/AST/ItaniumCXXABI.cpp
cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
cfe/trunk/lib/AST/MicrosoftMangle.cpp
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Jul 12 04:50:54 2012
@@ -1501,15 +1501,11 @@
/// \brief Retrieves the default calling convention to use for
/// C++ instance methods.
- CallingConv getDefaultMethodCallConv();
+ CallingConv getDefaultCXXMethodCallConv(bool isVariadic);
/// \brief Retrieves the canonical representation of the given
/// calling convention.
- CallingConv getCanonicalCallConv(CallingConv CC) const {
- if (!LangOpts.MRTD && CC == CC_C)
- return CC_Default;
- return CC;
- }
+ CallingConv getCanonicalCallConv(CallingConv CC) const;
/// \brief Determines whether two calling conventions name the same
/// calling convention.
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Jul 12 04:50:54 2012
@@ -7098,9 +7098,15 @@
return true;
}
-CallingConv ASTContext::getDefaultMethodCallConv() {
+CallingConv ASTContext::getDefaultCXXMethodCallConv(bool isVariadic) {
// Pass through to the C++ ABI object
- return ABI->getDefaultMethodCallConv();
+ return ABI->getDefaultMethodCallConv(isVariadic);
+}
+
+CallingConv ASTContext::getCanonicalCallConv(CallingConv CC) const {
+ if (CC == CC_C && !LangOpts.MRTD && getTargetInfo().getCXXABI() != CXXABI_Microsoft)
+ return CC_Default;
+ return CC;
}
bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {
Modified: cfe/trunk/lib/AST/CXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CXXABI.h?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CXXABI.h (original)
+++ cfe/trunk/lib/AST/CXXABI.h Thu Jul 12 04:50:54 2012
@@ -32,7 +32,7 @@
virtual unsigned getMemberPointerSize(const MemberPointerType *MPT) const = 0;
/// Returns the default calling convention for C++ methods.
- virtual CallingConv getDefaultMethodCallConv() const = 0;
+ virtual CallingConv getDefaultMethodCallConv(bool isVariadic) const = 0;
// Returns whether the given class is nearly empty, with just virtual pointers
// and no data except possibly virtual bases.
Modified: cfe/trunk/lib/AST/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumCXXABI.cpp Thu Jul 12 04:50:54 2012
@@ -39,7 +39,7 @@
return 1;
}
- CallingConv getDefaultMethodCallConv() const {
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const {
return CC_C;
}
Modified: cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftCXXABI.cpp Thu Jul 12 04:50:54 2012
@@ -29,8 +29,8 @@
unsigned getMemberPointerSize(const MemberPointerType *MPT) const;
- CallingConv getDefaultMethodCallConv() const {
- if (Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const {
+ if (!isVariadic && Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
return CC_X86ThisCall;
else
return CC_C;
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Jul 12 04:50:54 2012
@@ -1159,8 +1159,16 @@
// that they could be in a DLL and somebody from another module could call
// them.)
CallingConv CC = T->getCallConv();
- if (CC == CC_Default)
- CC = IsInstMethod ? getASTContext().getDefaultMethodCallConv() : CC_C;
+ if (CC == CC_Default) {
+ if (IsInstMethod) {
+ const FunctionProtoType *FPT =
+ T->getCanonicalTypeUnqualified().getAs<FunctionProtoType>();
+ bool isVariadic = FPT->isVariadic();
+ CC = getASTContext().getDefaultCXXMethodCallConv(isVariadic);
+ } else {
+ CC = CC_C;
+ }
+ }
switch (CC) {
default:
llvm_unreachable("Unsupported CC for mangling");
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Jul 12 04:50:54 2012
@@ -105,8 +105,12 @@
/// Given the formal ext-info of a C++ instance method, adjust it
/// according to the C++ ABI in effect.
static void adjustCXXMethodInfo(CodeGenTypes &CGT,
- FunctionType::ExtInfo &extInfo) {
- // FIXME: thiscall on Microsoft
+ FunctionType::ExtInfo &extInfo,
+ bool isVariadic) {
+ if (extInfo.getCC() == CC_Default) {
+ CallingConv CC = CGT.getContext().getDefaultCXXMethodCallConv(isVariadic);
+ extInfo = extInfo.withCallingConv(CC);
+ }
}
/// Arrange the argument and result information for a free function (i.e.
@@ -115,7 +119,7 @@
SmallVectorImpl<CanQualType> &prefix,
CanQual<FunctionProtoType> FTP) {
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
- adjustCXXMethodInfo(CGT, extInfo);
+ adjustCXXMethodInfo(CGT, extInfo, FTP->isVariadic());
return arrangeLLVMFunctionInfo(CGT, prefix, FTP, extInfo);
}
@@ -202,7 +206,7 @@
argTypes.push_back(FTP->getArgType(i));
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
- adjustCXXMethodInfo(*this, extInfo);
+ adjustCXXMethodInfo(*this, extInfo, FTP->isVariadic());
return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required);
}
@@ -220,9 +224,10 @@
CanQual<FunctionProtoType> FTP = GetFormalType(D);
assert(FTP->getNumArgs() == 0 && "dtor with formal parameters");
+ assert(FTP->isVariadic() == 0 && "dtor with formal parameters");
FunctionType::ExtInfo extInfo = FTP->getExtInfo();
- adjustCXXMethodInfo(*this, extInfo);
+ adjustCXXMethodInfo(*this, extInfo, false);
return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo,
RequiredArgs::All);
}
@@ -354,7 +359,7 @@
argTypes.push_back(Context.getCanonicalParamType(i->Ty));
FunctionType::ExtInfo info = FPT->getExtInfo();
- adjustCXXMethodInfo(*this, info);
+ adjustCXXMethodInfo(*this, info, FPT->isVariadic());
return arrangeLLVMFunctionInfo(GetReturnType(FPT->getResultType()),
argTypes, info, required);
}
Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp?rev=160121&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp Thu Jul 12 04:50:54 2012
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+class C {
+ public:
+ void simple_method() {}
+
+ void __cdecl cdecl_method() {}
+
+ void vararg_method(const char *fmt, ...) {}
+
+ static void static_method() {}
+
+ int a;
+};
+
+void call_simple_method() {
+ C instance;
+
+ instance.simple_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call x86_thiscallcc void @"\01?simple_method at C@@QAEXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01?simple_method at C@@QAEXXZ"
+// CHECK: ret
+}
+
+void call_cdecl_method() {
+ C instance;
+ instance.cdecl_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call void @"\01?cdecl_method at C@@QAAXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr void @"\01?cdecl_method at C@@QAAXXZ"
+// CHECK: ret
+}
+
+void call_vararg_method() {
+ C instance;
+ instance.vararg_method("Hello");
+// Make sure that the call uses the right calling convention:
+// CHECK: call void (%class.C*, i8*, ...)* @"\01?vararg_method at C@@QAAXPBDZZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr void @"\01?vararg_method at C@@QAAXPBDZZ"
+}
+
+void call_static_method() {
+ C::static_method();
+// Make sure that the call uses the right calling convention:
+// CHECK: call void @"\01?static_method at C@@SAXXZ"
+// CHECK: ret
+
+// Make sure that the definition uses the right calling convention:
+// CHECK: define linkonce_odr void @"\01?static_method at C@@SAXXZ"
+}
+
+class Base {
+ public:
+ Base() {}
+ ~Base() {}
+};
+
+class Child: public Base { };
+
+void constructors() {
+ Child c;
+// Make sure that the Base constructor call in the Child constructor uses
+// the right calling convention:
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Child@@QAE at XZ"
+// CHECK: call x86_thiscallcc void @"\01??0Base@@QAE at XZ"
+// CHECK: ret
+
+// Make sure that the Base destructor call in the Child denstructor uses
+// the right calling convention:
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Child@@QAE at XZ"
+// CHECK: call x86_thiscallcc void @"\01??1Base@@QAE at XZ"
+// CHECK: ret
+
+// Make sure that the Base destructor definition uses the right CC:
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Base@@QAE at XZ"
+
+// Make sure that the Base constructor definition uses the right CC:
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Base@@QAE at XZ"
+}
Propchange: cfe/trunk/test/CodeGenCXX/microsoft-abi-methods.cpp
------------------------------------------------------------------------------
svn:eol-style = LF
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp?rev=160121&r1=160120&r2=160121&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp Thu Jul 12 04:50:54 2012
@@ -6,12 +6,12 @@
} s;
// CHECK: define internal void [[INIT_s:@.*global_var.*]] nounwind
-// CHECK: call void @"\01??0S@@QAE at XZ"
+// CHECK: call x86_thiscallcc void @"\01??0S@@QAE at XZ"
// CHECK: call i32 @atexit(void ()* @"__dtor_\01?s@@3US@@A")
// CHECK: ret void
// CHECK: define internal void @"__dtor_\01?s@@3US@@A"() nounwind {
-// CHECK: call void @"\01??1S@@QAE at XZ"
+// CHECK: call x86_thiscallcc void @"\01??1S@@QAE at XZ"
// CHECK: ret void
// Force WeakODRLinkage by using templates
@@ -34,16 +34,16 @@
}
// CHECK: define internal void [[INIT_foo:@.*global_var.*]] nounwind
-// CHECK: call void @"\01??0A@@QAE at XZ"
+// CHECK: call x86_thiscallcc void @"\01??0A@@QAE at XZ"
// CHECK: call i32 @atexit(void ()* [[FOO_DTOR:@"__dtor_.*foo at .*]])
// CHECK: ret void
-// CHECK: define linkonce_odr void @"\01??0A@@QAE at XZ"
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0A@@QAE at XZ"
-// CHECK: define linkonce_odr void @"\01??1A@@QAE at XZ"
+// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE at XZ"
// CHECK: define internal void [[FOO_DTOR]]
-// CHECK: call void @"\01??1A@@QAE at XZ"{{.*}}foo
+// CHECK: call x86_thiscallcc void @"\01??1A@@QAE at XZ"{{.*}}foo
// CHECK: ret void
// CHECK: define internal void @_GLOBAL__I_a() nounwind {
More information about the cfe-commits
mailing list