r187753 - [ms-cxxabi] Properly mangle member pointers

David Majnemer david.majnemer at gmail.com
Mon Aug 5 15:43:06 PDT 2013


Author: majnemer
Date: Mon Aug  5 17:43:06 2013
New Revision: 187753

URL: http://llvm.org/viewvc/llvm-project?rev=187753&view=rev
Log:
[ms-cxxabi] Properly mangle member pointers

There were three things missing from the original implementation:

- We would omit the 'E' qualifier for members int 64-bit mode.
- We would not exmaine the qualifiers in 'IsMember' mode.
- We didn't generate the correct backref to the base class.

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=187753&r1=187752&r2=187753&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Mon Aug  5 17:43:06 2013
@@ -329,7 +329,11 @@ void MicrosoftCXXNameMangler::mangleVari
       mangleQualifiers(Ty.getQualifiers(), false);
   } else {
     mangleType(Ty, TL.getSourceRange(), QMM_Drop);
-    mangleQualifiers(Ty.getLocalQualifiers(), false);
+    mangleQualifiers(Ty.getLocalQualifiers(), Ty->isMemberPointerType());
+    // Member pointers are suffixed with a back reference to the member
+    // pointer's class name.
+    if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
+      mangleName(MPT->getClass()->getAsCXXRecordDecl());
   }
 }
 
@@ -978,6 +982,7 @@ void MicrosoftCXXNameMangler::mangleQual
   //         ::= 5 # not really based
   bool HasConst = Quals.hasConst(),
        HasVolatile = Quals.hasVolatile();
+
   if (!IsMember) {
     if (HasConst && HasVolatile) {
       Out << 'D';
@@ -989,6 +994,9 @@ void MicrosoftCXXNameMangler::mangleQual
       Out << 'A';
     }
   } else {
+    if (PointersAre64Bit)
+      Out << 'E';
+
     if (HasConst && HasVolatile) {
       Out << 'T';
     } else if (HasVolatile) {

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=187753&r1=187752&r2=187753&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Mon Aug  5 17:43:06 2013
@@ -13,8 +13,8 @@
 // CHECK: @"\01?h2@@3QBHB"
 // CHECK: @"\01?i@@3PAY0BE at HA"
 // CHECK: @"\01?j@@3P6GHCE at ZA"
-// CHECK: @"\01?k@@3PTfoo@@DA"
-// CHECK: @"\01?l@@3P8foo@@AEHH at ZA"
+// CHECK: @"\01?k@@3PTfoo@@DQ1@"
+// CHECK: @"\01?l@@3P8foo@@AEHH at ZQ1@"
 // CHECK: @"\01?color1@@3PANA"
 // CHECK: @"\01?color2@@3QBNB"
 // CHECK: @"\01?color3@@3QAY02$$CBNA"

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=187753&r1=187752&r2=187753&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Mon Aug  5 17:43:06 2013
@@ -50,22 +50,22 @@ int Multiple   ::*m_d_memptr;
 int Virtual    ::*v_d_memptr;
 int NonZeroVBPtr::*n_d_memptr;
 int Unspecified::*u_d_memptr;
-// CHECK: @"\01?s_d_memptr@@3PQSingle@@HA" = global i32 -1, align 4
-// CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HA" = global i32 0, align 4
-// CHECK: @"\01?m_d_memptr@@3PQMultiple@@HA" = global i32 -1, align 4
-// CHECK: @"\01?v_d_memptr@@3PQVirtual@@HA" = global { i32, i32 }
+// CHECK: @"\01?s_d_memptr@@3PQSingle@@HQ1@" = global i32 -1, align 4
+// CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HQ1@" = global i32 0, align 4
+// CHECK: @"\01?m_d_memptr@@3PQMultiple@@HQ1@" = global i32 -1, align 4
+// CHECK: @"\01?v_d_memptr@@3PQVirtual@@HQ1@" = global { i32, i32 }
 // CHECK:   { i32 0, i32 -1 }, align 4
-// CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HA" = global { i32, i32 }
+// CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HQ1@" = global { i32, i32 }
 // CHECK:   { i32 0, i32 -1 }, align 4
-// CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HA" = global { i32, i32, i32 }
+// CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HQ1@" = global { i32, i32, i32 }
 // CHECK:   { i32 0, i32 0, i32 -1 }, align 4
 
 void (Single  ::*s_f_memptr)();
 void (Multiple::*m_f_memptr)();
 void (Virtual ::*v_f_memptr)();
-// CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZA" = global i8* null, align 4
-// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZA" = global { i8*, i32 } zeroinitializer, align 4
-// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZA" = global { i8*, i32, i32 } zeroinitializer, align 4
+// CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZQ1@" = global i8* null, align 4
+// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 4
+// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 4
 
 // We can define Unspecified after locking in the inheritance model.
 struct Unspecified : Multiple, Virtual {
@@ -79,13 +79,13 @@ void (Single     ::*s_f_mp)() = &Single:
 void (Multiple   ::*m_f_mp)() = &B2::foo;
 void (Virtual    ::*v_f_mp)() = &Virtual::foo;
 void (Unspecified::*u_f_mp)() = &Unspecified::foo;
-// CHECK: @"\01?s_f_mp at Const@@3P8Single@@AEXXZA" =
+// CHECK: @"\01?s_f_mp at Const@@3P8Single@@AEXXZQ2@" =
 // CHECK:   global i8* bitcast ({{.*}} @"\01?foo at Single@@QAEXXZ" to i8*), align 4
-// CHECK: @"\01?m_f_mp at Const@@3P8Multiple@@AEXXZA" =
+// CHECK: @"\01?m_f_mp at Const@@3P8Multiple@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo at B2@@QAEXXZ" to i8*), i32 4 }, align 4
-// CHECK: @"\01?v_f_mp at Const@@3P8Virtual@@AEXXZA" =
+// CHECK: @"\01?v_f_mp at Const@@3P8Virtual@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo at Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4
-// CHECK: @"\01?u_f_mp at Const@@3P8Unspecified@@AEXXZA" =
+// CHECK: @"\01?u_f_mp at Const@@3P8Unspecified@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo at Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 4
 }
 
@@ -102,16 +102,16 @@ struct B { int b; };
 struct C : B, A { int c; };
 
 void (A::*ptr1)(void *) = (void (A::*)(void *)) &A::foo;
-// CHECK: @"\01?ptr1 at CastParam@@3P8A at 1@AEXPAX at ZA" =
+// CHECK: @"\01?ptr1 at CastParam@@3P8A at 1@AEXPAX at ZQ21@" =
 // CHECK:   global i8* bitcast (void ({{.*}})* @"\01?foo at A@CastParam@@QAEXPAU12@@Z" to i8*), align 4
 
 // Try a reinterpret_cast followed by a memptr conversion.
 void (C::*ptr2)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) &A::foo;
-// CHECK: @"\01?ptr2 at CastParam@@3P8C at 1@AEXPAX at ZA" =
+// CHECK: @"\01?ptr2 at CastParam@@3P8C at 1@AEXPAX at ZQ21@" =
 // CHECK:   global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo at A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 4
 
 void (C::*ptr3)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) (void (A::*)(A *)) 0;
-// CHECK: @"\01?ptr3 at CastParam@@3P8C at 1@AEXPAX at ZA" =
+// CHECK: @"\01?ptr3 at CastParam@@3P8C at 1@AEXPAX at ZQ21@" =
 // CHECK:   global { i8*, i32 } zeroinitializer, align 4
 
 struct D : C {
@@ -122,11 +122,11 @@ struct D : C {
 // Try a cast that changes the inheritance model.  Null for D is 0, but null for
 // C is -1.  We need the cast to long in order to hit the non-APValue path.
 int C::*ptr4 = (int C::*) (int D::*) (long D::*) 0;
-// CHECK: @"\01?ptr4 at CastParam@@3PQC at 1@HA" = global i32 -1, align 4
+// CHECK: @"\01?ptr4 at CastParam@@3PQC at 1@HQ21@" = global i32 -1, align 4
 
 // MSVC rejects this but we accept it.
 int C::*ptr5 = (int C::*) (long D::*) 0;
-// CHECK: @"\01?ptr5 at CastParam@@3PQC at 1@HA" = global i32 -1, align 4
+// CHECK: @"\01?ptr5 at CastParam@@3PQC at 1@HQ21@" = global i32 -1, align 4
 }
 
 struct UnspecWithVBPtr;





More information about the cfe-commits mailing list