diff --git a/llvm/lib/Demangle/DLangDemangle.cpp b/llvm/lib/Demangle/DLangDemangle.cpp --- a/llvm/lib/Demangle/DLangDemangle.cpp +++ b/llvm/lib/Demangle/DLangDemangle.cpp @@ -242,6 +242,23 @@ // TODO: Parse template instances with a length prefix. + // There can be multiple different declarations in the same function that + // have the same mangled name. To make the mangled names unique, a fake + // parent in the form `__Sddd' is added to the symbol. + if (Len >= 4 && Mangled[0] == '_' && Mangled[1] == '_' && Mangled[2] == 'S') { + const char *NumPtr = Mangled + 3; + while (NumPtr < (Mangled + Len) && std::isdigit(*NumPtr)) + ++NumPtr; + + if (Mangled + Len == NumPtr) { + // Skip over the fake parent. + Mangled += Len; + return parseIdentifier(Demangled, Mangled); + } + + // Else demangle it as a plain identifier. + } + return parseLName(Demangled, Mangled, Len); } diff --git a/llvm/unittests/Demangle/DLangDemangleTest.cpp b/llvm/unittests/Demangle/DLangDemangleTest.cpp --- a/llvm/unittests/Demangle/DLangDemangleTest.cpp +++ b/llvm/unittests/Demangle/DLangDemangleTest.cpp @@ -45,4 +45,6 @@ std::make_pair("_D8demangle4test11__InterfaceZ", "Interface for demangle.test"), std::make_pair("_D8demangle4test12__ModuleInfoZ", - "ModuleInfo for demangle.test"))); + "ModuleInfo for demangle.test"), + std::make_pair("_D8demangle4__S14testZ", "demangle.test"), + std::make_pair("_D8demangle4__Sd4testZ", "demangle.__Sd.test")));