]> granicus.if.org Git - clang/commitdiff
[ms-cxxabi] Properly mangle member pointers
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 5 Aug 2013 22:43:06 +0000 (22:43 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 5 Aug 2013 22:43:06 +0000 (22:43 +0000)
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.

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

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms.cpp
test/CodeGenCXX/microsoft-abi-member-pointers.cpp

index fb3f87ad132858439f864a516188c236058c2702..8d7b76db5e9fbac9587375c36c9b9859cc55ec85 100644 (file)
@@ -329,7 +329,11 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
       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::mangleQualifiers(Qualifiers Quals,
   //         ::= 5 # not really based
   bool HasConst = Quals.hasConst(),
        HasVolatile = Quals.hasVolatile();
+
   if (!IsMember) {
     if (HasConst && HasVolatile) {
       Out << 'D';
@@ -989,6 +994,9 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
       Out << 'A';
     }
   } else {
+    if (PointersAre64Bit)
+      Out << 'E';
+
     if (HasConst && HasVolatile) {
       Out << 'T';
     } else if (HasVolatile) {
index 3f80e54f4334da78a03a9f5179dd016c5d678ff3..1002d5ddc9ea768f495411cee388551c06575106 100644 (file)
@@ -13,8 +13,8 @@
 // CHECK: @"\01?h2@@3QBHB"
 // CHECK: @"\01?i@@3PAY0BE@HA"
 // CHECK: @"\01?j@@3P6GHCE@ZA"
-// CHECK: @"\01?k@@3PTfoo@@DA"
-// CHECK: @"\01?l@@3P8foo@@AEHH@ZA"
+// CHECK: @"\01?k@@3PTfoo@@DQ1@"
+// CHECK: @"\01?l@@3P8foo@@AEHH@ZQ1@"
 // CHECK: @"\01?color1@@3PANA"
 // CHECK: @"\01?color2@@3QBNB"
 // CHECK: @"\01?color3@@3QAY02$$CBNA"
index 4771fd4a5a99b55e25b92749795f7e90fe9d5ebd..ae41f3c391d7db5c0598c7bc76d74f4653190f10 100644 (file)
@@ -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::foo;
 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@Const@@3P8Single@@AEXXZA" =
+// CHECK: @"\01?s_f_mp@Const@@3P8Single@@AEXXZQ2@" =
 // CHECK:   global i8* bitcast ({{.*}} @"\01?foo@Single@@QAEXXZ" to i8*), align 4
-// CHECK: @"\01?m_f_mp@Const@@3P8Multiple@@AEXXZA" =
+// CHECK: @"\01?m_f_mp@Const@@3P8Multiple@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 4
-// CHECK: @"\01?v_f_mp@Const@@3P8Virtual@@AEXXZA" =
+// CHECK: @"\01?v_f_mp@Const@@3P8Virtual@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4
-// CHECK: @"\01?u_f_mp@Const@@3P8Unspecified@@AEXXZA" =
+// CHECK: @"\01?u_f_mp@Const@@3P8Unspecified@@AEXXZQ2@" =
 // CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@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@CastParam@@3P8A@1@AEXPAX@ZA" =
+// CHECK: @"\01?ptr1@CastParam@@3P8A@1@AEXPAX@ZQ21@" =
 // CHECK:   global i8* bitcast (void ({{.*}})* @"\01?foo@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@CastParam@@3P8C@1@AEXPAX@ZA" =
+// CHECK: @"\01?ptr2@CastParam@@3P8C@1@AEXPAX@ZQ21@" =
 // CHECK:   global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo@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@CastParam@@3P8C@1@AEXPAX@ZA" =
+// CHECK: @"\01?ptr3@CastParam@@3P8C@1@AEXPAX@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@CastParam@@3PQC@1@HA" = global i32 -1, align 4
+// CHECK: @"\01?ptr4@CastParam@@3PQC@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@CastParam@@3PQC@1@HA" = global i32 -1, align 4
+// CHECK: @"\01?ptr5@CastParam@@3PQC@1@HQ21@" = global i32 -1, align 4
 }
 
 struct UnspecWithVBPtr;