Index: llvm/lib/Demangle/DLangDemangle.cpp =================================================================== --- llvm/lib/Demangle/DLangDemangle.cpp +++ llvm/lib/Demangle/DLangDemangle.cpp @@ -324,6 +324,17 @@ /// \see https://dlang.org/spec/abi.html#TypeModifiers const char *parseTypeModifiers(OutputString *Decl, const char *Mangled); + /// Extract and demangle a tuple 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#TypeTuple + const char *parseTuple(OutputString *Decl, const char *Mangled); + /// The string we are demangling. const char *Str; /// The index of the last back reference. @@ -1122,7 +1133,10 @@ return parseQualified(Decl, Mangled, false); // TODO: Parse delegate types - // TODO: Parse tuple types + + case 'B': /* tuple T */ + Mangled++; + return parseTuple(Decl, Mangled); // Basic types case 'n': @@ -1255,6 +1269,28 @@ } } +const char *Demangler::parseTuple(OutputString *Decl, const char *Mangled) { + unsigned long Elements; + + Mangled = decodeNumber(Mangled, &Elements); + if (Mangled == nullptr) + return nullptr; + + Decl->append("tuple("); + + while (Elements--) { + Mangled = parseType(Decl, Mangled); + if (Mangled == nullptr) + return nullptr; + + if (Elements != 0) + Decl->append(", "); + } + + Decl->append(')'); + return Mangled; +} + const char *Demangler::parseLName(OutputString *Decl, const char *Mangled, unsigned long Len) { switch (Len) { Index: llvm/unittests/Demangle/DLangDemangleTest.cpp =================================================================== --- llvm/unittests/Demangle/DLangDemangleTest.cpp +++ llvm/unittests/Demangle/DLangDemangleTest.cpp @@ -130,7 +130,12 @@ {"_D8demangle4testFaaYv", "demangle.test(char, char, ...)"}, {"_D8demangle4testFXv", "demangle.test(...)"}, {"_D8demangle4testFYv", "demangle.test(, ...)"}, - {"_D8demangle4testFaaZv", "demangle.test(char, char)"} + {"_D8demangle4testFaaZv", "demangle.test(char, char)"}, + {"_D8demangle4testFB0Zv", "demangle.test(tuple())"}, + {"_D8demangle4testFB1aZv", "demangle.test(tuple(char))"}, + {"_D8demangle4testFB2aaZv", "demangle.test(tuple(char, char))"}, + {"_D8demangle4testFB3aaaZv", "demangle.test(tuple(char, char, char))"}, + {"_D8demangle4testFB2OaaZv", "demangle.test(tuple(shared(char), char))"} }; for (ExpectedVal Val : ExpectedArray) {