diff options
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 38 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms.cpp | 35 |
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" |