Home | History | Annotate | Line # | Download | only in Demangle
      1 //===--- RustDemangle.h -----------------------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_DEMANGLE_RUSTDEMANGLE_H
     10 #define LLVM_DEMANGLE_RUSTDEMANGLE_H
     11 
     12 #include "llvm/Demangle/DemangleConfig.h"
     13 #include "llvm/Demangle/StringView.h"
     14 #include "llvm/Demangle/Utility.h"
     15 #include <cstdint>
     16 
     17 namespace llvm {
     18 namespace rust_demangle {
     19 
     20 using llvm::itanium_demangle::OutputStream;
     21 using llvm::itanium_demangle::StringView;
     22 using llvm::itanium_demangle::SwapAndRestore;
     23 
     24 struct Identifier {
     25   StringView Name;
     26   bool Punycode;
     27 
     28   bool empty() const { return Name.empty(); }
     29 };
     30 
     31 enum class BasicType {
     32   Bool,
     33   Char,
     34   I8,
     35   I16,
     36   I32,
     37   I64,
     38   I128,
     39   ISize,
     40   U8,
     41   U16,
     42   U32,
     43   U64,
     44   U128,
     45   USize,
     46   F32,
     47   F64,
     48   Str,
     49   Placeholder,
     50   Unit,
     51   Variadic,
     52   Never,
     53 };
     54 
     55 enum class InType {
     56   No,
     57   Yes,
     58 };
     59 
     60 class Demangler {
     61   // Maximum recursion level. Used to avoid stack overflow.
     62   size_t MaxRecursionLevel;
     63   // Current recursion level.
     64   size_t RecursionLevel;
     65 
     66   // Input string that is being demangled with "_R" prefix removed.
     67   StringView Input;
     68   // Position in the input string.
     69   size_t Position;
     70 
     71   // When true, print methods append the output to the stream.
     72   // When false, the output is suppressed.
     73   bool Print;
     74 
     75   // True if an error occurred.
     76   bool Error;
     77 
     78 public:
     79   // Demangled output.
     80   OutputStream Output;
     81 
     82   Demangler(size_t MaxRecursionLevel = 500);
     83 
     84   bool demangle(StringView MangledName);
     85 
     86 private:
     87   void demanglePath(InType InType);
     88   void demangleImplPath(InType InType);
     89   void demangleGenericArg();
     90   void demangleType();
     91   void demangleFnSig();
     92   void demangleConst();
     93   void demangleConstInt();
     94   void demangleConstBool();
     95   void demangleConstChar();
     96 
     97   Identifier parseIdentifier();
     98   uint64_t parseOptionalBase62Number(char Tag);
     99   uint64_t parseBase62Number();
    100   uint64_t parseDecimalNumber();
    101   uint64_t parseHexNumber(StringView &HexDigits);
    102 
    103   void print(char C) {
    104     if (Error || !Print)
    105       return;
    106 
    107     Output += C;
    108   }
    109 
    110   void print(StringView S) {
    111     if (Error || !Print)
    112       return;
    113 
    114     Output += S;
    115   }
    116 
    117   void printDecimalNumber(uint64_t N) {
    118     if (Error || !Print)
    119       return;
    120 
    121     Output << N;
    122   }
    123 
    124   void printBasicType(BasicType);
    125 
    126   char look() const {
    127     if (Error || Position >= Input.size())
    128       return 0;
    129 
    130     return Input[Position];
    131   }
    132 
    133   char consume() {
    134     if (Error || Position >= Input.size()) {
    135       Error = true;
    136       return 0;
    137     }
    138 
    139     return Input[Position++];
    140   }
    141 
    142   bool consumeIf(char Prefix) {
    143     if (Error || Position >= Input.size() || Input[Position] != Prefix)
    144       return false;
    145 
    146     Position += 1;
    147     return true;
    148   }
    149 
    150   /// Computes A + B. When computation wraps around sets the error and returns
    151   /// false. Otherwise assigns the result to A and returns true.
    152   bool addAssign(uint64_t &A, const uint64_t B) {
    153     if (A > std::numeric_limits<uint64_t>::max() - B) {
    154       Error = true;
    155       return false;
    156     }
    157 
    158     A += B;
    159     return true;
    160   }
    161 
    162   /// Computes A * B. When computation wraps around sets the error and returns
    163   /// false. Otherwise assigns the result to A and returns true.
    164   bool mulAssign(uint64_t &A, const uint64_t B) {
    165     if (B != 0 && A > std::numeric_limits<uint64_t>::max() / B) {
    166       Error = true;
    167       return false;
    168     }
    169 
    170     A *= B;
    171     return true;
    172   }
    173 };
    174 
    175 } // namespace rust_demangle
    176 } // namespace llvm
    177 
    178 #endif
    179