diff --git a/llvm/include/llvm/Demangle/RustDemangle.h b/llvm/include/llvm/Demangle/RustDemangle.h --- a/llvm/include/llvm/Demangle/RustDemangle.h +++ b/llvm/include/llvm/Demangle/RustDemangle.h @@ -79,7 +79,7 @@ bool demangle(StringView MangledName); private: - void demanglePath(); + void demanglePath(bool InType); void demangleImplPath(); void demangleGenericArg(); void demangleType(); diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -110,7 +110,7 @@ } Input = Mangled; - demanglePath(); + demanglePath(false /* InType */); // FIXME parse optional . @@ -120,6 +120,8 @@ return !Error; } +// Demangles a path. InType indicates whether a path is inside a type. +// // = "C" // crate root // | "M" // (inherent impl) // | "X" // (trait impl) @@ -132,7 +134,7 @@ // | "S" // shim // | // other special namespaces // | // internal namespaces -void Demangler::demanglePath() { +void Demangler::demanglePath(bool InType) { if (Error || RecursionLevel >= MaxRecursionLevel) { Error = true; return; @@ -158,7 +160,7 @@ print("<"); demangleType(); print(" as "); - demanglePath(); + demanglePath(true /* InType */); print(">"); break; } @@ -166,7 +168,7 @@ print("<"); demangleType(); print(" as "); - demanglePath(); + demanglePath(true /* InType */); print(">"); break; } @@ -176,7 +178,7 @@ Error = true; break; } - demanglePath(); + demanglePath(InType); uint64_t Disambiguator = parseOptionalBase62Number('s'); Identifier Ident = parseIdentifier(); @@ -207,8 +209,11 @@ break; } case 'I': { - demanglePath(); - print("::<"); + demanglePath(InType); + // Omit "::" in type paths where "<" opening generic arguments is optional. + if (!InType) + print("::"); + print("<"); for (size_t I = 0; !Error && !consumeIf('E'); ++I) { if (I > 0) print(", "); @@ -229,7 +234,7 @@ void Demangler::demangleImplPath() { SwapAndRestore SavePrint(Print, false); parseOptionalBase62Number('s'); - demanglePath(); + demanglePath(false /* InType */); } // = @@ -416,11 +421,25 @@ // | "D" // dyn Trait + Send + 'a // | // backref void Demangler::demangleType() { + char C = consume(); BasicType Type; - if (parseBasicType(consume(), Type)) - printBasicType(Type); - else - Error = true; // FIXME parse remaining productions. + if (parseBasicType(C, Type)) + return printBasicType(Type); + + switch (C) { + case 'C': + case 'M': + case 'X': + case 'Y': + case 'N': + case 'I': + Position -= 1; + demanglePath(true /* InType */); + break; + default: + Error = true; + break; + } } // = diff --git a/llvm/test/Demangle/rust.test b/llvm/test/Demangle/rust.test --- a/llvm/test/Demangle/rust.test +++ b/llvm/test/Demangle/rust.test @@ -135,6 +135,26 @@ CHECK: basic:: _RIC5basiczE +; Named types. Test possible paths productions. + +CHECK: + _RMC5crateC4name + +CHECK: <<_>> + _RMC5crateMC5cratep + +CHECK: <<_ as Name>> + _RMC5crateXC5cratepC4Name + +CHECK: <<_ as Name>> + _RMC5crateYpC4Name + +CHECK: + _RMC5crateNvC4name4Name + +CHECK: > + _RMC5crateIC4NameE + ; Integer constants. Test value demangling. CHECK: integer::<0>