diff options
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 146 |
1 files changed, 104 insertions, 42 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 65b7905f962..2be8cec696d 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -28,13 +28,44 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MathExtras.h" #include "llvm/Support/JamCRC.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/MathExtras.h" using namespace clang; namespace { +struct msvc_hashing_ostream : public llvm::raw_svector_ostream { + raw_ostream &OS; + llvm::SmallString<64> Buffer; + + msvc_hashing_ostream(raw_ostream &OS) + : llvm::raw_svector_ostream(Buffer), OS(OS) {} + ~msvc_hashing_ostream() override { + StringRef MangledName = str(); + bool StartsWithEscape = MangledName.startswith("\01"); + if (StartsWithEscape) + MangledName = MangledName.drop_front(1); + if (MangledName.size() <= 4096) { + OS << str(); + return; + } + + llvm::MD5 Hasher; + llvm::MD5::MD5Result Hash; + Hasher.update(MangledName); + Hasher.final(Hash); + + SmallString<32> HexString; + llvm::MD5::stringifyResult(Hash, HexString); + + if (StartsWithEscape) + OS << '\01'; + OS << "??@" << HexString << '@'; + } +}; + /// \brief Retrieve the declaration context that should be used when mangling /// the given declaration. static const DeclContext *getEffectiveDeclContext(const Decl *D) { @@ -206,7 +237,7 @@ public: } private: - void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode); + void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out); }; /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the @@ -2458,7 +2489,8 @@ void MicrosoftMangleContextImpl::mangleCXXName(const NamedDecl *D, getASTContext().getSourceManager(), "Mangling declaration"); - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); return Mangler.mangle(D); } @@ -2558,7 +2590,8 @@ MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, const MicrosoftVTableContext::MethodVFTableLocation &ML = VTContext->getMethodVFTableLocation(GlobalDecl(MD)); - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?"; Mangler.mangleVirtualMemPtrThunk(MD, ML); } @@ -2566,10 +2599,11 @@ MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); - Out << "\01?"; + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); + Mangler.getStream() << "\01?"; Mangler.mangleName(MD); - mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out); + mangleThunkThisAdjustment(MD, Thunk.This, Mangler, MHO); if (!Thunk.Return.isEmpty()) assert(Thunk.Method != nullptr && "Thunk info should hold the overridee decl"); @@ -2586,10 +2620,11 @@ void MicrosoftMangleContextImpl::mangleCXXDtorThunk( // dtors rather than scalar deleting dtors. Just use the vector deleting dtor // mangling manually until we support both deleting dtor types. assert(Type == Dtor_Deleting); - MicrosoftCXXNameMangler Mangler(*this, Out, DD, Type); - Out << "\01??_E"; + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type); + Mangler.getStream() << "\01??_E"; Mangler.mangleName(DD->getParent()); - mangleThunkThisAdjustment(DD, Adjustment, Mangler, Out); + mangleThunkThisAdjustment(DD, Adjustment, Mangler, MHO); Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD); } @@ -2600,7 +2635,8 @@ void MicrosoftMangleContextImpl::mangleCXXVFTable( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '6' for vftables. - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); if (Derived->hasAttr<DLLImportAttr>()) Mangler.getStream() << "\01??_S"; else @@ -2619,7 +2655,8 @@ void MicrosoftMangleContextImpl::mangleCXXVBTable( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '7' for vbtables. - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_8"; Mangler.mangleName(Derived); Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const. @@ -2629,7 +2666,8 @@ void MicrosoftMangleContextImpl::mangleCXXVBTable( } void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R0"; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); Mangler.getStream() << "@8"; @@ -2644,7 +2682,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap( const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_K"; Mangler.mangleName(SrcRD); Mangler.getStream() << "$C"; @@ -2656,7 +2695,8 @@ void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsVolatile, uint32_t NumEntries, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "_TI"; if (IsConst) Mangler.getStream() << 'C'; @@ -2668,7 +2708,8 @@ void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray( QualType T, uint32_t NumEntries, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "_CTA"; Mangler.getStream() << NumEntries; Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result); @@ -2684,17 +2725,20 @@ void MicrosoftMangleContextImpl::mangleCXXCatchableType( llvm::SmallString<64> RTTIMangling; { llvm::raw_svector_ostream Stream(RTTIMangling); - mangleCXXRTTI(T, Stream); + msvc_hashing_ostream MHO(Stream); + mangleCXXRTTI(T, MHO); } Mangler.getStream() << RTTIMangling.substr(1); // VS2015 CTP6 omits the copy-constructor in the mangled name. This name is, // in fact, superfluous but I'm not sure the change was made consciously. - // TODO: Revisit this when VS2015 gets released. llvm::SmallString<64> CopyCtorMangling; - if (CD) { + if (!getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2015) && + CD) { llvm::raw_svector_ostream Stream(CopyCtorMangling); - mangleCXXCtor(CD, CT, Stream); + msvc_hashing_ostream MHO(Stream); + mangleCXXCtor(CD, CT, MHO); } Mangler.getStream() << CopyCtorMangling.substr(1); @@ -2713,7 +2757,8 @@ void MicrosoftMangleContextImpl::mangleCXXCatchableType( void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor( const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R1"; Mangler.mangleNumber(NVOffset); Mangler.mangleNumber(VBPtrOffset); @@ -2725,7 +2770,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor( void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray( const CXXRecordDecl *Derived, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R2"; Mangler.mangleName(Derived); Mangler.getStream() << "8"; @@ -2733,7 +2779,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray( void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor( const CXXRecordDecl *Derived, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??_R3"; Mangler.mangleName(Derived); Mangler.getStream() << "8"; @@ -2746,18 +2793,26 @@ void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator( // <cvr-qualifiers> [<name>] @ // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class> // is always '6' for vftables. - MicrosoftCXXNameMangler Mangler(*this, Out); - Mangler.getStream() << "\01??_R4"; - Mangler.mangleName(Derived); - Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const. - for (const CXXRecordDecl *RD : BasePath) - Mangler.mangleName(RD); - Mangler.getStream() << '@'; + llvm::SmallString<64> VFTableMangling; + llvm::raw_svector_ostream Stream(VFTableMangling); + mangleCXXVFTable(Derived, BasePath, Stream); + + if (VFTableMangling.startswith("\01??@")) { + assert(VFTableMangling.endswith("@")); + Out << VFTableMangling << "??_R4@"; + return; + } + + assert(VFTableMangling.startswith("\01??_7") || + VFTableMangling.startswith("\01??_S")); + + Out << "\01??_R4" << StringRef(VFTableMangling).drop_front(5); } void MicrosoftMangleContextImpl::mangleSEHFilterExpression( const NamedDecl *EnclosingDecl, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, // so the numbering here doesn't have to be the same across TUs. // @@ -2768,7 +2823,8 @@ void MicrosoftMangleContextImpl::mangleSEHFilterExpression( void MicrosoftMangleContextImpl::mangleSEHFinallyBlock( const NamedDecl *EnclosingDecl, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); // The function body is in the same comdat as the function with the handler, // so the numbering here doesn't have to be the same across TUs. // @@ -2788,20 +2844,23 @@ void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) { void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, raw_ostream &Out) { - MicrosoftCXXNameMangler mangler(*this, Out, D, Type); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler mangler(*this, MHO, D, Type); mangler.mangle(D); } void MicrosoftMangleContextImpl::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, raw_ostream &Out) { - MicrosoftCXXNameMangler mangler(*this, Out, D, Type); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler mangler(*this, MHO, D, Type); mangler.mangle(D); } void MicrosoftMangleContextImpl::mangleReferenceTemporary( const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?$RT" << ManglingNumber << '@'; Mangler.mangle(VD, ""); @@ -2809,7 +2868,8 @@ void MicrosoftMangleContextImpl::mangleReferenceTemporary( void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable( const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) { - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01?$TSS" << GuardNum << '@'; Mangler.mangleNestedName(VD); @@ -2827,7 +2887,8 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD, // than 32 static locals. We don't fully implement the second mangling // because those guards are not externally visible, and instead use LLVM's // default renaming when creating a new guard variable. - MicrosoftCXXNameMangler Mangler(*this, Out); + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); bool Visible = VD->isExternallyVisible(); if (Visible) { @@ -2849,9 +2910,10 @@ void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD, } void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D, - raw_ostream &Out, - char CharCode) { - MicrosoftCXXNameMangler Mangler(*this, Out); + char CharCode, + raw_ostream &Out) { + msvc_hashing_ostream MHO(Out); + MicrosoftCXXNameMangler Mangler(*this, MHO); Mangler.getStream() << "\01??__" << CharCode; Mangler.mangleName(D); if (D->isStaticDataMember()) { @@ -2866,14 +2928,14 @@ void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D, void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) { // <initializer-name> ::= ?__E <name> YAXXZ - mangleInitFiniStub(D, Out, 'E'); + mangleInitFiniStub(D, 'E', Out); } void MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out) { // <destructor-name> ::= ?__F <name> YAXXZ - mangleInitFiniStub(D, Out, 'F'); + mangleInitFiniStub(D, 'F', Out); } void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL, |