[llvm] r340341 - [MS Demangler] Fix a few more edge cases.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 21 14:23:50 PDT 2018
Author: zturner
Date: Tue Aug 21 14:23:49 2018
New Revision: 340341
URL: http://llvm.org/viewvc/llvm-project?rev=340341&view=rev
Log:
[MS Demangler] Fix a few more edge cases.
I found these by running llvm-undname over a couple hundred
megabytes of object files generated as part of building chromium.
The issues fixed in this patch are:
1) decltype-auto return types.
2) Indirect vtables (e.g. const A::`vftable'{for `B'})
3) Pointers, references, and rvalue-references to member pointers.
I have exactly one remaining symbol out of a few hundred MB of object
files that produces a name we can't demangle, and it's related to
back-referencing.
Modified:
llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
llvm/trunk/test/Demangle/ms-mangle.test
llvm/trunk/test/Demangle/ms-operators.test
llvm/trunk/test/Demangle/ms-templates-memptrs.test
Modified: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp?rev=340341&r1=340340&r2=340341&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp Tue Aug 21 14:23:49 2018
@@ -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 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(StringV
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(StringVi
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
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(Strin
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
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;
Modified: llvm/trunk/test/Demangle/ms-mangle.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-mangle.test?rev=340341&r1=340340&r2=340341&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-mangle.test (original)
+++ llvm/trunk/test/Demangle/ms-mangle.test Tue Aug 21 14:23:49 2018
@@ -392,3 +392,6 @@
??0?$L at V?$H at PAH@PR26029@@@PR26029@@QAE at XZ
; CHECK: __thiscall PR26029::L<class PR26029::H<int *>>::L<class PR26029::H<int *>>(void)
+
+; ??$emplace_back at ABH@?$vector at HV?$allocator at H@std@@@std@@QAE?A?<decltype-auto>@@ABH at Z
+<decltype-auto> __thiscall std::vector<int, class std::allocator<int>>::emplace_back<int const &>(int const &)
\ No newline at end of file
Modified: llvm/trunk/test/Demangle/ms-operators.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-operators.test?rev=340341&r1=340340&r2=340341&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-operators.test (original)
+++ llvm/trunk/test/Demangle/ms-operators.test Tue Aug 21 14:23:49 2018
@@ -140,6 +140,9 @@
??_7Base@@6B@
; CHECK: const Base::`vftable'
+??_7A at B@@6BC at D@@@
+; CHECK: const B::A::`vftable'{for `D::C'}
+
??_8Middle2@@7B@
; CHECK: const Middle2::`vbtable'
Modified: llvm/trunk/test/Demangle/ms-templates-memptrs.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-templates-memptrs.test?rev=340341&r1=340340&r2=340341&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-templates-memptrs.test (original)
+++ llvm/trunk/test/Demangle/ms-templates-memptrs.test Tue Aug 21 14:23:49 2018
@@ -93,3 +93,5 @@
??$ReadField at UV@@$FM at A@@@YAHAAUV@@@Z
; CHECK: int __cdecl ReadField<struct V, {12, 0}>(struct V &)
+?Q@@3$$QEAP8Foo@@EAAXXZEA
+; CHECK: void (__cdecl Foo::*&&Q)(void)
More information about the llvm-commits
mailing list