forked from OSchip/llvm-project
[-cxx-abi microsoft] Mangle member pointers better
Summary: There were several things going wrong: - We mangled in useless qualifiers like "volatile void" return types. - We didn't propagate 64-bit pointer markers sufficiently. - We mangled qualifiers belonging to the pointee incorrectly. This fixes PR16844 and PR16848. Reviewers: rnk, whunt Reviewed By: rnk CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1353 llvm-svn: 188450
This commit is contained in:
parent
2ffd06528d
commit
6dda7bb08d
|
@ -318,9 +318,18 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
|
|||
// mangled as 'QAHA' instead of 'PAHB', for example.
|
||||
TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
|
||||
QualType Ty = TL.getType();
|
||||
if (Ty->isPointerType() || Ty->isReferenceType()) {
|
||||
if (Ty->isPointerType() || Ty->isReferenceType() ||
|
||||
Ty->isMemberPointerType()) {
|
||||
mangleType(Ty, TL.getSourceRange(), QMM_Drop);
|
||||
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
|
||||
if (PointersAre64Bit)
|
||||
Out << 'E';
|
||||
if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
|
||||
mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
|
||||
// Member pointers are suffixed with a back reference to the member
|
||||
// pointer's class name.
|
||||
mangleName(MPT->getClass()->getAsCXXRecordDecl());
|
||||
} else
|
||||
mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
|
||||
} else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
|
||||
// Global arrays are funny, too.
|
||||
mangleDecayedArrayType(AT, true);
|
||||
|
@ -330,11 +339,7 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
|
|||
mangleQualifiers(Ty.getQualifiers(), false);
|
||||
} else {
|
||||
mangleType(Ty, TL.getSourceRange(), QMM_Drop);
|
||||
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());
|
||||
mangleQualifiers(Ty.getLocalQualifiers(), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1024,9 +1029,6 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
|
|||
Out << 'A';
|
||||
}
|
||||
} else {
|
||||
if (PointersAre64Bit)
|
||||
Out << 'E';
|
||||
|
||||
if (HasConst && HasVolatile) {
|
||||
Out << 'T';
|
||||
} else if (HasVolatile) {
|
||||
|
@ -1275,8 +1277,11 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
|
|||
|
||||
// If this is a C++ instance method, mangle the CVR qualifiers for the
|
||||
// this pointer.
|
||||
if (IsInstMethod)
|
||||
if (IsInstMethod) {
|
||||
if (PointersAre64Bit)
|
||||
Out << 'E';
|
||||
mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
|
||||
}
|
||||
|
||||
mangleCallingConvention(T, IsInstMethod);
|
||||
|
||||
|
@ -1294,7 +1299,10 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
|
|||
}
|
||||
Out << '@';
|
||||
} else {
|
||||
mangleType(Proto->getResultType(), Range, QMM_Result);
|
||||
QualType ResultType = Proto->getResultType();
|
||||
if (ResultType->isVoidType())
|
||||
ResultType = ResultType.getUnqualifiedType();
|
||||
mangleType(ResultType, Range, QMM_Result);
|
||||
}
|
||||
|
||||
// <argument-list> ::= X # void
|
||||
|
@ -1376,8 +1384,6 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
|
|||
else
|
||||
Out << 'Q';
|
||||
}
|
||||
if (PointersAre64Bit && !MD->isStatic())
|
||||
Out << 'E';
|
||||
} else
|
||||
Out << 'Y';
|
||||
}
|
||||
|
@ -1565,6 +1571,8 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
|
|||
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
|
||||
mangleFunctionType(FPT, NULL, false, true);
|
||||
} else {
|
||||
if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
|
||||
Out << 'E';
|
||||
mangleQualifiers(PointeeType.getQualifiers(), true);
|
||||
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
|
||||
mangleType(PointeeType, Range, QMM_Drop);
|
||||
|
@ -1604,6 +1612,8 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
|
|||
SourceRange Range) {
|
||||
// Object pointers never have qualifiers.
|
||||
Out << 'A';
|
||||
if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
|
||||
Out << 'E';
|
||||
mangleType(T->getPointeeType(), Range);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,27 @@
|
|||
// CHECK: @"\01?h2@@3QBHB"
|
||||
// CHECK: @"\01?i@@3PAY0BE@HA"
|
||||
// CHECK: @"\01?j@@3P6GHCE@ZA"
|
||||
// CHECK: @"\01?k@@3PTfoo@@DQ1@"
|
||||
// X64: @"\01?k@@3PETfoo@@DET1@"
|
||||
// CHECK: @"\01?l@@3P8foo@@AEHH@ZQ1@"
|
||||
// CHECK: @"\01?color1@@3PANA"
|
||||
// CHECK: @"\01?color2@@3QBNB"
|
||||
// CHECK: @"\01?color3@@3QAY02$$CBNA"
|
||||
// CHECK: @"\01?color4@@3QAY02$$CBNA"
|
||||
// X64: @"\01?memptr1@@3RESB@@HES1@"
|
||||
// X64: @"\01?memptr2@@3PESB@@HES1@"
|
||||
// X64: @"\01?memptr3@@3REQB@@HEQ1@"
|
||||
// X64: @"\01?funmemptr1@@3RESB@@R6AHXZES1@"
|
||||
// X64: @"\01?funmemptr2@@3PESB@@R6AHXZES1@"
|
||||
// X64: @"\01?funmemptr3@@3REQB@@P6AHXZEQ1@"
|
||||
// X64: @"\01?memptrtofun1@@3R8B@@EAAXXZEQ1@"
|
||||
// X64: @"\01?memptrtofun2@@3P8B@@EAAXXZEQ1@"
|
||||
// X64: @"\01?memptrtofun3@@3P8B@@EAAXXZEQ1@"
|
||||
// X64: @"\01?memptrtofun4@@3R8B@@EAAHXZEQ1@"
|
||||
// X64: @"\01?memptrtofun5@@3P8B@@EAA?CHXZEQ1@"
|
||||
// X64: @"\01?memptrtofun6@@3P8B@@EAA?BHXZEQ1@"
|
||||
// X64: @"\01?memptrtofun7@@3R8B@@EAAP6AHXZXZEQ1@"
|
||||
// X64: @"\01?memptrtofun8@@3P8B@@EAAR6AHXZXZEQ1@"
|
||||
// X64: @"\01?memptrtofun9@@3P8B@@EAAQ6AHXZXZEQ1@"
|
||||
|
||||
int a;
|
||||
|
||||
|
@ -180,6 +195,24 @@ extern const RGB color2 = {};
|
|||
extern RGB const color3[5] = {};
|
||||
extern RGB const ((color4)[5]) = {};
|
||||
|
||||
struct B;
|
||||
volatile int B::* volatile memptr1;
|
||||
volatile int B::* memptr2;
|
||||
int B::* volatile memptr3;
|
||||
typedef int (*fun)();
|
||||
volatile fun B::* volatile funmemptr1;
|
||||
volatile fun B::* funmemptr2;
|
||||
fun B::* volatile funmemptr3;
|
||||
void (B::* volatile memptrtofun1)();
|
||||
const void (B::* memptrtofun2)();
|
||||
volatile void (B::* memptrtofun3)();
|
||||
int (B::* volatile memptrtofun4)();
|
||||
volatile int (B::* memptrtofun5)();
|
||||
const int (B::* memptrtofun6)();
|
||||
fun (B::* volatile memptrtofun7)();
|
||||
volatile fun (B::* memptrtofun8)();
|
||||
const fun (B::* memptrtofun9)();
|
||||
|
||||
// PR12603
|
||||
enum E {};
|
||||
// CHECK: "\01?fooE@@YA?AW4E@@XZ"
|
||||
|
|
Loading…
Reference in New Issue