diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 55169c410102..becafb66e520 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1129,6 +1129,10 @@ public: NestedNameSpecifier * getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS); + /// \brief Retrieves the default calling convention to use for + /// C++ instance methods. + CallingConv getDefaultMethodCallConv(); + /// \brief Retrieves the canonical representation of the given /// calling convention. CallingConv getCanonicalCallConv(CallingConv CC) { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b2451a2d867d..0f449835412e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5838,4 +5838,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { return true; } +CallingConv ASTContext::getDefaultMethodCallConv() { + // Pass through to the C++ ABI object + return ABI->getDefaultMethodCallConv(); +} + CXXABI::~CXXABI() {} diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index baa6ed3f8272..dd2f1cb1345f 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -72,7 +72,7 @@ private: void mangleType(const ArrayType *T, bool IsGlobal); void mangleExtraDimensions(QualType T); void mangleFunctionClass(const FunctionDecl *FD); - void mangleCallingConvention(const FunctionType *T); + void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false); void mangleThrowSpecification(const FunctionProtoType *T); }; @@ -803,7 +803,7 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, if (IsInstMethod) mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false); - mangleCallingConvention(T); + mangleCallingConvention(T, IsInstMethod); // ::= // ::= @ # structors (they have no declared return type) @@ -898,7 +898,8 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { } else Out << 'Y'; } -void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) { +void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T, + bool IsInstMethod) { // ::= A # __cdecl // ::= B # __export __cdecl // ::= C # __pascal @@ -914,7 +915,10 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) { // that keyword. (It didn't actually export them, it just made them so // that they could be in a DLL and somebody from another module could call // them.) - switch (T->getCallConv()) { + CallingConv CC = T->getCallConv(); + if (CC == CC_Default) + CC = IsInstMethod ? getASTContext().getDefaultMethodCallConv() : CC_C; + switch (CC) { case CC_Default: case CC_C: Out << 'A'; break; case CC_X86Pascal: Out << 'C'; break; diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 61f8a595fc4f..d8d75b7d0f0e 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s +// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s // CHECK: @"\01?a@@3HA" // CHECK: @"\01?b@N@@3HA" @@ -11,7 +11,7 @@ // CHECK: @"\01?i@@3PAY0BE@HA" // CHECK: @"\01?j@@3P6GHCE@ZA" // CHECK: @"\01?k@@3PTfoo@@DA" -// CHECK: @"\01?l@@3P8foo@@AAHH@ZA" +// CHECK: @"\01?l@@3P8foo@@AEHH@ZA" int a; @@ -46,10 +46,8 @@ enum quux { qthree }; -// NOTE: The calling convention is supposed to be __thiscall by default, -// but that needs to be fixed in Sema/AST. int foo::operator+(int a) {return a;} -// CHECK: @"\01??Hfoo@@QAAHH@Z" +// CHECK: @"\01??Hfoo@@QAEHH@Z" const short foo::d = 0; volatile long foo::e;