diff --git a/llvm/include/llvm/Demangle/RustDemangle.h b/llvm/include/llvm/Demangle/RustDemangle.h index 3fe73803cf869..8797830cac690 100644 --- a/llvm/include/llvm/Demangle/RustDemangle.h +++ b/llvm/include/llvm/Demangle/RustDemangle.h @@ -81,6 +81,7 @@ class Demangler { void demangleConst(); void demangleConstInt(); void demangleConstBool(); + void demangleConstChar(); Identifier parseIdentifier(); uint64_t parseOptionalBase62Number(char Tag); diff --git a/llvm/lib/Demangle/RustDemangle.cpp b/llvm/lib/Demangle/RustDemangle.cpp index 3a9e75f33b9c5..ebccafcae2993 100644 --- a/llvm/lib/Demangle/RustDemangle.cpp +++ b/llvm/lib/Demangle/RustDemangle.cpp @@ -414,11 +414,14 @@ void Demangler::demangleConst() { case BasicType::Bool: demangleConstBool(); break; + case BasicType::Char: + demangleConstChar(); + break; case BasicType::Placeholder: print('_'); break; default: - // FIXME demangle backreferences and char constants. + // FIXME demangle backreferences. Error = true; break; } @@ -455,6 +458,54 @@ void Demangler::demangleConstBool() { Error = true; } +/// Returns true if CodePoint represents a printable ASCII character. +static bool isAsciiPrintable(uint64_t CodePoint) { + return 0x20 <= CodePoint && CodePoint <= 0x7e; +} + +// = +void Demangler::demangleConstChar() { + StringView HexDigits; + uint64_t CodePoint = parseHexNumber(HexDigits); + if (Error || HexDigits.size() > 6) { + Error = true; + return; + } + + print("'"); + switch (CodePoint) { + case '\t': + print(R"(\t)"); + break; + case '\r': + print(R"(\r)"); + break; + case '\n': + print(R"(\n)"); + break; + case '\\': + print(R"(\\)"); + break; + case '"': + print(R"(")"); + break; + case '\'': + print(R"(\')"); + break; + default: + if (isAsciiPrintable(CodePoint)) { + char C = CodePoint; + print(C); + } else { + print(R"(\u{)"); + print(HexDigits); + print('}'); + } + break; + } + print('\''); +} + // = ["u"] ["_"] Identifier Demangler::parseIdentifier() { bool Punycode = consumeIf('u'); diff --git a/llvm/test/Demangle/rust.test b/llvm/test/Demangle/rust.test index 4caf92b3230e4..89eda8ff1ebfe 100644 --- a/llvm/test/Demangle/rust.test +++ b/llvm/test/Demangle/rust.test @@ -207,6 +207,40 @@ CHECK: _RIC4boolKb2_E CHECK: _RIC4boolKbn0_E _RIC4boolKbn0_E +; Char constants + +CHECK: char::<'a'> + _RIC4charKc61_E + +CHECK: char::<'"'> + _RIC4charKc22_E + +CHECK: char::<'\t'> + _RIC4charKc9_E + +CHECK: char::<'\r'> + _RIC4charKcd_E + +CHECK: char::<'\n'> + _RIC4charKca_E + +CHECK: char::<'\\'> + _RIC4charKc5c_E + +CHECK: char::<'\''> + _RIC4charKc27_E + +CHECK: char::<'\u{1f40d}'> + _RIC4charKc1f40d_E + +CHECK: char::<'\u{10ffff}'> + _RIC4charKc10ffff_E + +; Invalid char constants + +CHECK: _RIC4charKc1234567_E + _RIC4charKc1234567_E + ; Invalid mangled characters CHECK: _RNvC2a.1c