diff options
| -rw-r--r-- | llvm/lib/Demangle/MicrosoftDemangle.cpp | 37 | ||||
| -rw-r--r-- | llvm/test/Demangle/ms-cxx11.test | 4 |
2 files changed, 36 insertions, 5 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index ad6990c4e21..bd7faa31c80 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -520,14 +520,27 @@ Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena, 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::demangleInitFiniStub(StringView &MangledName, 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::demangleInitFiniStub(StringView &MangledName, 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(StringView &MangledName) { 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; } diff --git a/llvm/test/Demangle/ms-cxx11.test b/llvm/test/Demangle/ms-cxx11.test index 54299da1b67..fa756a54bb8 100644 --- a/llvm/test/Demangle/ms-cxx11.test +++ b/llvm/test/Demangle/ms-cxx11.test @@ -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@H$$ZH@@YAHAEBU?$Foo@H@@0@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 |

