diff options
author | David Majnemer <david.majnemer@gmail.com> | 2017-02-14 00:54:11 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2017-02-14 00:54:11 +0000 |
commit | dc169759ca2a72d6fe9eff0b9320ad4296e3791a (patch) | |
tree | 3a9f780d3c0d21e76f12eca8b70d027ce9c1b2ae /clang/lib/AST/MicrosoftMangle.cpp | |
parent | d96089b2487448af11ecdaba8371f08d9b2381a2 (diff) |
[MS ABI] Correctly mangling vbase destructors
They are a little bit of a special case in the mangling. They are always
mangled without taking into account their virtual-ness of the
destructor. They are also mangled to return void, unlike the actual
destructor.
This fixes PR31931.
Differential Revision: https://reviews.llvm.org/D29912
llvm-svn: 295010
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 07e38eb7bbac..ef0512fd444a 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1890,14 +1890,18 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, // <return-type> ::= <type> // ::= @ # structors (they have no declared return type) if (IsStructor) { - if (isa<CXXDestructorDecl>(D) && isStructorDecl(D) && - StructorType == Dtor_Deleting) { - // The scalar deleting destructor takes an extra int argument. - // However, the FunctionType generated has 0 arguments. - // FIXME: This is a temporary hack. - // Maybe should fix the FunctionType creation instead? - Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z"); - return; + if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) { + // The scalar deleting destructor takes an extra int argument which is not + // reflected in the AST. + if (StructorType == Dtor_Deleting) { + Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z"); + return; + } + // The vbase destructor returns void which is not reflected in the AST. + if (StructorType == Dtor_Complete) { + Out << "XXZ"; + return; + } } if (IsCtorClosure) { // Default constructor closure and copy constructor closure both return @@ -2005,13 +2009,20 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { // <global-function> ::= Y # global near // ::= Z # global far if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { + bool IsVirtual = MD->isVirtual(); + // When mangling vbase destructor variants, ignore whether or not the + // underlying destructor was defined to be virtual. + if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) && + StructorType == Dtor_Complete) { + IsVirtual = false; + } switch (MD->getAccess()) { case AS_none: llvm_unreachable("Unsupported access specifier"); case AS_private: if (MD->isStatic()) Out << 'C'; - else if (MD->isVirtual()) + else if (IsVirtual) Out << 'E'; else Out << 'A'; @@ -2019,7 +2030,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { case AS_protected: if (MD->isStatic()) Out << 'K'; - else if (MD->isVirtual()) + else if (IsVirtual) Out << 'M'; else Out << 'I'; @@ -2027,7 +2038,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { case AS_public: if (MD->isStatic()) Out << 'S'; - else if (MD->isVirtual()) + else if (IsVirtual) Out << 'U'; else Out << 'Q'; |