diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2013-08-05 22:43:06 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2013-08-05 22:43:06 +0000 |
| commit | 89594f373349c5749ec8cf89d93b363660bb1266 (patch) | |
| tree | 0708dc8d097c1d1600d254339fd2df2ce12fd8fe /clang | |
| parent | 0062f2edc096a69d312ab1ed6977f897bfedd5f5 (diff) | |
| download | bcm5719-llvm-89594f373349c5749ec8cf89d93b363660bb1266.tar.gz bcm5719-llvm-89594f373349c5749ec8cf89d93b363660bb1266.zip | |
[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.
llvm-svn: 187753
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 10 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/mangle-ms.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp | 36 |
3 files changed, 29 insertions, 21 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index fb3f87ad132..8d7b76db5e9 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -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) { diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 3f80e54f433..1002d5ddc9e 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -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" diff --git a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 4771fd4a5a9..ae41f3c391d 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -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; |

