Skip to content

Commit 6a729c6

Browse files
committedJun 11, 2014
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 llvm-svn: 210637
1 parent ace0080 commit 6a729c6

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed
 

‎clang/lib/AST/MicrosoftMangle.cpp

+25-24
Original file line numberDiff line numberDiff line change
@@ -495,18 +495,9 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
495495
// ::= $H? <name> <number>
496496
// ::= $I? <name> <number> <number>
497497
// ::= $J? <name> <number> <number> <number>
498-
// ::= $0A@
499498

500499
MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
501500

502-
// The null member function pointer is $0A@ in function templates and crashes
503-
// MSVC when used in class templates, so we don't know what they really look
504-
// like.
505-
if (!MD) {
506-
Out << "$0A@";
507-
return;
508-
}
509-
510501
char Code = '\0';
511502
switch (IM) {
512503
case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break;
@@ -515,28 +506,38 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
515506
case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
516507
}
517508

518-
Out << '$' << Code << '?';
519-
520509
// If non-virtual, mangle the name. If virtual, mangle as a virtual memptr
521510
// thunk.
522511
uint64_t NVOffset = 0;
523512
uint64_t VBTableOffset = 0;
524513
uint64_t VBPtrOffset = 0;
525-
if (MD->isVirtual()) {
526-
MicrosoftVTableContext *VTContext =
527-
cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
528-
const MicrosoftVTableContext::MethodVFTableLocation &ML =
529-
VTContext->getMethodVFTableLocation(GlobalDecl(MD));
530-
mangleVirtualMemPtrThunk(MD, ML);
531-
NVOffset = ML.VFPtrOffset.getQuantity();
532-
VBTableOffset = ML.VBTableIndex * 4;
533-
if (ML.VBase) {
534-
const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
535-
VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
514+
if (MD) {
515+
Out << '$' << Code << '?';
516+
if (MD->isVirtual()) {
517+
MicrosoftVTableContext *VTContext =
518+
cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
519+
const MicrosoftVTableContext::MethodVFTableLocation &ML =
520+
VTContext->getMethodVFTableLocation(GlobalDecl(MD));
521+
mangleVirtualMemPtrThunk(MD, ML);
522+
NVOffset = ML.VFPtrOffset.getQuantity();
523+
VBTableOffset = ML.VBTableIndex * 4;
524+
if (ML.VBase) {
525+
const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
526+
VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
527+
}
528+
} else {
529+
mangleName(MD);
530+
mangleFunctionEncoding(MD);
536531
}
537532
} else {
538-
mangleName(MD);
539-
mangleFunctionEncoding(MD);
533+
// Null single inheritance member functions are encoded as a simple nullptr.
534+
if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
535+
Out << "$0A@";
536+
return;
537+
}
538+
if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
539+
VBTableOffset = -1;
540+
Out << '$' << Code;
540541
}
541542

542543
if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))

‎clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
// RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
22

3+
template <typename T, int (T::*)() = nullptr>
4+
struct J {};
5+
6+
struct __single_inheritance M;
7+
J<M> m;
8+
// CHECK-DAG: @"\01?m@@3U?$J@UM@@$0A@@@A"
9+
10+
struct __multiple_inheritance N;
11+
J<N> n;
12+
// CHECK-DAG: @"\01?n@@3U?$J@UN@@$HA@@@A"
13+
14+
struct __virtual_inheritance O;
15+
J<O> o;
16+
// CHECK-DAG: @"\01?o@@3U?$J@UO@@$IA@A@@@A"
17+
18+
struct P;
19+
J<P> p;
20+
// CHECK-DAG: @"\01?p@@3U?$J@UP@@$JA@A@?0@@A"
21+
322
#pragma pointers_to_members(full_generality, virtual_inheritance)
423

524
struct S {

0 commit comments

Comments
 (0)
Please sign in to comment.