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 @@ -52,6 +52,8 @@ private: void demanglePath(); + void demangleGenericArg(); + void demangleType(); Identifier parseIdentifier(); uint64_t parseOptionalBase62Number(char Tag); 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 @@ -177,6 +177,17 @@ } break; } + case 'I': { + demanglePath(); + print("::<"); + for (size_t I = 0; !Error && !consumeIf('E'); ++I) { + if (I > 0) + print(", "); + demangleGenericArg(); + } + print(">"); + break; + } default: // FIXME parse remaining productions. Error = true; @@ -184,6 +195,92 @@ } } +// = +// | +// | "K" +// = "L" +void Demangler::demangleGenericArg() { + // FIXME parse remaining productions + demangleType(); +} + +static const char *const BasicTypes[] = { + "i8", // a + "bool", // b + "char", // c + "f64", // d + "str", // e + "f32", // f + nullptr, // g + "u8", // h + "isize", // i + "usize", // j + nullptr, // k + "i32", // l + "u32", // m + "i128", // n + "u128", // o + "_", // p + nullptr, // q + nullptr, // r + "i16", // s + "u16", // t + "()", // u + "...", // v + nullptr, // w + "i64", // x + "u64", // y + "!", // z +}; + +// = "a" // i8 +// | "b" // bool +// | "c" // char +// | "d" // f64 +// | "e" // str +// | "f" // f32 +// | "h" // u8 +// | "i" // isize +// | "j" // usize +// | "l" // i32 +// | "m" // u32 +// | "n" // i128 +// | "o" // u128 +// | "s" // i16 +// | "t" // u16 +// | "u" // () +// | "v" // ... +// | "x" // i64 +// | "y" // u64 +// | "z" // ! +// | "p" // placeholder (e.g. for generic params), shown as _ +static const char *parseBasicType(char C) { + if (isLower(C)) + return BasicTypes[C - 'a']; + return nullptr; +} + +// = | +// | // named type +// | "A" // [T; N] +// | "S" // [T] +// | "T" {} "E" // (T1, T2, T3, ...) +// | "R" [] // &T +// | "Q" [] // &mut T +// | "P" // *const T +// | "O" // *mut T +// | "F" // fn(...) -> ... +// | "D" // dyn Trait + Send + 'a +// | // backref +void Demangler::demangleType() { + if (const char *BasicType = parseBasicType(consume())) { + print(BasicType); + } else { + // FIXME parse remaining productions. + Error = true; + } +} + // = ["u"] ["_"] Identifier Demangler::parseIdentifier() { bool Punycode = consumeIf('u'); 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 @@ -33,6 +33,82 @@ CHECK: crate::{Z:ident#10} _RNZC5crates8_5ident +; Generic type arguments + +CHECK: generic::<_> + _RIC7genericpE + +CHECK: generic::<_, _> + _RIC7genericppE + +CHECK: generic::<_, _, _> + _RIC7genericpppE + +; Basic types + +CHECK: basic:: + _RIC5basicaE + +CHECK: basic:: + _RIC5basicbE + +CHECK: basic:: + _RIC5basiccE + +CHECK: basic:: + _RIC5basicdE + +CHECK: basic:: + _RIC5basiceE + +CHECK: basic:: + _RIC5basicfE + +CHECK: basic:: + _RIC5basichE + +CHECK: basic:: + _RIC5basiciE + +CHECK: basic:: + _RIC5basicjE + +CHECK: basic:: + _RIC5basiclE + +CHECK: basic:: + _RIC5basicmE + +CHECK: basic:: + _RIC5basicnE + +CHECK: basic:: + _RIC5basicoE + +CHECK: basic::<_> + _RIC5basicpE + +CHECK: basic:: + _RIC5basicsE + +CHECK: basic:: + _RIC5basictE + +CHECK: basic::<()> + _RIC5basicuE + +CHECK: basic::<...> + _RIC5basicvE + +CHECK: basic:: + _RIC5basicxE + +CHECK: basic:: + _RIC5basicyE + +CHECK: basic:: + _RIC5basiczE + ; Invalid mangled characters CHECK: _RNvC2a.1c