[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