[llvm] 2ba49f6 - [Demangle][Rust] Parse char constants

Tomasz Miąsko via llvm-commits llvm-commits at lists.llvm.org
Sat May 15 02:25:35 PDT 2021


Author: Tomasz Miąsko
Date: 2021-05-15T10:48:27+02:00
New Revision: 2ba49f6ae611b1dfd1dd64fe0fc4c0143bedc271

URL: https://github.com/llvm/llvm-project/commit/2ba49f6ae611b1dfd1dd64fe0fc4c0143bedc271
DIFF: https://github.com/llvm/llvm-project/commit/2ba49f6ae611b1dfd1dd64fe0fc4c0143bedc271.diff

LOG: [Demangle][Rust] Parse char constants

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D102524

Added: 
    

Modified: 
    llvm/include/llvm/Demangle/RustDemangle.h
    llvm/lib/Demangle/RustDemangle.cpp
    llvm/test/Demangle/rust.test

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Demangle/RustDemangle.h b/llvm/include/llvm/Demangle/RustDemangle.h
index 3fe73803cf86..8797830cac69 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 3a9e75f33b9c..ebccafcae299 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;
+}
+
+// <const-data> = <hex-number>
+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('\'');
+}
+
 // <undisambiguated-identifier> = ["u"] <decimal-number> ["_"] <bytes>
 Identifier Demangler::parseIdentifier() {
   bool Punycode = consumeIf('u');

diff  --git a/llvm/test/Demangle/rust.test b/llvm/test/Demangle/rust.test
index 4caf92b3230e..89eda8ff1ebf 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


        


More information about the llvm-commits mailing list