[Demangle][Rust] Parse named types

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D102571
This commit is contained in:
Tomasz Miąsko 2021-05-18 18:13:21 +02:00
parent 8e93d10633
commit 068332978c
3 changed files with 50 additions and 17 deletions

View File

@ -52,6 +52,11 @@ enum class BasicType {
Never,
};
enum class InType {
No,
Yes,
};
class Demangler {
// Maximum recursion level. Used to avoid stack overflow.
size_t MaxRecursionLevel;
@ -79,8 +84,8 @@ public:
bool demangle(StringView MangledName);
private:
void demanglePath();
void demangleImplPath();
void demanglePath(InType InType);
void demangleImplPath(InType InType);
void demangleGenericArg();
void demangleType();
void demangleConst();

View File

@ -110,7 +110,7 @@ bool Demangler::demangle(StringView Mangled) {
}
Input = Mangled;
demanglePath();
demanglePath(InType::No);
// FIXME parse optional <instantiating-crate>.
@ -120,6 +120,8 @@ bool Demangler::demangle(StringView Mangled) {
return !Error;
}
// Demangles a path. InType indicates whether a path is inside a type.
//
// <path> = "C" <identifier> // crate root
// | "M" <impl-path> <type> // <T> (inherent impl)
// | "X" <impl-path> <type> <path> // <T as Trait> (trait impl)
@ -132,7 +134,7 @@ bool Demangler::demangle(StringView Mangled) {
// | "S" // shim
// | <A-Z> // other special namespaces
// | <a-z> // internal namespaces
void Demangler::demanglePath() {
void Demangler::demanglePath(InType InType) {
if (Error || RecursionLevel >= MaxRecursionLevel) {
Error = true;
return;
@ -147,18 +149,18 @@ void Demangler::demanglePath() {
break;
}
case 'M': {
demangleImplPath();
demangleImplPath(InType);
print("<");
demangleType();
print(">");
break;
}
case 'X': {
demangleImplPath();
demangleImplPath(InType);
print("<");
demangleType();
print(" as ");
demanglePath();
demanglePath(InType::Yes);
print(">");
break;
}
@ -166,7 +168,7 @@ void Demangler::demanglePath() {
print("<");
demangleType();
print(" as ");
demanglePath();
demanglePath(InType::Yes);
print(">");
break;
}
@ -176,7 +178,7 @@ void Demangler::demanglePath() {
Error = true;
break;
}
demanglePath();
demanglePath(InType);
uint64_t Disambiguator = parseOptionalBase62Number('s');
Identifier Ident = parseIdentifier();
@ -207,8 +209,11 @@ void Demangler::demanglePath() {
break;
}
case 'I': {
demanglePath();
print("::<");
demanglePath(InType);
// Omit "::" when in a type, where it is optional.
if (InType == InType::No)
print("::");
print("<");
for (size_t I = 0; !Error && !consumeIf('E'); ++I) {
if (I > 0)
print(", ");
@ -226,10 +231,10 @@ void Demangler::demanglePath() {
// <impl-path> = [<disambiguator>] <path>
// <disambiguator> = "s" <base-62-number>
void Demangler::demangleImplPath() {
void Demangler::demangleImplPath(InType InType) {
SwapAndRestore<bool> SavePrint(Print, false);
parseOptionalBase62Number('s');
demanglePath();
demanglePath(InType);
}
// <generic-arg> = <lifetime>
@ -416,11 +421,14 @@ void Demangler::printBasicType(BasicType Type) {
// | "D" <dyn-bounds> <lifetime> // dyn Trait<Assoc = X> + Send + 'a
// | <backref> // backref
void Demangler::demangleType() {
char C = look();
BasicType Type;
if (parseBasicType(consume(), Type))
printBasicType(Type);
else
Error = true; // FIXME parse remaining productions.
if (parseBasicType(C, Type)) {
consume();
return printBasicType(Type);
}
demanglePath(InType::Yes);
}
// <const> = <basic-type> <const-data>

View File

@ -135,6 +135,26 @@ CHECK: basic::<u64>
CHECK: basic::<!>
_RIC5basiczE
; Named types. Test possible paths productions.
CHECK: named::<name>
_RIC5namedC4nameE
CHECK: named::<<_>>
_RIC5namedMC5cratepE
CHECK: named::<<_ as Name>>
_RIC5namedXC5cratepC4NameE
CHECK: named::<<_ as Name>>
_RIC5namedYpC4NameE
CHECK: named::<name::Name>
_RIC5namedNvC4name4NameE
CHECK: named::<Name<>>
_RIC5namedIC4NameEE
; Integer constants. Test value demangling.
CHECK: integer::<0>