diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Demangle/MicrosoftDemangle.cpp | 87 | ||||
-rw-r--r-- | llvm/test/Demangle/ms-mangle.test | 3 | ||||
-rw-r--r-- | llvm/test/Demangle/ms-operators.test | 3 | ||||
-rw-r--r-- | llvm/test/Demangle/ms-templates-memptrs.test | 2 |
4 files changed, 77 insertions, 18 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index 69e0a73e651..6145539a819 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -193,6 +193,7 @@ enum class PrimTy : uint8_t { Double, Ldouble, Nullptr, + Custom, Vftable, Vbtable, LocalStaticGuard @@ -271,8 +272,17 @@ enum class OperatorTy : uint8_t { LocalVftableCtorClosure, // ?_T # local vftable constructor closure ArrayNew, // ?_U operator new[] ArrayDelete, // ?_V operator delete[] + ManVectorCtorIter, // ?__A managed vector ctor iterator + ManVectorDtorIter, // ?__B managed vector dtor iterator + EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator + EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator DynamicInitializer, // ?__E dynamic initializer for `T' DynamicAtexitDestructor, // ?__F dynamic atexit destructor for `T' + VectorCopyCtorIter, // ?__G vector copy constructor iterator + VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator + ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor + // iterator + LocalStaticThreadGuard, // ?__J local static thread guard LiteralOperator, // ?__K operator ""_name CoAwait, // ?__L co_await Spaceship, // operator<=> @@ -362,8 +372,19 @@ OperatorMapEntry OperatorMap[] = { {"_T", "`local vftable ctor closure'", OperatorTy::LocalVftableCtorClosure}, {"_U", "operator new[]", OperatorTy::ArrayNew}, {"_V", "operator delete[]", OperatorTy::ArrayDelete}, + {"__A", "managed vector ctor iterator", OperatorTy::ManVectorCtorIter}, + {"__B", "managed vector dtor iterator", OperatorTy::ManVectorDtorIter}, + {"__C", "EH vector copy ctor iterator", OperatorTy::EHVectorCopyCtorIter}, + {"__D", "EH vector vbase copy ctor iterator", + OperatorTy::EHVectorVbaseCopyCtorIter}, {"__E", "dynamic initializer", OperatorTy::DynamicInitializer}, {"__F", "dynamic atexit destructor", OperatorTy::DynamicAtexitDestructor}, + {"__G", "vector copy ctor iterator", OperatorTy::VectorCopyCtorIter}, + {"__H", "vector vbase copy constructor iterator", + OperatorTy::VectorVbaseCopyCtorIter}, + {"__I", "managed vector vbase copy constructor iterator", + OperatorTy::ManVectorVbaseCopyCtorIter}, + {"__J", "local static thread guard", OperatorTy::LocalStaticThreadGuard}, {"__K", "operator \"\"", OperatorTy::LiteralOperator}, {"__L", "co_await", OperatorTy::CoAwait}, }; @@ -467,6 +488,7 @@ struct Type { PrimTy Prim = PrimTy::Unknown; Qualifiers Quals = Q_None; + StringView Custom; StorageClass Storage = StorageClass::None; // storage class }; @@ -498,6 +520,19 @@ struct OperatorInfo : public Name { : OperatorInfo(OperatorMap[(int)OpType]) {} const OperatorMapEntry *Info = nullptr; + bool IsIndirectTable = false; +}; + +struct IndirectTable : public OperatorInfo { + explicit IndirectTable(const OperatorMapEntry &Info) : OperatorInfo(Info) { + this->IsOperator = true; + this->IsIndirectTable = true; + } + explicit IndirectTable(OperatorTy OpType) + : IndirectTable(OperatorMap[(int)OpType]) {} + + const Name *TableLocation = nullptr; + const Name *TableTarget = nullptr; }; struct StringLiteral : public OperatorInfo { @@ -889,6 +924,14 @@ static void outputName(OutputStream &OS, const Name *TheName, const Type *Ty) { const VirtualMemberPtrThunk *Thunk = nullptr; bool PrintLastScopeSeparator = true; if (Operator) { + if (Operator->IsIndirectTable) { + const IndirectTable *Table = static_cast<const IndirectTable *>(Operator); + outputName(OS, Table->TableLocation, nullptr); + OS << "{for `"; + outputName(OS, Table->TableTarget, nullptr); + OS << "'}"; + return; + } if (Operator->Info->Operator == OperatorTy::Vcall) { Thunk = static_cast<const VirtualMemberPtrThunk *>(Operator); OS << "[thunk]: "; @@ -1116,6 +1159,9 @@ void Type::outputPre(OutputStream &OS) { case PrimTy::Nullptr: OS << "std::nullptr_t"; break; + case PrimTy::Custom: + OS << Custom; + break; case PrimTy::Vbtable: case PrimTy::Vftable: break; @@ -1479,11 +1525,16 @@ Symbol *Demangler::parseOperator(StringView &MangledName) { S->Category = SymbolCategory::UnnamedVariable; switch (MangledName.popFront()) { case '6': - case '7': + case '7': { std::tie(S->SymbolQuals, IsMember) = demangleQualifiers(MangledName); - if (!MangledName.consumeFront('@')) - Error = true; + if (!MangledName.consumeFront('@')) { + IndirectTable *Table = Arena.alloc<IndirectTable>(OTy); + Table->TableTarget = demangleFullyQualifiedTypeName(MangledName); + Table->TableLocation = S->SymbolName; + S->SymbolName = Table; + } break; + } default: Error = true; break; @@ -1754,8 +1805,9 @@ Demangler::demangleOperatorName(StringView &MangledName, bool FullyQualified) { case OperatorTy::LocalVftable: // Foo@@6B@ case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@ case OperatorTy::Vbtable: { // Foo@@7B@ - OperatorInfo *Oper = Arena.alloc<OperatorInfo>(*Entry); - N = (FullyQualified) ? demangleNameScopeChain(MangledName, Oper) : Oper; + N = Arena.alloc<OperatorInfo>(*Entry); + if (FullyQualified) + N = demangleNameScopeChain(MangledName, N); break; } @@ -2515,25 +2567,18 @@ Type *Demangler::demangleType(StringView &MangledName, QualifierMangleMode QMM) { Qualifiers Quals = Q_None; bool IsMember = false; - bool IsMemberKnown = false; if (QMM == QualifierMangleMode::Mangle) { std::tie(Quals, IsMember) = demangleQualifiers(MangledName); - IsMemberKnown = true; } else if (QMM == QualifierMangleMode::Result) { - if (MangledName.consumeFront('?')) { + if (MangledName.consumeFront('?')) std::tie(Quals, IsMember) = demangleQualifiers(MangledName); - IsMemberKnown = true; - } } Type *Ty = nullptr; if (isTagType(MangledName)) Ty = demangleClassType(MangledName); else if (isPointerType(MangledName)) { - if (!IsMemberKnown) - IsMember = isMemberPointer(MangledName); - - if (IsMember) + if (isMemberPointer(MangledName)) Ty = demangleMemberPointerType(MangledName); else Ty = demanglePointerType(MangledName); @@ -2648,6 +2693,15 @@ Type *Demangler::demangleBasicType(StringView &MangledName) { Ty->Prim = PrimTy::Nullptr; return Ty; } + if (MangledName.consumeFront("?")) { + Ty->Prim = PrimTy::Custom; + Ty->Custom = demangleSimpleString(MangledName, false); + if (!MangledName.consumeFront('@')) { + Error = true; + return nullptr; + } + return Ty; + } switch (MangledName.popFront()) { case 'X': @@ -2955,10 +3009,7 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) { if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") || MangledName.consumeFront("$$$V")) { TP.IsEmptyParameterPack = true; - break; - } - - if (MangledName.consumeFront("$$Y")) { + } else if (MangledName.consumeFront("$$Y")) { // Template alias TP.IsTemplateTemplate = true; TP.IsAliasTemplate = true; diff --git a/llvm/test/Demangle/ms-mangle.test b/llvm/test/Demangle/ms-mangle.test index 3a87a1e2b7d..cd65d8306a1 100644 --- a/llvm/test/Demangle/ms-mangle.test +++ b/llvm/test/Demangle/ms-mangle.test @@ -392,3 +392,6 @@ ??0?$L@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ ; CHECK: __thiscall PR26029::L<class PR26029::H<int *>>::L<class PR26029::H<int *>>(void) + +; ??$emplace_back@ABH@?$vector@HV?$allocator@H@std@@@std@@QAE?A?<decltype-auto>@@ABH@Z +<decltype-auto> __thiscall std::vector<int, class std::allocator<int>>::emplace_back<int const &>(int const &)
\ No newline at end of file diff --git a/llvm/test/Demangle/ms-operators.test b/llvm/test/Demangle/ms-operators.test index 7be3da94cc0..3eb49170b86 100644 --- a/llvm/test/Demangle/ms-operators.test +++ b/llvm/test/Demangle/ms-operators.test @@ -140,6 +140,9 @@ ??_7Base@@6B@ ; CHECK: const Base::`vftable' +??_7A@B@@6BC@D@@@ +; CHECK: const B::A::`vftable'{for `D::C'} + ??_8Middle2@@7B@ ; CHECK: const Middle2::`vbtable' diff --git a/llvm/test/Demangle/ms-templates-memptrs.test b/llvm/test/Demangle/ms-templates-memptrs.test index 3647a898871..88e7c21b33c 100644 --- a/llvm/test/Demangle/ms-templates-memptrs.test +++ b/llvm/test/Demangle/ms-templates-memptrs.test @@ -93,3 +93,5 @@ ??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z ; CHECK: int __cdecl ReadField<struct V, {12, 0}>(struct V &) +?Q@@3$$QEAP8Foo@@EAAXXZEA +; CHECK: void (__cdecl Foo::*&&Q)(void) |