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@C@@QAEXXZ" +// CHECK: ret + +// Make sure that the definition uses the right calling convention: +// CHECK: define linkonce_odr x86_thiscallcc void @"\01?simple_method@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@C@@QAAXXZ" +// CHECK: ret + +// Make sure that the definition uses the right calling convention: +// CHECK: define linkonce_odr void @"\01?cdecl_method@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@C@@QAAXPBDZZ" +// CHECK: ret + +// Make sure that the definition uses the right calling convention: +// CHECK: define linkonce_odr void @"\01?vararg_method@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@C@@SAXXZ" +// CHECK: ret + +// Make sure that the definition uses the right calling convention: +// CHECK: define linkonce_odr void @"\01?static_method@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@XZ" +// CHECK: call x86_thiscallcc void @"\01??0Base@@QAE@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@XZ" +// CHECK: call x86_thiscallcc void @"\01??1Base@@QAE@XZ" +// CHECK: ret + +// Make sure that the Base destructor definition uses the right CC: +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Base@@QAE@XZ" + +// Make sure that the Base constructor definition uses the right CC: +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0Base@@QAE@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@XZ" +// CHECK: call x86_thiscallcc void @"\01??0S@@QAE@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@XZ" +// CHECK: call x86_thiscallcc void @"\01??1S@@QAE@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@XZ" +// CHECK: call x86_thiscallcc void @"\01??0A@@QAE@XZ" // CHECK: call i32 @atexit(void ()* [[FOO_DTOR:@"__dtor_.*foo@.*]]) // CHECK: ret void -// CHECK: define linkonce_odr void @"\01??0A@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??0A@@QAE@XZ" -// CHECK: define linkonce_odr void @"\01??1A@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ" // CHECK: define internal void [[FOO_DTOR]] -// CHECK: call void @"\01??1A@@QAE@XZ"{{.*}}foo +// CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo // CHECK: ret void // CHECK: define internal void @_GLOBAL__I_a() nounwind { _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits