llvm.org GIT mirror llvm / da9501c
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340341 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 1 year, 27 days ago
4 changed file(s) with 77 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
192192 Double,
193193 Ldouble,
194194 Nullptr,
195 Custom,
195196 Vftable,
196197 Vbtable,
197198 LocalStaticGuard
270271 LocalVftableCtorClosure, // ?_T # local vftable constructor closure
271272 ArrayNew, // ?_U operator new[]
272273 ArrayDelete, // ?_V operator delete[]
274 ManVectorCtorIter, // ?__A managed vector ctor iterator
275 ManVectorDtorIter, // ?__B managed vector dtor iterator
276 EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
277 EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iterator
273278 DynamicInitializer, // ?__E dynamic initializer for `T'
274279 DynamicAtexitDestructor, // ?__F dynamic atexit destructor for `T'
280 VectorCopyCtorIter, // ?__G vector copy constructor iterator
281 VectorVbaseCopyCtorIter, // ?__H vector vbase copy constructor iterator
282 ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy constructor
283 // iterator
284 LocalStaticThreadGuard, // ?__J local static thread guard
275285 LiteralOperator, // ?__K operator ""_name
276286 CoAwait, // ?__L co_await
277287 Spaceship, // operator<=>
361371 {"_T", "`local vftable ctor closure'", OperatorTy::LocalVftableCtorClosure},
362372 {"_U", "operator new[]", OperatorTy::ArrayNew},
363373 {"_V", "operator delete[]", OperatorTy::ArrayDelete},
374 {"__A", "managed vector ctor iterator", OperatorTy::ManVectorCtorIter},
375 {"__B", "managed vector dtor iterator", OperatorTy::ManVectorDtorIter},
376 {"__C", "EH vector copy ctor iterator", OperatorTy::EHVectorCopyCtorIter},
377 {"__D", "EH vector vbase copy ctor iterator",
378 OperatorTy::EHVectorVbaseCopyCtorIter},
364379 {"__E", "dynamic initializer", OperatorTy::DynamicInitializer},
365380 {"__F", "dynamic atexit destructor", OperatorTy::DynamicAtexitDestructor},
381 {"__G", "vector copy ctor iterator", OperatorTy::VectorCopyCtorIter},
382 {"__H", "vector vbase copy constructor iterator",
383 OperatorTy::VectorVbaseCopyCtorIter},
384 {"__I", "managed vector vbase copy constructor iterator",
385 OperatorTy::ManVectorVbaseCopyCtorIter},
386 {"__J", "local static thread guard", OperatorTy::LocalStaticThreadGuard},
366387 {"__K", "operator \"\"", OperatorTy::LiteralOperator},
367388 {"__L", "co_await", OperatorTy::CoAwait},
368389 };
466487 PrimTy Prim = PrimTy::Unknown;
467488
468489 Qualifiers Quals = Q_None;
490 StringView Custom;
469491 StorageClass Storage = StorageClass::None; // storage class
470492 };
471493
497519 : OperatorInfo(OperatorMap[(int)OpType]) {}
498520
499521 const OperatorMapEntry *Info = nullptr;
522 bool IsIndirectTable = false;
523 };
524
525 struct IndirectTable : public OperatorInfo {
526 explicit IndirectTable(const OperatorMapEntry &Info) : OperatorInfo(Info) {
527 this->IsOperator = true;
528 this->IsIndirectTable = true;
529 }
530 explicit IndirectTable(OperatorTy OpType)
531 : IndirectTable(OperatorMap[(int)OpType]) {}
532
533 const Name *TableLocation = nullptr;
534 const Name *TableTarget = nullptr;
500535 };
501536
502537 struct StringLiteral : public OperatorInfo {
888923 const VirtualMemberPtrThunk *Thunk = nullptr;
889924 bool PrintLastScopeSeparator = true;
890925 if (Operator) {
926 if (Operator->IsIndirectTable) {
927 const IndirectTable *Table = static_cast(Operator);
928 outputName(OS, Table->TableLocation, nullptr);
929 OS << "{for `";
930 outputName(OS, Table->TableTarget, nullptr);
931 OS << "'}";
932 return;
933 }
891934 if (Operator->Info->Operator == OperatorTy::Vcall) {
892935 Thunk = static_cast(Operator);
893936 OS << "[thunk]: ";
11141157 break;
11151158 case PrimTy::Nullptr:
11161159 OS << "std::nullptr_t";
1160 break;
1161 case PrimTy::Custom:
1162 OS << Custom;
11171163 break;
11181164 case PrimTy::Vbtable:
11191165 case PrimTy::Vftable:
14781524 S->Category = SymbolCategory::UnnamedVariable;
14791525 switch (MangledName.popFront()) {
14801526 case '6':
1481 case '7':
1527 case '7': {
14821528 std::tie(S->SymbolQuals, IsMember) = demangleQualifiers(MangledName);
1483 if (!MangledName.consumeFront('@'))
1484 Error = true;
1529 if (!MangledName.consumeFront('@')) {
1530 IndirectTable *Table = Arena.alloc(OTy);
1531 Table->TableTarget = demangleFullyQualifiedTypeName(MangledName);
1532 Table->TableLocation = S->SymbolName;
1533 S->SymbolName = Table;
1534 }
14851535 break;
1536 }
14861537 default:
14871538 Error = true;
14881539 break;
17531804 case OperatorTy::LocalVftable: // Foo@@6B@
17541805 case OperatorTy::RttiCompleteObjLocator: // Foo@@6B@
17551806 case OperatorTy::Vbtable: { // Foo@@7B@
1756 OperatorInfo *Oper = Arena.alloc(*Entry);
1757 N = (FullyQualified) ? demangleNameScopeChain(MangledName, Oper) : Oper;
1807 N = Arena.alloc(*Entry);
1808 if (FullyQualified)
1809 N = demangleNameScopeChain(MangledName, N);
17581810 break;
17591811 }
17601812
25142566 QualifierMangleMode QMM) {
25152567 Qualifiers Quals = Q_None;
25162568 bool IsMember = false;
2517 bool IsMemberKnown = false;
25182569 if (QMM == QualifierMangleMode::Mangle) {
25192570 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
2520 IsMemberKnown = true;
25212571 } else if (QMM == QualifierMangleMode::Result) {
2522 if (MangledName.consumeFront('?')) {
2572 if (MangledName.consumeFront('?'))
25232573 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
2524 IsMemberKnown = true;
2525 }
25262574 }
25272575
25282576 Type *Ty = nullptr;
25292577 if (isTagType(MangledName))
25302578 Ty = demangleClassType(MangledName);
25312579 else if (isPointerType(MangledName)) {
2532 if (!IsMemberKnown)
2533 IsMember = isMemberPointer(MangledName);
2534
2535 if (IsMember)
2580 if (isMemberPointer(MangledName))
25362581 Ty = demangleMemberPointerType(MangledName);
25372582 else
25382583 Ty = demanglePointerType(MangledName);
26452690
26462691 if (MangledName.consumeFront("$$T")) {
26472692 Ty->Prim = PrimTy::Nullptr;
2693 return Ty;
2694 }
2695 if (MangledName.consumeFront("?")) {
2696 Ty->Prim = PrimTy::Custom;
2697 Ty->Custom = demangleSimpleString(MangledName, false);
2698 if (!MangledName.consumeFront('@')) {
2699 Error = true;
2700 return nullptr;
2701 }
26482702 return Ty;
26492703 }
26502704
29543008 if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
29553009 MangledName.consumeFront("$$$V")) {
29563010 TP.IsEmptyParameterPack = true;
2957 break;
2958 }
2959
2960 if (MangledName.consumeFront("$$Y")) {
3011 } else if (MangledName.consumeFront("$$Y")) {
29613012 // Template alias
29623013 TP.IsTemplateTemplate = true;
29633014 TP.IsAliasTemplate = true;
391391
392392 ??0?$L@V?$H@PAH@PR26029@@@PR26029@@QAE@XZ
393393 ; CHECK: __thiscall PR26029::L>::L>(void)
394
395 ; ??$emplace_back@ABH@?$vector@HV?$allocator@H@std@@@std@@QAE?A?@@ABH@Z
396 __thiscall std::vector>::emplace_back(int const &)
139139 ??_7Base@@6B@
140140 ; CHECK: const Base::`vftable'
141141
142 ??_7A@B@@6BC@D@@@
143 ; CHECK: const B::A::`vftable'{for `D::C'}
144
142145 ??_8Middle2@@7B@
143146 ; CHECK: const Middle2::`vbtable'
144147
9292 ??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z
9393 ; CHECK: int __cdecl ReadField(struct V &)
9494
95 ?Q@@3$$QEAP8Foo@@EAAXXZEA
96 ; CHECK: void (__cdecl Foo::*&&Q)(void)