[llvm] r341119 - [MS Demangler] Add support for $$Z parameter pack separator.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 30 13:53:30 PDT 2018


Author: zturner
Date: Thu Aug 30 13:53:29 2018
New Revision: 341119

URL: http://llvm.org/viewvc/llvm-project?rev=341119&view=rev
Log:
[MS Demangler] Add support for $$Z parameter pack separator.

$$Z appears between adjacent expanded parameter packs in the
same template instantiation.  We don't need to print it, it's
only there to disambiguate between manglings that would otherwise
be ambiguous.  So we just need to parse it and throw it away.

Modified:
    llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
    llvm/trunk/test/Demangle/ms-cxx11.test

Modified: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp?rev=341119&r1=341118&r2=341119&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp Thu Aug 30 13:53:29 2018
@@ -520,14 +520,27 @@ Demangler::demangleRttiBaseClassDescript
   return VSN;
 }
 
+void dump(Node *N) {
+  OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
+  N->output(OS, OF_Default);
+  OS << '\0';
+  char *Name = OS.getBuffer();
+
+  printf(Name);
+  printf("\n");
+  std::free(Name);
+}
+
 FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
                                                     bool IsDestructor) {
   DynamicStructorIdentifierNode *DSIN =
       Arena.alloc<DynamicStructorIdentifierNode>();
   DSIN->IsDestructor = IsDestructor;
 
-  // What follows is a main symbol name. This may include namespaces or class
-  // back references.
+  bool IsKnownStaticDataMember = false;
+  if (MangledName.consumeFront('?'))
+    IsKnownStaticDataMember = true;
+
   QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
 
   SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
@@ -536,7 +549,15 @@ FunctionSymbolNode *Demangler::demangleI
 
   if (Symbol->kind() == NodeKind::VariableSymbol) {
     DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol);
-    if (!MangledName.consumeFront('@')) {
+
+    // Older versions of clang mangled this type of symbol incorrectly.  They
+    // would omit the leading ? and they would only emit a single @ at the end.
+    // The correct mangling is a leading ? and 2 trailing @ signs.  Handle
+    // both cases.
+    int AtCount = IsKnownStaticDataMember ? 2 : 1;
+    for (int I = 0; I < AtCount; ++I) {
+      if (MangledName.consumeFront('@'))
+        continue;
       Error = true;
       return nullptr;
     }
@@ -544,6 +565,12 @@ FunctionSymbolNode *Demangler::demangleI
     FSN = demangleFunctionEncoding(MangledName);
     FSN->Name = synthesizeQualifiedName(Arena, DSIN);
   } else {
+    if (IsKnownStaticDataMember) {
+      // This was supposed to be a static data member, but we got a function.
+      Error = true;
+      return nullptr;
+    }
+
     FSN = static_cast<FunctionSymbolNode *>(Symbol);
     DSIN->Name = Symbol->Name;
     FSN->Name = synthesizeQualifiedName(Arena, DSIN);
@@ -2148,8 +2175,8 @@ Demangler::demangleTemplateParameterList
 
   while (!Error && !MangledName.startsWith('@')) {
     if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
-        MangledName.consumeFront("$$$V")) {
-      // Empty parameter pack.
+        MangledName.consumeFront("$$$V") || MangledName.consumeFront("$$Z")) {
+      // parameter pack separator
       continue;
     }
 

Modified: llvm/trunk/test/Demangle/ms-cxx11.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-cxx11.test?rev=341119&r1=341118&r2=341119&view=diff
==============================================================================
--- llvm/trunk/test/Demangle/ms-cxx11.test (original)
+++ llvm/trunk/test/Demangle/ms-cxx11.test Thu Aug 30 13:53:29 2018
@@ -86,6 +86,10 @@
 ??$templ_fun_with_pack@$S@@YAXXZ
 ; CHECK: void __cdecl templ_fun_with_pack<>(void)
 
+; $$Z is a parameter pack separator.
+??$func at H$$ZH@@YAHAEBU?$Foo at H@@0 at Z
+; CHECK: int __cdecl func<int, int>(struct Foo<int> const &, struct Foo<int> const &)
+
 ??$templ_fun_with_ty_pack@$$$V@@YAXXZ
 ; CHECK: void __cdecl templ_fun_with_ty_pack<>(void)
 ??$templ_fun_with_ty_pack@$$V@@YAXXZ




More information about the llvm-commits mailing list