r210637 - MS ABI: Mangle null pointer-to-member-functions compatibly

David Majnemer david.majnemer at gmail.com
Tue Jun 10 21:55:09 PDT 2014


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 at UM@@$0A@@@A"
+
+struct __multiple_inheritance N;
+J<N> n;
+// CHECK-DAG: @"\01?n@@3U?$J at UN@@$HA@@@A"
+
+struct __virtual_inheritance O;
+J<O> o;
+// CHECK-DAG: @"\01?o@@3U?$J at UO@@$IA at A@@@A"
+
+struct P;
+J<P> p;
+// CHECK-DAG: @"\01?p@@3U?$J at UP@@$JA at A@?0@@A"
+
 #pragma pointers_to_members(full_generality, virtual_inheritance)
 
 struct S {





More information about the cfe-commits mailing list