summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp38
-rw-r--r--clang/test/CodeGenCXX/mangle-ms.cpp35
2 files changed, 58 insertions, 15 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index ac18db0dff3..714f3fc5677 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -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);
}
diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp
index 1002d5ddc9e..8f8929919d9 100644
--- a/clang/test/CodeGenCXX/mangle-ms.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms.cpp
@@ -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"
OpenPOWER on IntegriCloud