Author: majnemer Date: Tue Jun 10 23:55:08 2014 New Revision: 210637 URL: http://llvm.org/viewvc/llvm-project?rev=210637&view=rev Log: MS ABI: Mangle null pointer-to-member-functions compatibly
Summary: Previously, we would mangle nullptr pointer-to-member-functions in class templates with a mangling we invented because contemporary versions of MSVC would crash when trying to compile such code. However, VS "14" can successfully compile these sorts of template instantiations. This commit updates our mangling to be compatible with theirs. Reviewers: rnk Reviewed By: rnk Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4059 Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=210637&r1=210636&r2=210637&view=diff ============================================================================== --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Jun 10 23:55:08 2014 @@ -495,18 +495,9 @@ MicrosoftCXXNameMangler::mangleMemberFun // ::= $H? <name> <number> // ::= $I? <name> <number> <number> // ::= $J? <name> <number> <number> <number> - // ::= $0A@ MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel(); - // The null member function pointer is $0A@ in function templates and crashes - // MSVC when used in class templates, so we don't know what they really look - // like. - if (!MD) { - Out << "$0A@"; - return; - } - char Code = '\0'; switch (IM) { case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break; @@ -515,28 +506,38 @@ MicrosoftCXXNameMangler::mangleMemberFun case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break; } - Out << '$' << Code << '?'; - // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr // thunk. uint64_t NVOffset = 0; uint64_t VBTableOffset = 0; uint64_t VBPtrOffset = 0; - if (MD->isVirtual()) { - MicrosoftVTableContext *VTContext = - cast<MicrosoftVTableContext>(getASTContext().getVTableContext()); - const MicrosoftVTableContext::MethodVFTableLocation &ML = - VTContext->getMethodVFTableLocation(GlobalDecl(MD)); - mangleVirtualMemPtrThunk(MD, ML); - NVOffset = ML.VFPtrOffset.getQuantity(); - VBTableOffset = ML.VBTableIndex * 4; - if (ML.VBase) { - const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD); - VBPtrOffset = Layout.getVBPtrOffset().getQuantity(); + if (MD) { + Out << '$' << Code << '?'; + if (MD->isVirtual()) { + MicrosoftVTableContext *VTContext = + cast<MicrosoftVTableContext>(getASTContext().getVTableContext()); + const MicrosoftVTableContext::MethodVFTableLocation &ML = + VTContext->getMethodVFTableLocation(GlobalDecl(MD)); + mangleVirtualMemPtrThunk(MD, ML); + NVOffset = ML.VFPtrOffset.getQuantity(); + VBTableOffset = ML.VBTableIndex * 4; + if (ML.VBase) { + const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD); + VBPtrOffset = Layout.getVBPtrOffset().getQuantity(); + } + } else { + mangleName(MD); + mangleFunctionEncoding(MD); } } else { - mangleName(MD); - mangleFunctionEncoding(MD); + // Null single inheritance member functions are encoded as a simple nullptr. + if (IM == MSInheritanceAttr::Keyword_single_inheritance) { + Out << "$0A@"; + return; + } + if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance) + VBTableOffset = -1; + Out << '$' << Code; } if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM)) Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp?rev=210637&r1=210636&r2=210637&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp (original) +++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp Tue Jun 10 23:55:08 2014 @@ -1,5 +1,24 @@ // RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +template <typename T, int (T::*)() = nullptr> +struct J {}; + +struct __single_inheritance M; +J<M> m; +// CHECK-DAG: @"\01?m@@3U?$J@UM@@$0A@@@A" + +struct __multiple_inheritance N; +J<N> n; +// CHECK-DAG: @"\01?n@@3U?$J@UN@@$HA@@@A" + +struct __virtual_inheritance O; +J<O> o; +// CHECK-DAG: @"\01?o@@3U?$J@UO@@$IA@A@@@A" + +struct P; +J<P> p; +// CHECK-DAG: @"\01?p@@3U?$J@UP@@$JA@A@?0@@A" + #pragma pointers_to_members(full_generality, virtual_inheritance) struct S { _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
