[llvm] 2961f86 - [Demangle][Rust] Parse basic types

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Mon May 10 09:44:56 PDT 2021


Author: Tomasz Miąsko
Date: 2021-05-10T09:44:46-07:00
New Revision: 2961f86317f8560c948af8f38581e1ea5a9cfebf

URL: https://github.com/llvm/llvm-project/commit/2961f86317f8560c948af8f38581e1ea5a9cfebf
DIFF: https://github.com/llvm/llvm-project/commit/2961f86317f8560c948af8f38581e1ea5a9cfebf.diff

LOG: [Demangle][Rust] Parse basic types

Reviewed By: dblaikie

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

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 9bf938d3674da..9a8c3620250ae 100644
--- a/llvm/include/llvm/Demangle/RustDemangle.h
+++ b/llvm/include/llvm/Demangle/RustDemangle.h
@@ -52,6 +52,8 @@ class Demangler {
 
 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
index 213bf28948462..2687978218ffc 100644
--- a/llvm/lib/Demangle/RustDemangle.cpp
+++ b/llvm/lib/Demangle/RustDemangle.cpp
@@ -177,6 +177,17 @@ void Demangler::demanglePath() {
     }
     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 @@ void Demangler::demanglePath() {
   }
 }
 
+// <generic-arg> = <lifetime>
+//               | <type>
+//               | "K" <const>
+// <lifetime> = "L" <base-62-number>
+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
+};
+
+// <basic-type> = "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;
+}
+
+// <type> = | <basic-type>
+//          | <path>                      // named type
+//          | "A" <type> <const>          // [T; N]
+//          | "S" <type>                  // [T]
+//          | "T" {<type>} "E"            // (T1, T2, T3, ...)
+//          | "R" [<lifetime>] <type>     // &T
+//          | "Q" [<lifetime>] <type>     // &mut T
+//          | "P" <type>                  // *const T
+//          | "O" <type>                  // *mut T
+//          | "F" <fn-sig>                // fn(...) -> ...
+//          | "D" <dyn-bounds> <lifetime> // dyn Trait<Assoc = X> + Send + 'a
+//          | <backref>                   // backref
+void Demangler::demangleType() {
+  if (const char *BasicType = parseBasicType(consume())) {
+    print(BasicType);
+  } else {
+    // FIXME parse remaining productions.
+    Error = true;
+  }
+}
+
 // <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 7e3e543e8aa95..11012491e2026 100644
--- a/llvm/test/Demangle/rust.test
+++ b/llvm/test/Demangle/rust.test
@@ -33,6 +33,82 @@ CHECK: crate::{shim:reify#0}
 CHECK: crate::{Z:ident#10}
        _RNZC5crates8_5ident
 
+; Generic type arguments
+
+CHECK: generic::<_>
+       _RIC7genericpE
+
+CHECK: generic::<_, _>
+       _RIC7genericppE
+
+CHECK: generic::<_, _, _>
+       _RIC7genericpppE
+
+; Basic types
+
+CHECK: basic::<i8>
+       _RIC5basicaE
+
+CHECK: basic::<bool>
+       _RIC5basicbE
+
+CHECK: basic::<char>
+       _RIC5basiccE
+
+CHECK: basic::<f64>
+       _RIC5basicdE
+
+CHECK: basic::<str>
+       _RIC5basiceE
+
+CHECK: basic::<f32>
+       _RIC5basicfE
+
+CHECK: basic::<u8>
+       _RIC5basichE
+
+CHECK: basic::<isize>
+       _RIC5basiciE
+
+CHECK: basic::<usize>
+       _RIC5basicjE
+
+CHECK: basic::<i32>
+       _RIC5basiclE
+
+CHECK: basic::<u32>
+       _RIC5basicmE
+
+CHECK: basic::<i128>
+       _RIC5basicnE
+
+CHECK: basic::<u128>
+       _RIC5basicoE
+
+CHECK: basic::<_>
+       _RIC5basicpE
+
+CHECK: basic::<i16>
+       _RIC5basicsE
+
+CHECK: basic::<u16>
+       _RIC5basictE
+
+CHECK: basic::<()>
+       _RIC5basicuE
+
+CHECK: basic::<...>
+       _RIC5basicvE
+
+CHECK: basic::<i64>
+       _RIC5basicxE
+
+CHECK: basic::<u64>
+       _RIC5basicyE
+
+CHECK: basic::<!>
+       _RIC5basiczE
+
 ; Invalid mangled characters
 
 CHECK: _RNvC2a.1c


        


More information about the llvm-commits mailing list