LLVM: lib/Demangle/DLangDemangle.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
19
20#include
21#include
22#include
23#include <string_view>
24
25using namespace llvm;
26using llvm::itanium_demangle::OutputBuffer;
27using llvm::itanium_demangle::starts_with;
28
29namespace {
30
31
32struct Demangler {
33
34
35
36 Demangler(std::string_view Mangled);
37
38
39
40
41
42
43
44
45
46
47 const char *parseMangle(OutputBuffer *Demangled);
48
49private:
50
51
52
53
54
55
56
57
58 void parseMangle(OutputBuffer *Demangled, std::string_view &Mangled);
59
60
61
62
63
64
65
66
67
68 void decodeNumber(std::string_view &Mangled, unsigned long &Ret);
69
70
71
72
73
74
75
76
77
78
79
80
81 bool decodeBackrefPos(std::string_view &Mangled, long &Ret);
82
83
84
85
86
87
88
89
90
91 bool decodeBackref(std::string_view &Mangled, std::string_view &Ret);
92
93
94
95
96
97
98
99
100
101 void parseSymbolBackref(OutputBuffer *Demangled, std::string_view &Mangled);
102
103
104
105
106
107
108
109
110 void parseTypeBackref(std::string_view &Mangled);
111
112
113
114
115
116
117
118
119 bool isSymbolName(std::string_view Mangled);
120
121
122
123
124
125
126
127
128 void parseIdentifier(OutputBuffer *Demangled, std::string_view &Mangled);
129
130
131
132
133
134
135
136
137
138
139 void parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
140 unsigned long Len);
141
142
143
144
145
146
147
148
149 void parseQualified(OutputBuffer *Demangled, std::string_view &Mangled);
150
151
152
153
154
155
156
157
158
159 bool parseType(std::string_view &Mangled);
160
161
162 const std::string_view Str;
163
164 int LastBackref;
165};
166
167}
168
169void Demangler::decodeNumber(std::string_view &Mangled, unsigned long &Ret) {
170
173 return;
174 }
175
176 if (!std::isdigit(Mangled.front())) {
178 return;
179 }
180
181 unsigned long Val = 0;
182
183 do {
184 unsigned long Digit = Mangled[0] - '0';
185
186
187 if (Val > (std::numeric_limits::max() - Digit) / 10) {
189 return;
190 }
191
192 Val = Val * 10 + Digit;
193 Mangled.remove_prefix(1);
194 } while (.empty() && std::isdigit(Mangled.front()));
195
198 return;
199 }
200
201 Ret = Val;
202}
203
204bool Demangler::decodeBackrefPos(std::string_view &Mangled, long &Ret) {
205
208 return false;
209 }
210
211
212
213
214
215
216
217
218
219
220 unsigned long Val = 0;
221
222 while (.empty() && std::isalpha(Mangled.front())) {
223
224 if (Val > (std::numeric_limits::max() - 25) / 26)
225 break;
226
227 Val *= 26;
228
229 if (Mangled[0] >= 'a' && Mangled[0] <= 'z') {
231 if ((long)Val <= 0)
232 break;
233 Ret = Val;
234 Mangled.remove_prefix(1);
235 return true;
236 }
237
239 Mangled.remove_prefix(1);
240 }
241
243 return false;
244}
245
246bool Demangler::decodeBackref(std::string_view &Mangled,
247 std::string_view &Ret) {
249 "Invalid back reference!");
250 Ret = {};
251
252
253 const char *Qpos = Mangled.data();
254 long RefPos;
255 Mangled.remove_prefix(1);
256
257 if (!decodeBackrefPos(Mangled, RefPos)) {
259 return false;
260 }
261
262 if (RefPos > Qpos - Str.data()) {
264 return false;
265 }
266
267
268 Ret = Qpos - RefPos;
269
270 return true;
271}
272
273void Demangler::parseSymbolBackref(OutputBuffer *Demangled,
274 std::string_view &Mangled) {
275
276
277
278
279 unsigned long Len;
280
281
282 std::string_view Backref;
283 if (!decodeBackref(Mangled, Backref)) {
285 return;
286 }
287
288
289 decodeNumber(Backref, Len);
290 if (Backref.empty() || Backref.length() < Len) {
292 return;
293 }
294
295 parseLName(Demangled, Backref, Len);
296 if (Backref.empty())
298}
299
300void Demangler::parseTypeBackref(std::string_view &Mangled) {
301
302
303
304
305
306
307
308 if (Mangled.data() - Str.data() >= LastBackref) {
310 return;
311 }
312
313 int SaveRefPos = LastBackref;
314 LastBackref = Mangled.data() - Str.data();
315
316
317 std::string_view Backref;
318 if (!decodeBackref(Mangled, Backref)) {
320 return;
321 }
322
323
324 if (Backref.empty()) {
326 return;
327 }
328
329
332
333 LastBackref = SaveRefPos;
334
335 if (Backref.empty())
337}
338
339bool Demangler::isSymbolName(std::string_view Mangled) {
340 long Ret;
341 const char *Qref = Mangled.data();
342
343 if (std::isdigit(Mangled.front()))
344 return true;
345
346
347
348 if (Mangled.front() != 'Q')
349 return false;
350
351 Mangled.remove_prefix(1);
352 bool Valid = decodeBackrefPos(Mangled, Ret);
353 if (!Valid || Ret > Qref - Str.data())
354 return false;
355
356 return std::isdigit(Qref[-Ret]);
357}
358
359void Demangler::parseMangle(OutputBuffer *Demangled,
360 std::string_view &Mangled) {
361
362
363
364
365
366
367
368
369
370 Mangled.remove_prefix(2);
371
372 parseQualified(Demangled, Mangled);
373
376 return;
377 }
378
379
380 if (Mangled.front() == 'Z') {
381 Mangled.remove_prefix(1);
384}
385
386void Demangler::parseQualified(OutputBuffer *Demangled,
387 std::string_view &Mangled) {
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403 size_t NotFirst = false;
404 do {
405
407 do
408 Mangled.remove_prefix(1);
410
411 continue;
412 }
413
414 if (NotFirst)
415 *Demangled << '.';
416 NotFirst = true;
417
418 parseIdentifier(Demangled, Mangled);
419 } while (.empty() && isSymbolName(Mangled));
420}
421
422void Demangler::parseIdentifier(OutputBuffer *Demangled,
423 std::string_view &Mangled) {
426 return;
427 }
428
429 if (Mangled.front() == 'Q')
430 return parseSymbolBackref(Demangled, Mangled);
431
432
433
434 unsigned long Len;
435 decodeNumber(Mangled, Len);
436
439 return;
440 }
441 if (!Len || Mangled.length() < Len) {
443 return;
444 }
445
446
447
448
449
450
451 if (Len >= 4 && starts_with(Mangled, "__S")) {
452 const size_t SuffixLen = Mangled.length() - Len;
453 std::string_view P = Mangled.substr(3);
454 while (P.length() > SuffixLen && std::isdigit(P.front()))
455 P.remove_prefix(1);
456 if (P.length() == SuffixLen) {
457
458 Mangled.remove_prefix(Len);
459 return parseIdentifier(Demangled, Mangled);
460 }
461
462
463 }
464
465 parseLName(Demangled, Mangled, Len);
466}
467
468bool Demangler::parseType(std::string_view &Mangled) {
471 return false;
472 }
473
474 switch (Mangled.front()) {
475
476
477
478
479
480
481
482 case 'i':
483 Mangled.remove_prefix(1);
484
485 return true;
486
487
488
489
490 case 'Q': {
491 parseTypeBackref(Mangled);
492 return true;
493 }
494
495 default:
497 return false;
498 }
499}
500
501void Demangler::parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
502 unsigned long Len) {
503 switch (Len) {
504 case 6:
506
507 Demangled->prepend("initializer for ");
509 Mangled.remove_prefix(Len);
510 return;
511 }
513
514 Demangled->prepend("vtable for ");
516 Mangled.remove_prefix(Len);
517 return;
518 }
519 break;
520
521 case 7:
523
524 Demangled->prepend("ClassInfo for ");
526 Mangled.remove_prefix(Len);
527 return;
528 }
529 break;
530
531 case 11:
532 if (starts_with(Mangled, "__InterfaceZ")) {
533
534 Demangled->prepend("Interface for ");
536 Mangled.remove_prefix(Len);
537 return;
538 }
539 break;
540
541 case 12:
542 if (starts_with(Mangled, "__ModuleInfoZ")) {
543
544 Demangled->prepend("ModuleInfo for ");
546 Mangled.remove_prefix(Len);
547 return;
548 }
549 break;
550 }
551
552 *Demangled << Mangled.substr(0, Len);
553 Mangled.remove_prefix(Len);
554}
555
556Demangler::Demangler(std::string_view Mangled)
557 : Str(Mangled), LastBackref(Mangled.length()) {}
558
559const char *Demangler::parseMangle(OutputBuffer *Demangled) {
560 std::string_view M(this->Str);
561 parseMangle(Demangled, M);
562 return M.data();
563}
564
566 if (MangledName.empty() || (MangledName, "_D"))
567 return nullptr;
568
570 if (MangledName == "_Dmain") {
571 Demangled << "D main";
572 } else {
573
574 Demangler D(MangledName);
575 const char *M = D.parseMangle(&Demangled);
576
577
578 if (M == nullptr || *M != '\0') {
579 std::free(Demangled.getBuffer());
580 return nullptr;
581 }
582 }
583
584
585
587 Demangled << '\0';
590 }
591
592 std::free(Demangled.getBuffer());
593 return nullptr;
594}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
OutputBuffer & prepend(std::string_view R)
void setCurrentPosition(size_t NewPos)
size_t getCurrentPosition() const
@ Valid
The data is already valid.
This is an optimization pass for GlobalISel generic memory operations.
DEMANGLE_ABI char * dlangDemangle(std::string_view MangledName)
Definition DLangDemangle.cpp:565
LLVM_ABI Type * parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)
Parse a type in the given string.