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 @@ -397,6 +397,28 @@ /// \see https://dlang.org/spec/abi.html#Value const char *parseInteger(OutputString *Decl, const char *Mangled, char Type); + /// Extract and demangle an array 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 + /// + /// \return the remaining string on success or nullptr on failure + /// + /// \see https://dlang.org/spec/abi.html#Value + const char *parseArrayLiteral(OutputString *Decl, const char *Mangled); + + /// Extract and demangle an associative array 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 + /// + /// \return the remaining string on success or nullptr on failure + /// + /// \see https://dlang.org/spec/abi.html#Value + const char *parseAssocArray(OutputString *Decl, const char *Mangled); + /// Extract and demangle a string value from a given mangled symbol append it /// to the output string /// @@ -1751,6 +1773,15 @@ Mangled = parseString(Decl, Mangled); break; + // Array values + case 'A': + Mangled++; + if (Type == 'H') + Mangled = parseAssocArray(Decl, Mangled); + else + Mangled = parseArrayLiteral(Decl, Mangled); + break; + default: return nullptr; } @@ -1971,6 +2002,55 @@ return Mangled; } +const char *Demangler::parseArrayLiteral(OutputString *Decl, + const char *Mangled) { + unsigned long Elements; + + Mangled = decodeNumber(Mangled, &Elements); + if (Mangled == nullptr) + return nullptr; + + Decl->append('['); + while (Elements--) { + Mangled = parseValue(Decl, Mangled, '\0'); + if (Mangled == nullptr) + return nullptr; + + if (Elements != 0) + Decl->append(", "); + } + + Decl->append(']'); + return Mangled; +} + +const char *Demangler::parseAssocArray(OutputString *Decl, + const char *Mangled) { + unsigned long Elements; + + Mangled = decodeNumber(Mangled, &Elements); + if (Mangled == nullptr) + return nullptr; + + Decl->append('['); + while (Elements--) { + Mangled = parseValue(Decl, Mangled, '\0'); + if (Mangled == nullptr) + return nullptr; + + Decl->append(':'); + Mangled = parseValue(Decl, Mangled, '\0'); + if (Mangled == nullptr) + return nullptr; + + if (Elements != 0) + Decl->append(", "); + } + + Decl->append(']'); + return Mangled; +} + Demangler::Demangler(const char *Mangled) : Str(Mangled), LastBackref(strlen(Mangled)) {} 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 @@ -308,7 +308,13 @@ {"_D8demangle22__T4testVG3uw3_616263Zv", "demangle.test!(\"abc\"w)"}, {"_D8demangle16__T4testVAyaa0_Zv", "demangle.test!(\"\")"}, {"_D8demangle32__T4testVAyaa8_20090a0d0c0b00ffZv", - "demangle.test!(\" \\t\\n\\r\\f\\v\\x00\\xff\")"} + "demangle.test!(\" \\t\\n\\r\\f\\v\\x00\\xff\")"}, + {"_D8demangle22__T4testVAiA4i1i2i3i4Zv", "demangle.test!([1, 2, 3, 4])"}, + {"_D8demangle25__T4testVAdA2e08P1eN08P1Zv", + "demangle.test!([0x0.8p1, -0x0.8p1])"}, + {"_D8demangle23__T4testVHiiA2i1i2i3i4Zv", "demangle.test!([1:2, 3:4])"}, + {"_D8demangle39__T4testVHAxaiA2a3_616263i1a3_646566i2Zv", + "demangle.test!([\"abc\":1, \"def\":2])"} }; for (ExpectedVal Val : ExpectedArray) {