[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@lsferreira.net> Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D111419
This commit is contained in:
parent
bec08795db
commit
b21ea1c270
|
@ -105,6 +105,17 @@ private:
|
|||
/// \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 @@ private:
|
|||
|
||||
/// 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);
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in New Issue