[llvm] b21ea1c - [Demangle] Add support for D types back referencing
Luís Ferreira via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 12 14:01:52 PST 2022
Author: Luís Ferreira
Date: 2022-01-12T21:57:31Z
New Revision: b21ea1c2701d754072b679c27df75c43699a2623
URL: https://github.com/llvm/llvm-project/commit/b21ea1c2701d754072b679c27df75c43699a2623
DIFF: https://github.com/llvm/llvm-project/commit/b21ea1c2701d754072b679c27df75c43699a2623.diff
LOG: [Demangle] Add support for D types back referencing
This patch adds support for type back referencing, allowing demangling of
compressed mangled symbols with repetitive types.
Signed-off-by: Luís Ferreira <contact at lsferreira.net>
Reviewed By: dblaikie
Differential Revision: https://reviews.llvm.org/D111419
Added:
Modified:
llvm/lib/Demangle/DLangDemangle.cpp
llvm/unittests/Demangle/DLangDemangleTest.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Demangle/DLangDemangle.cpp b/llvm/lib/Demangle/DLangDemangle.cpp
index 086c76557f5b9..9c0ea7a51bf4c 100644
--- a/llvm/lib/Demangle/DLangDemangle.cpp
+++ b/llvm/lib/Demangle/DLangDemangle.cpp
@@ -105,6 +105,17 @@ struct Demangler {
/// \see https://dlang.org/spec/abi.html#IdentifierBackRef .
const char *parseSymbolBackref(OutputBuffer *Demangled, const char *Mangled);
+ /// Extract and demangle backreferenced type from a given mangled symbol
+ /// and append it to the output string.
+ ///
+ /// \param Mangled mangled symbol to be demangled.
+ ///
+ /// \return the remaining string on success or nullptr on failure.
+ ///
+ /// \see https://dlang.org/spec/abi.html#back_ref .
+ /// \see https://dlang.org/spec/abi.html#TypeBackRef .
+ const char *parseTypeBackref(const char *Mangled);
+
/// Check whether it is the beginning of a symbol name.
///
/// \param Mangled string to extract the symbol name.
@@ -162,6 +173,8 @@ struct Demangler {
/// The string we are demangling.
const char *Str;
+ /// The index of the last back reference.
+ int LastBackref;
};
} // namespace
@@ -276,6 +289,39 @@ const char *Demangler::parseSymbolBackref(OutputBuffer *Demangled,
return Mangled;
}
+const char *Demangler::parseTypeBackref(const char *Mangled) {
+ // A type back reference always points to a letter.
+ // TypeBackRef:
+ // Q NumberBackRef
+ // ^
+ const char *Backref;
+
+ // If we appear to be moving backwards through the mangle string, then
+ // bail as this may be a recursive back reference.
+ if (Mangled - Str >= LastBackref)
+ return nullptr;
+
+ int SaveRefPos = LastBackref;
+ LastBackref = Mangled - Str;
+
+ // Get position of the back reference.
+ Mangled = decodeBackref(Mangled, Backref);
+
+ // Can't decode back reference.
+ if (Backref == nullptr)
+ return nullptr;
+
+ // TODO: Add support for function type back references.
+ Backref = parseType(Backref);
+
+ LastBackref = SaveRefPos;
+
+ if (Backref == nullptr)
+ return nullptr;
+
+ return Mangled;
+}
+
bool Demangler::isSymbolName(const char *Mangled) {
long Ret;
const char *Qref = Mangled;
@@ -423,7 +469,10 @@ const char *Demangler::parseType(const char *Mangled) {
return Mangled;
// TODO: Add support for the rest of the basic types.
- // TODO: Parse back referenced types.
+
+ // Back referenced type.
+ case 'Q':
+ return parseTypeBackref(Mangled);
default: // unhandled.
return nullptr;
@@ -487,7 +536,8 @@ const char *Demangler::parseLName(OutputBuffer *Demangled, const char *Mangled,
return Mangled;
}
-Demangler::Demangler(const char *Mangled) : Str(Mangled) {}
+Demangler::Demangler(const char *Mangled)
+ : Str(Mangled), LastBackref(strlen(Mangled)) {}
const char *Demangler::parseMangle(OutputBuffer *Demangled) {
return parseMangle(Demangled, this->Str);
diff --git a/llvm/unittests/Demangle/DLangDemangleTest.cpp b/llvm/unittests/Demangle/DLangDemangleTest.cpp
index d76bf36c14598..dd0c699d5c186 100644
--- a/llvm/unittests/Demangle/DLangDemangleTest.cpp
+++ b/llvm/unittests/Demangle/DLangDemangleTest.cpp
@@ -63,4 +63,13 @@ INSTANTIATE_TEST_SUITE_P(
std::make_pair("_D8demangle3ABCQa1ai",
nullptr), // invalid symbol back reference (recursive).
std::make_pair("_D8demangleQDXXXXXXXXXXXXx",
- nullptr))); // overflow back reference position.
+ nullptr), // overflow back reference position.
+ std::make_pair(
+ "_D8demangle4ABCi1aQd",
+ "demangle.ABCi.a"), // type back reference: `Qd` is a back reference
+ // for position 4, counting from `d` char, so
+ // decoding it points to `i`.
+ std::make_pair("_D8demangle3fooQXXXx",
+ nullptr), // invalid type back reference position.
+ std::make_pair("_D8demangle5recurQa",
+ nullptr))); // invalid type back reference (recursive).
More information about the llvm-commits
mailing list