]> granicus.if.org Git - clang/commitdiff
Mangle the vbptr offset into pointers to member functions
authorReid Kleckner <reid@kleckner.net>
Mon, 7 Apr 2014 18:07:03 +0000 (18:07 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 7 Apr 2014 18:07:03 +0000 (18:07 +0000)
This can actually be non-zero if you override a function from a virtual
base and you have forced the most_general pointer to member
representation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205727 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp [new file with mode: 0644]

index 061fc13c084847e5ebd872fdf85c20c61e844457..4bec8be7327890832cb358b8b702c66a422643bd 100644 (file)
@@ -470,6 +470,9 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
 
   mangleNumber(FieldOffset);
 
+  // The C++ standard doesn't allow base-to-derived member pointer conversions
+  // in template parameter contexts, so the vbptr offset of data member pointers
+  // is always zero.
   if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
     mangleNumber(0);
   if (MSInheritanceAttr::hasVBTableOffsetField(IM))
@@ -509,6 +512,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
   // thunk.
   uint64_t NVOffset = 0;
   uint64_t VBTableOffset = 0;
+  uint64_t VBPtrOffset = 0;
   if (MD->isVirtual()) {
     MicrosoftVTableContext *VTContext =
         cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
@@ -518,11 +522,8 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
     NVOffset = ML.VFPtrOffset.getQuantity();
     VBTableOffset = ML.VBTableIndex * 4;
     if (ML.VBase) {
-      DiagnosticsEngine &Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(
-          DiagnosticsEngine::Error,
-          "cannot mangle pointers to member functions from virtual bases");
-      Diags.Report(MD->getLocation(), DiagID);
+      const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
+      VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
     }
   } else {
     mangleName(MD);
@@ -532,7 +533,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
   if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
     mangleNumber(NVOffset);
   if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
-    mangleNumber(0);
+    mangleNumber(VBPtrOffset);
   if (MSInheritanceAttr::hasVBTableOffsetField(IM))
     mangleNumber(VBTableOffset);
 }
diff --git a/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp b/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
new file mode 100644 (file)
index 0000000..993199a
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+
+struct S {
+  int a, b;
+  void f();
+  virtual void g();
+};
+
+struct GeneralBase {
+  virtual void h();
+};
+struct MostGeneral : S, virtual GeneralBase {
+  virtual void h();
+};
+template <void (MostGeneral::*MP)()>
+struct ClassTemplate {
+  ClassTemplate() {}
+};
+
+template struct ClassTemplate<&MostGeneral::h>;
+
+// Test that we mangle in the vbptr offset, which is 12 here.
+//
+// CHECK: define weak_odr x86_thiscallcc %struct.ClassTemplate* @"\01??0?$ClassTemplate@$J??_9MostGeneral@@$BA@AEA@M@3@@QAE@XZ"