Index: llvm/lib/Demangle/DLangDemangle.cpp =================================================================== --- llvm/lib/Demangle/DLangDemangle.cpp +++ llvm/lib/Demangle/DLangDemangle.cpp @@ -397,6 +397,19 @@ /// \see https://dlang.org/spec/abi.html#Value const char *parseInteger(OutputString *Decl, const char *Mangled, char Type); + /// Extract and demangle an struct literal value from a given mangled symbol + /// append it to the output string + /// + /// \param Decl output buffer to write the demangled name + /// \param Mangled mangled symbol to be demangled + /// \param Name demangled symbol name of the struct literal + /// + /// \return the remaining string on success or nullptr on failure + /// + /// \see https://dlang.org/spec/abi.html#Value + const char *parseStructLiteral(OutputString *Decl, const char *Mangled, + const char *Name); + /// Extract and demangle an array literal value from a given mangled symbol /// append it to the output string /// @@ -446,13 +459,15 @@ /// /// \param Decl output buffer to write the demangled name /// \param Mangled mangled symbol to be demangled + /// \param Name demangled symbol name of the type, if needed /// \param Type mangled type character in which the type should be /// represented as, if needed /// /// \return the remaining string on success or nullptr on failure /// /// \see https://dlang.org/spec/abi.html#Value - const char *parseValue(OutputString *Decl, const char *Mangled, char Type); + const char *parseValue(OutputString *Decl, const char *Mangled, + const char *Name, char Type); /// The string we are demangling. const char *Str; @@ -1647,7 +1662,7 @@ Name.append('\0'); Name.Ptr--; - Mangled = parseValue(Decl, Mangled, Type); + Mangled = parseValue(Decl, Mangled, Name.Buffer, Type); Name.free(); break; } @@ -1716,7 +1731,7 @@ } const char *Demangler::parseValue(OutputString *Decl, const char *Mangled, - char Type) { + const char *Name, char Type) { if (Mangled == nullptr || *Mangled == '\0') return nullptr; @@ -1782,6 +1797,12 @@ Mangled = parseArrayLiteral(Decl, Mangled); break; + // Struct values + case 'S': + Mangled++; + Mangled = parseStructLiteral(Decl, Mangled, Name); + break; + default: return nullptr; } @@ -1789,6 +1810,32 @@ return Mangled; } +const char *Demangler::parseStructLiteral(OutputString *Decl, + const char *Mangled, + const char *Name) { + unsigned long Args; + + Mangled = decodeNumber(Mangled, &Args); + if (Mangled == nullptr) + return nullptr; + + if (Name != nullptr) + Decl->append(Name); + + Decl->append('('); + while (Args--) { + Mangled = parseValue(Decl, Mangled, nullptr, '\0'); + if (Mangled == nullptr) + return nullptr; + + if (Args != 0) + Decl->append(", "); + } + + Decl->append(')'); + return Mangled; +} + const char *Demangler::parseString(OutputString *Decl, const char *Mangled) { char Type = *Mangled; unsigned long Len; @@ -2012,7 +2059,7 @@ Decl->append('['); while (Elements--) { - Mangled = parseValue(Decl, Mangled, '\0'); + Mangled = parseValue(Decl, Mangled, nullptr, '\0'); if (Mangled == nullptr) return nullptr; @@ -2034,12 +2081,12 @@ Decl->append('['); while (Elements--) { - Mangled = parseValue(Decl, Mangled, '\0'); + Mangled = parseValue(Decl, Mangled, nullptr, '\0'); if (Mangled == nullptr) return nullptr; Decl->append(':'); - Mangled = parseValue(Decl, Mangled, '\0'); + Mangled = parseValue(Decl, Mangled, nullptr, '\0'); if (Mangled == nullptr) return nullptr; Index: llvm/unittests/Demangle/DLangDemangleTest.cpp =================================================================== --- llvm/unittests/Demangle/DLangDemangleTest.cpp +++ llvm/unittests/Demangle/DLangDemangleTest.cpp @@ -314,7 +314,11 @@ "demangle.test!([0x0.8p1, -0x0.8p1])"}, {"_D8demangle23__T4testVHiiA2i1i2i3i4Zv", "demangle.test!([1:2, 3:4])"}, {"_D8demangle39__T4testVHAxaiA2a3_616263i1a3_646566i2Zv", - "demangle.test!([\"abc\":1, \"def\":2])"} + "demangle.test!([\"abc\":1, \"def\":2])"}, + {"_D8demangle28__T4testVS8demangle1SS2i1i2Zv", + "demangle.test!(demangle.S(1, 2))"}, + {"_D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv", + "demangle.test!(demangle.S(1, \"abc\"))"} }; for (ExpectedVal Val : ExpectedArray) {