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 @@ -102,6 +102,21 @@ void demangleConstBool(); void demangleConstChar(); + template void demangleBackref(Callable Demangler) { + uint64_t Backref = parseBase62Number(); + if (Error || Backref >= Position) { + Error = true; + return; + } + + if (!Print) + return; + + SwapAndRestore SavePosition(Position, Position); + Position = Backref; + Demangler(); + } + Identifier parseIdentifier(); uint64_t parseOptionalBase62Number(char Tag); uint64_t parseBase62Number(); 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 @@ -232,8 +232,12 @@ print(">"); break; } + case 'B': { + bool IsOpen = false; + demangleBackref([&] { IsOpen = demanglePath(InType, LeaveOpen); }); + return IsOpen; + } default: - // FIXME parse remaining productions. 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 @@ -420,6 +420,22 @@ CHECK: _RIC4charKc1234567_E _RIC4charKc1234567_E +; Backreferences + +CHECK: backref:: + _RIC7backrefNvB0_5identE + +; Invalid backreferences + +CHECK: _RB_ + _RB_ + +CHECK: _RB5_ + _RB5_ + +CHECK: _RNvB_1a + _RNvB_1a + ; Invalid mangled characters CHECK: _RNvC2a.1c