diff options
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 326b0d3e3d8..baa16b04ea8 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -28,12 +28,25 @@ using namespace clang; namespace { +static const FunctionDecl *getStructor(const FunctionDecl *fn) { + if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate()) + return ftd->getTemplatedDecl(); + + return fn; +} + /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the /// Microsoft Visual C++ ABI. class MicrosoftCXXNameMangler { MangleContext &Context; raw_ostream &Out; + /// The "structor" is the top-level declaration being mangled, if + /// that's not a template specialization; otherwise it's the pattern + /// for that specialization. + const NamedDecl *Structor; + unsigned StructorType; + // FIXME: audit the performance of BackRefMap as it might do way too many // copying of strings. typedef std::map<std::string, unsigned> BackRefMap; @@ -47,7 +60,15 @@ class MicrosoftCXXNameMangler { public: MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_) - : Context(C), Out(Out_), UseNameBackReferences(true) { } + : Context(C), Out(Out_), + Structor(0), StructorType(-1), + UseNameBackReferences(true) { } + + MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_, + const CXXDestructorDecl *D, CXXDtorType Type) + : Context(C), Out(Out_), + Structor(getStructor(D)), StructorType(Type), + UseNameBackReferences(true) { } raw_ostream &getStream() const { return Out; } @@ -68,6 +89,7 @@ private: void mangleSourceName(const IdentifierInfo *II); void manglePostfix(const DeclContext *DC, bool NoFunction=false); void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc); + void mangleCXXDtorType(CXXDtorType T); void mangleQualifiers(Qualifiers Quals, bool IsMember); void manglePointerQualifiers(Qualifiers Quals); @@ -485,7 +507,14 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; case DeclarationName::CXXDestructorName: - Out << "?1"; + if (ND == Structor) + // If the named decl is the C++ destructor we're mangling, + // use the type we were given. + mangleCXXDtorType(static_cast<CXXDtorType>(StructorType)); + else + // Otherwise, use the complete destructor name. This is relevant if a + // class with a destructor is declared within a destructor. + mangleCXXDtorType(Dtor_Complete); break; case DeclarationName::CXXConversionFunctionName: @@ -543,6 +572,23 @@ void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC, } } +void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) { + switch (T) { + case Dtor_Deleting: + Out << "?_G"; + return; + case Dtor_Base: + // FIXME: We should be asked to mangle base dtors. + // However, fixing this would require larger changes to the CodeGenModule. + // Please put llvm_unreachable here when CGM is changed. + // For now, just mangle a base dtor the same way as a complete dtor... + case Dtor_Complete: + Out << "?1"; + return; + } + llvm_unreachable("Unsupported dtor type?"); +} + void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc) { switch (OO) { @@ -1110,9 +1156,18 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, // <return-type> ::= <type> // ::= @ # structors (they have no declared return type) - if (IsStructor) + if (IsStructor) { + if (isa<CXXDestructorDecl>(D) && D == Structor && + 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 << "PAXI@Z"; + return; + } Out << '@'; - else { + } else { QualType Result = Proto->getResultType(); const Type* RT = Result.getTypePtr(); if (!RT->isAnyPointerType() && !RT->isReferenceType()) { @@ -1711,7 +1766,7 @@ void MicrosoftMangleContext::mangleCXXCtor(const CXXConstructorDecl *D, void MicrosoftMangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream & Out) { - MicrosoftCXXNameMangler mangler(*this, Out); + MicrosoftCXXNameMangler mangler(*this, Out, D, Type); mangler.mangle(D); } void MicrosoftMangleContext::mangleReferenceTemporary(const clang::VarDecl *VD, |