xref: /netbsd-src/external/apache2/llvm/dist/llvm/include/llvm/Demangle/RustDemangle.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 
emptyIdentifier28   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 
print(char C)103   void print(char C) {
104     if (Error || !Print)
105       return;
106 
107     Output += C;
108   }
109 
print(StringView S)110   void print(StringView S) {
111     if (Error || !Print)
112       return;
113 
114     Output += S;
115   }
116 
printDecimalNumber(uint64_t N)117   void printDecimalNumber(uint64_t N) {
118     if (Error || !Print)
119       return;
120 
121     Output << N;
122   }
123 
124   void printBasicType(BasicType);
125 
look()126   char look() const {
127     if (Error || Position >= Input.size())
128       return 0;
129 
130     return Input[Position];
131   }
132 
consume()133   char consume() {
134     if (Error || Position >= Input.size()) {
135       Error = true;
136       return 0;
137     }
138 
139     return Input[Position++];
140   }
141 
consumeIf(char Prefix)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.
addAssign(uint64_t & A,const uint64_t B)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.
mulAssign(uint64_t & A,const uint64_t B)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