File tree 3 files changed +80
-16
lines changed
3 files changed +80
-16
lines changed Original file line number Diff line number Diff line change 12
12
#include " llvm/Demangle/DemangleConfig.h"
13
13
#include " llvm/Demangle/StringView.h"
14
14
#include " llvm/Demangle/Utility.h"
15
+ #include < cstdint>
15
16
16
17
namespace llvm {
17
18
namespace rust_demangle {
18
19
19
20
using llvm::itanium_demangle::OutputStream;
20
21
using llvm::itanium_demangle::StringView;
22
+ using llvm::itanium_demangle::SwapAndRestore;
21
23
22
24
struct Identifier {
23
25
StringView Name;
@@ -52,17 +54,31 @@ class Demangler {
52
54
void demanglePath ();
53
55
54
56
Identifier parseIdentifier ();
55
- void parseOptionalBase62Number (char Tag);
57
+ uint64_t parseOptionalBase62Number (char Tag);
56
58
uint64_t parseBase62Number ();
57
59
uint64_t parseDecimalNumber ();
58
60
61
+ void print (char C) {
62
+ if (Error)
63
+ return ;
64
+
65
+ Output += C;
66
+ }
67
+
59
68
void print (StringView S) {
60
69
if (Error)
61
70
return ;
62
71
63
72
Output += S;
64
73
}
65
74
75
+ void printDecimalNumber (uint64_t N) {
76
+ if (Error)
77
+ return ;
78
+
79
+ Output << N;
80
+ }
81
+
66
82
char look () const {
67
83
if (Error || Position >= Input.size ())
68
84
return 0 ;
Original file line number Diff line number Diff line change @@ -132,7 +132,7 @@ void Demangler::demanglePath() {
132
132
Error = true ;
133
133
return ;
134
134
}
135
- RecursionLevel += 1 ;
135
+ SwapAndRestore< size_t > SaveRecursionLevel ( RecursionLevel, RecursionLevel + 1 ) ;
136
136
137
137
switch (consume ()) {
138
138
case ' C' : {
@@ -149,15 +149,31 @@ void Demangler::demanglePath() {
149
149
}
150
150
demanglePath ();
151
151
152
- parseOptionalBase62Number (' s' );
152
+ uint64_t Disambiguator = parseOptionalBase62Number (' s' );
153
153
Identifier Ident = parseIdentifier ();
154
154
155
- if (!Ident.empty ()) {
156
- // FIXME print special namespaces:
157
- // * "C" closures
158
- // * "S" shim
159
- print (" ::" );
160
- print (Ident.Name );
155
+ if (isUpper (NS)) {
156
+ // Special namespaces
157
+ print (" ::{" );
158
+ if (NS == ' C' )
159
+ print (" closure" );
160
+ else if (NS == ' S' )
161
+ print (" shim" );
162
+ else
163
+ print (NS);
164
+ if (!Ident.empty ()) {
165
+ print (" :" );
166
+ print (Ident.Name );
167
+ }
168
+ print (' #' );
169
+ printDecimalNumber (Disambiguator);
170
+ print (' }' );
171
+ } else {
172
+ // Implementation internal namespaces.
173
+ if (!Ident.empty ()) {
174
+ print (" ::" );
175
+ print (Ident.Name );
176
+ }
161
177
}
162
178
break ;
163
179
}
@@ -166,8 +182,6 @@ void Demangler::demanglePath() {
166
182
Error = true ;
167
183
break ;
168
184
}
169
-
170
- RecursionLevel -= 1 ;
171
185
}
172
186
173
187
// <undisambiguated-identifier> = ["u"] <decimal-number> ["_"] <bytes>
@@ -195,11 +209,16 @@ Identifier Demangler::parseIdentifier() {
195
209
}
196
210
197
211
// Parses optional base 62 number. The presence of a number is determined using
198
- // Tag.
199
- void Demangler::parseOptionalBase62Number (char Tag) {
200
- // Parsing result is currently unused.
201
- if (consumeIf (Tag))
202
- parseBase62Number ();
212
+ // Tag. Returns 0 when tag is absent and parsed value + 1 otherwise.
213
+ uint64_t Demangler::parseOptionalBase62Number (char Tag) {
214
+ if (!consumeIf (Tag))
215
+ return 0 ;
216
+
217
+ uint64_t N = parseBase62Number ();
218
+ if (Error || !addAssign (N, 1 ))
219
+ return 0 ;
220
+
221
+ return N;
203
222
}
204
223
205
224
// Parses base 62 number with <0-9a-zA-Z> as digits. Number is terminated by
Original file line number Diff line number Diff line change @@ -9,6 +9,30 @@ CHECK: hello::rust
9
9
CHECK: a::b::c
10
10
_RNvNvC1a1b1c
11
11
12
+ ; Closure namespace
13
+
14
+ CHECK: crate::{closure#0}
15
+ _RNCC5crate0
16
+
17
+ CHECK: crate::{closure#1}
18
+ _RNCC5crates_0
19
+
20
+ CHECK: crate::{closure:foo#0}
21
+ _RNCC5crate3foo
22
+
23
+ CHECK: crate::{closure:foo#1}
24
+ _RNCC5crates_3foo
25
+
26
+ ; Shim namespace
27
+
28
+ CHECK: crate::{shim:reify#0}
29
+ _RNSC5crate5reify
30
+
31
+ ; Unrecognized special namespace
32
+
33
+ CHECK: crate::{Z:ident#10}
34
+ _RNZC5crates8_5ident
35
+
12
36
; Invalid mangled characters
13
37
14
38
CHECK: _RNvC2a.1c
@@ -17,6 +41,11 @@ CHECK: _RNvC2a.1c
17
41
CHECK: _RNvC2a$1c
18
42
_RNvC2a$1c
19
43
44
+ ; Invalid namespace (not in [a-zA-Z]).
45
+
46
+ CHECK: _RN_C5crate4main
47
+ _RN_C5crate4main
48
+
20
49
; Invalid identifier length (UINT64_MAX + 3, which happens to be ok after a wraparound).
21
50
22
51
CHECK: _RNvC2ab18446744073709551618xy
You can’t perform that action at this time.
0 commit comments