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 @@ -84,7 +84,7 @@ bool demangle(StringView MangledName); private: - void demanglePath(InType InType); + bool demanglePath(InType InType, bool LeaveOpen = false); void demangleImplPath(InType InType); 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 @@ -121,7 +121,10 @@ return !Error; } -// Demangles a path. InType indicates whether a path is inside a type. +// Demangles a path. InType indicates whether a path is inside a type. When +// LeaveOpen is true, a closing `>` after generic arguments is omitted from the +// output. Return value indicates whether generics arguments have been left +// open. // // = "C" // crate root // | "M" // (inherent impl) @@ -135,12 +138,13 @@ // | "S" // shim // | // other special namespaces // | // internal namespaces -void Demangler::demanglePath(InType InType) { +bool Demangler::demanglePath(InType InType, bool LeaveOpen) { if (Error || RecursionLevel >= MaxRecursionLevel) { Error = true; - return; + return false; } SwapAndRestore SaveRecursionLevel(RecursionLevel, RecursionLevel + 1); + bool IsOpen = false; switch (consume()) { case 'C': { @@ -220,7 +224,10 @@ print(", "); demangleGenericArg(); } - print(">"); + if (LeaveOpen) + IsOpen = true; + else + print(">"); break; } default: @@ -228,6 +235,8 @@ Error = true; break; } + + return IsOpen; } // = [] @@ -555,8 +564,20 @@ // = {} // = "p" void Demangler::demangleDynTrait() { - demanglePath(InType::Yes); - // FIXME demangle {} + bool IsOpen = demanglePath(InType::Yes, true /* LeaveOpen */); + while (!Error && consumeIf('p')) { + if (!IsOpen) { + IsOpen = true; + print('<'); + } else { + print(", "); + } + print(parseIdentifier().Name); + print(" = "); + demangleType(); + } + if (IsOpen) + print(">"); } // Demangles optional binder and updates the number of bound lifetimes. 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 @@ -252,6 +252,15 @@ CHECK: trait:: Display> _RIC5traitDG_C7DisplayEL_E +CHECK: trait::> + _RIC5traitDIC12IntoIteratorpEp4ItempEL_E + +CHECK: trait::> + _RIC5traitDC12IntoIteratorp4ItempEL_E + +CHECK: trait::> + _RIC5traitDC12IntoIteratorp4Itempp8IntoIterpEL_E + ; Invalid trait object, missing lifetime. CHECK: _RIC5traitDEE