blob: 43c1e57bf0e75cfc3569817760e6a25b3647903b [file] [log] [blame]
Rafael Espindolab940b662016-09-06 19:16:48 +00001//===- ItaniumDemangle.cpp ------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Reid Klecknerb2881f12016-09-06 19:39:56 +000010#include "llvm/Demangle/Demangle.h"
Rafael Espindolab940b662016-09-06 19:16:48 +000011
12// This file exports a single function: llvm::itanium_demangle.
13// It also has no dependencies on the rest of llvm. It is implemented this way
14// so that it can be easily reused in libcxxabi.
15
16#include <algorithm>
17#include <cctype>
18#include <cstdlib>
19#include <cstring>
20#include <numeric>
21#include <string>
22#include <vector>
23
24#ifdef _MSC_VER
25// snprintf is implemented in VS 2015
26#if _MSC_VER < 1900
27#define snprintf _snprintf_s
28#endif
29#endif
30
31enum {
32 unknown_error = -4,
33 invalid_args = -3,
34 invalid_mangled_name,
35 memory_alloc_failure,
36 success
37};
38
39template <class C>
40static const char *parse_type(const char *first, const char *last, C &db);
41template <class C>
42static const char *parse_encoding(const char *first, const char *last, C &db);
43template <class C>
44static const char *parse_name(const char *first, const char *last, C &db,
45 bool *ends_with_template_args = 0);
46template <class C>
47static const char *parse_expression(const char *first, const char *last, C &db);
48template <class C>
49static const char *parse_template_args(const char *first, const char *last,
50 C &db);
51template <class C>
52static const char *parse_operator_name(const char *first, const char *last,
53 C &db);
54template <class C>
55static const char *parse_unqualified_name(const char *first, const char *last,
56 C &db);
57template <class C>
58static const char *parse_decltype(const char *first, const char *last, C &db);
59
60// <number> ::= [n] <non-negative decimal integer>
61
62static const char *parse_number(const char *first, const char *last) {
63 if (first != last) {
64 const char *t = first;
65 if (*t == 'n')
66 ++t;
67 if (t != last) {
68 if (*t == '0') {
69 first = t + 1;
70 } else if ('1' <= *t && *t <= '9') {
71 first = t + 1;
72 while (first != last && std::isdigit(*first))
73 ++first;
74 }
75 }
76 }
77 return first;
78}
79
80namespace {
81template <class Float> struct float_data;
82
83template <> struct float_data<float> {
84 static const size_t mangled_size = 8;
85 static const size_t max_demangled_size = 24;
86 static const char *spec;
87};
88const char *float_data<float>::spec = "%af";
89
90template <> struct float_data<double> {
91 static const size_t mangled_size = 16;
92 static const size_t max_demangled_size = 32;
93 static const char *spec;
94};
95
96const char *float_data<double>::spec = "%a";
97
98template <> struct float_data<long double> {
99#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
100 defined(__wasm__)
101 static const size_t mangled_size = 32;
102#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
103 static const size_t mangled_size = 16;
104#else
105 static const size_t mangled_size =
106 20; // May need to be adjusted to 16 or 24 on other platforms
107#endif
108 static const size_t max_demangled_size = 40;
109 static const char *spec;
110};
111
112const char *float_data<long double>::spec = "%LaL";
113}
114
115template <class Float, class C>
116static const char *parse_floating_number(const char *first, const char *last,
117 C &db) {
118 const size_t N = float_data<Float>::mangled_size;
119 if (static_cast<std::size_t>(last - first) > N) {
120 last = first + N;
121 union {
122 Float value;
123 char buf[sizeof(Float)];
124 };
125 const char *t = first;
126 char *e = buf;
127 for (; t != last; ++t, ++e) {
128 if (!isxdigit(*t))
129 return first;
130 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
131 : static_cast<unsigned>(*t - 'a' + 10);
132 ++t;
133 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
134 : static_cast<unsigned>(*t - 'a' + 10);
135 *e = static_cast<char>((d1 << 4) + d0);
136 }
137 if (*t == 'E') {
138#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
139 std::reverse(buf, e);
140#endif
141 char num[float_data<Float>::max_demangled_size] = {0};
142 int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);
143 if (static_cast<std::size_t>(n) >= sizeof(num))
144 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000145 db.names.push_back(std::string(num, static_cast<std::size_t>(n)));
Rafael Espindolab940b662016-09-06 19:16:48 +0000146 first = t + 1;
147 }
148 }
149 return first;
150}
151
152// <source-name> ::= <positive length number> <identifier>
153
154template <class C>
155static const char *parse_source_name(const char *first, const char *last,
156 C &db) {
157 if (first != last) {
158 char c = *first;
159 if (isdigit(c) && first + 1 != last) {
160 const char *t = first + 1;
161 size_t n = static_cast<size_t>(c - '0');
162 for (c = *t; isdigit(c); c = *t) {
163 n = n * 10 + static_cast<size_t>(c - '0');
164 if (++t == last)
165 return first;
166 }
167 if (static_cast<size_t>(last - t) >= n) {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000168 std::string r(t, n);
Rafael Espindolab940b662016-09-06 19:16:48 +0000169 if (r.substr(0, 10) == "_GLOBAL__N")
170 db.names.push_back("(anonymous namespace)");
171 else
172 db.names.push_back(std::move(r));
173 first = t + n;
174 }
175 }
176 }
177 return first;
178}
179
180// <substitution> ::= S <seq-id> _
181// ::= S_
182// <substitution> ::= Sa # ::std::allocator
183// <substitution> ::= Sb # ::std::basic_string
184// <substitution> ::= Ss # ::std::basic_string < char,
185// ::std::char_traits<char>,
186// ::std::allocator<char> >
187// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
188// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
189// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
190
191template <class C>
192static const char *parse_substitution(const char *first, const char *last,
193 C &db) {
194 if (last - first >= 2) {
195 if (*first == 'S') {
196 switch (first[1]) {
197 case 'a':
198 db.names.push_back("std::allocator");
199 first += 2;
200 break;
201 case 'b':
202 db.names.push_back("std::basic_string");
203 first += 2;
204 break;
205 case 's':
206 db.names.push_back("std::string");
207 first += 2;
208 break;
209 case 'i':
210 db.names.push_back("std::istream");
211 first += 2;
212 break;
213 case 'o':
214 db.names.push_back("std::ostream");
215 first += 2;
216 break;
217 case 'd':
218 db.names.push_back("std::iostream");
219 first += 2;
220 break;
221 case '_':
222 if (!db.subs.empty()) {
223 for (const auto &n : db.subs.front())
224 db.names.push_back(n);
225 first += 2;
226 }
227 break;
228 default:
229 if (std::isdigit(first[1]) || std::isupper(first[1])) {
230 size_t sub = 0;
231 const char *t = first + 1;
232 if (std::isdigit(*t))
233 sub = static_cast<size_t>(*t - '0');
234 else
235 sub = static_cast<size_t>(*t - 'A') + 10;
236 for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t) {
237 sub *= 36;
238 if (std::isdigit(*t))
239 sub += static_cast<size_t>(*t - '0');
240 else
241 sub += static_cast<size_t>(*t - 'A') + 10;
242 }
243 if (t == last || *t != '_')
244 return first;
245 ++sub;
246 if (sub < db.subs.size()) {
247 for (const auto &n : db.subs[sub])
248 db.names.push_back(n);
249 first = t + 1;
250 }
251 }
252 break;
253 }
254 }
255 }
256 return first;
257}
258
259// <builtin-type> ::= v # void
260// ::= w # wchar_t
261// ::= b # bool
262// ::= c # char
263// ::= a # signed char
264// ::= h # unsigned char
265// ::= s # short
266// ::= t # unsigned short
267// ::= i # int
268// ::= j # unsigned int
269// ::= l # long
270// ::= m # unsigned long
271// ::= x # long long, __int64
272// ::= y # unsigned long long, __int64
273// ::= n # __int128
274// ::= o # unsigned __int128
275// ::= f # float
276// ::= d # double
277// ::= e # long double, __float80
278// ::= g # __float128
279// ::= z # ellipsis
280// ::= Dd # IEEE 754r decimal floating point (64 bits)
281// ::= De # IEEE 754r decimal floating point (128 bits)
282// ::= Df # IEEE 754r decimal floating point (32 bits)
283// ::= Dh # IEEE 754r half-precision floating point (16 bits)
284// ::= Di # char32_t
285// ::= Ds # char16_t
286// ::= Da # auto (in dependent new-expressions)
287// ::= Dc # decltype(auto)
288// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
289// ::= u <source-name> # vendor extended type
290
291template <class C>
292static const char *parse_builtin_type(const char *first, const char *last,
293 C &db) {
294 if (first != last) {
295 switch (*first) {
296 case 'v':
297 db.names.push_back("void");
298 ++first;
299 break;
300 case 'w':
301 db.names.push_back("wchar_t");
302 ++first;
303 break;
304 case 'b':
305 db.names.push_back("bool");
306 ++first;
307 break;
308 case 'c':
309 db.names.push_back("char");
310 ++first;
311 break;
312 case 'a':
313 db.names.push_back("signed char");
314 ++first;
315 break;
316 case 'h':
317 db.names.push_back("unsigned char");
318 ++first;
319 break;
320 case 's':
321 db.names.push_back("short");
322 ++first;
323 break;
324 case 't':
325 db.names.push_back("unsigned short");
326 ++first;
327 break;
328 case 'i':
329 db.names.push_back("int");
330 ++first;
331 break;
332 case 'j':
333 db.names.push_back("unsigned int");
334 ++first;
335 break;
336 case 'l':
337 db.names.push_back("long");
338 ++first;
339 break;
340 case 'm':
341 db.names.push_back("unsigned long");
342 ++first;
343 break;
344 case 'x':
345 db.names.push_back("long long");
346 ++first;
347 break;
348 case 'y':
349 db.names.push_back("unsigned long long");
350 ++first;
351 break;
352 case 'n':
353 db.names.push_back("__int128");
354 ++first;
355 break;
356 case 'o':
357 db.names.push_back("unsigned __int128");
358 ++first;
359 break;
360 case 'f':
361 db.names.push_back("float");
362 ++first;
363 break;
364 case 'd':
365 db.names.push_back("double");
366 ++first;
367 break;
368 case 'e':
369 db.names.push_back("long double");
370 ++first;
371 break;
372 case 'g':
373 db.names.push_back("__float128");
374 ++first;
375 break;
376 case 'z':
377 db.names.push_back("...");
378 ++first;
379 break;
380 case 'u': {
381 const char *t = parse_source_name(first + 1, last, db);
382 if (t != first + 1)
383 first = t;
384 } break;
385 case 'D':
386 if (first + 1 != last) {
387 switch (first[1]) {
388 case 'd':
389 db.names.push_back("decimal64");
390 first += 2;
391 break;
392 case 'e':
393 db.names.push_back("decimal128");
394 first += 2;
395 break;
396 case 'f':
397 db.names.push_back("decimal32");
398 first += 2;
399 break;
400 case 'h':
401 db.names.push_back("decimal16");
402 first += 2;
403 break;
404 case 'i':
405 db.names.push_back("char32_t");
406 first += 2;
407 break;
408 case 's':
409 db.names.push_back("char16_t");
410 first += 2;
411 break;
412 case 'a':
413 db.names.push_back("auto");
414 first += 2;
415 break;
416 case 'c':
417 db.names.push_back("decltype(auto)");
418 first += 2;
419 break;
420 case 'n':
421 db.names.push_back("std::nullptr_t");
422 first += 2;
423 break;
424 }
425 }
426 break;
427 }
428 }
429 return first;
430}
431
432// <CV-qualifiers> ::= [r] [V] [K]
433
434static const char *parse_cv_qualifiers(const char *first, const char *last,
435 unsigned &cv) {
436 cv = 0;
437 if (first != last) {
438 if (*first == 'r') {
439 cv |= 4;
440 ++first;
441 }
442 if (*first == 'V') {
443 cv |= 2;
444 ++first;
445 }
446 if (*first == 'K') {
447 cv |= 1;
448 ++first;
449 }
450 }
451 return first;
452}
453
454// <template-param> ::= T_ # first template parameter
455// ::= T <parameter-2 non-negative number> _
456
457template <class C>
458static const char *parse_template_param(const char *first, const char *last,
459 C &db) {
460 if (last - first >= 2) {
461 if (*first == 'T') {
462 if (first[1] == '_') {
463 if (db.template_param.empty())
464 return first;
465 if (!db.template_param.back().empty()) {
466 for (auto &t : db.template_param.back().front())
467 db.names.push_back(t);
468 first += 2;
469 } else {
470 db.names.push_back("T_");
471 first += 2;
472 db.fix_forward_references = true;
473 }
474 } else if (isdigit(first[1])) {
475 const char *t = first + 1;
476 size_t sub = static_cast<size_t>(*t - '0');
477 for (++t; t != last && isdigit(*t); ++t) {
478 sub *= 10;
479 sub += static_cast<size_t>(*t - '0');
480 }
481 if (t == last || *t != '_' || db.template_param.empty())
482 return first;
483 ++sub;
484 if (sub < db.template_param.back().size()) {
485 for (auto &temp : db.template_param.back()[sub])
486 db.names.push_back(temp);
487 first = t + 1;
488 } else {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000489 db.names.push_back(std::string(first, t + 1));
Rafael Espindolab940b662016-09-06 19:16:48 +0000490 first = t + 1;
491 db.fix_forward_references = true;
492 }
493 }
494 }
495 }
496 return first;
497}
498
499// cc <type> <expression> # const_cast<type>
500// (expression)
501
502template <class C>
503static const char *parse_const_cast_expr(const char *first, const char *last,
504 C &db) {
505 if (last - first >= 3 && first[0] == 'c' && first[1] == 'c') {
506 const char *t = parse_type(first + 2, last, db);
507 if (t != first + 2) {
508 const char *t1 = parse_expression(t, last, db);
509 if (t1 != t) {
510 if (db.names.size() < 2)
511 return first;
512 auto expr = db.names.back().move_full();
513 db.names.pop_back();
514 if (db.names.empty())
515 return first;
516 db.names.back() =
517 "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
518 first = t1;
519 }
520 }
521 }
522 return first;
523}
524
525// dc <type> <expression> # dynamic_cast<type>
526// (expression)
527
528template <class C>
529static const char *parse_dynamic_cast_expr(const char *first, const char *last,
530 C &db) {
531 if (last - first >= 3 && first[0] == 'd' && first[1] == 'c') {
532 const char *t = parse_type(first + 2, last, db);
533 if (t != first + 2) {
534 const char *t1 = parse_expression(t, last, db);
535 if (t1 != t) {
536 if (db.names.size() < 2)
537 return first;
538 auto expr = db.names.back().move_full();
539 db.names.pop_back();
540 if (db.names.empty())
541 return first;
542 db.names.back() =
543 "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";
544 first = t1;
545 }
546 }
547 }
548 return first;
549}
550
551// rc <type> <expression> # reinterpret_cast<type>
552// (expression)
553
554template <class C>
555static const char *parse_reinterpret_cast_expr(const char *first,
556 const char *last, C &db) {
557 if (last - first >= 3 && first[0] == 'r' && first[1] == 'c') {
558 const char *t = parse_type(first + 2, last, db);
559 if (t != first + 2) {
560 const char *t1 = parse_expression(t, last, db);
561 if (t1 != t) {
562 if (db.names.size() < 2)
563 return first;
564 auto expr = db.names.back().move_full();
565 db.names.pop_back();
566 if (db.names.empty())
567 return first;
568 db.names.back() = "reinterpret_cast<" + db.names.back().move_full() +
569 ">(" + expr + ")";
570 first = t1;
571 }
572 }
573 }
574 return first;
575}
576
577// sc <type> <expression> # static_cast<type>
578// (expression)
579
580template <class C>
581static const char *parse_static_cast_expr(const char *first, const char *last,
582 C &db) {
583 if (last - first >= 3 && first[0] == 's' && first[1] == 'c') {
584 const char *t = parse_type(first + 2, last, db);
585 if (t != first + 2) {
586 const char *t1 = parse_expression(t, last, db);
587 if (t1 != t) {
588 if (db.names.size() < 2)
589 return first;
590 auto expr = db.names.back().move_full();
591 db.names.pop_back();
592 db.names.back() =
593 "static_cast<" + db.names.back().move_full() + ">(" + expr + ")";
594 first = t1;
595 }
596 }
597 }
598 return first;
599}
600
601// sp <expression> # pack expansion
602
603template <class C>
604static const char *parse_pack_expansion(const char *first, const char *last,
605 C &db) {
606 if (last - first >= 3 && first[0] == 's' && first[1] == 'p') {
607 const char *t = parse_expression(first + 2, last, db);
608 if (t != first + 2)
609 first = t;
610 }
611 return first;
612}
613
614// st <type> # sizeof (a type)
615
616template <class C>
617static const char *parse_sizeof_type_expr(const char *first, const char *last,
618 C &db) {
619 if (last - first >= 3 && first[0] == 's' && first[1] == 't') {
620 const char *t = parse_type(first + 2, last, db);
621 if (t != first + 2) {
622 if (db.names.empty())
623 return first;
624 db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
625 first = t;
626 }
627 }
628 return first;
629}
630
631// sz <expr> # sizeof (a expression)
632
633template <class C>
634static const char *parse_sizeof_expr_expr(const char *first, const char *last,
635 C &db) {
636 if (last - first >= 3 && first[0] == 's' && first[1] == 'z') {
637 const char *t = parse_expression(first + 2, last, db);
638 if (t != first + 2) {
639 if (db.names.empty())
640 return first;
641 db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
642 first = t;
643 }
644 }
645 return first;
646}
647
648// sZ <template-param> # size of a parameter
649// pack
650
651template <class C>
652static const char *parse_sizeof_param_pack_expr(const char *first,
653 const char *last, C &db) {
654 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' &&
655 first[2] == 'T') {
656 size_t k0 = db.names.size();
657 const char *t = parse_template_param(first + 2, last, db);
658 size_t k1 = db.names.size();
659 if (t != first + 2) {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000660 std::string tmp("sizeof...(");
Rafael Espindolab940b662016-09-06 19:16:48 +0000661 size_t k = k0;
662 if (k != k1) {
663 tmp += db.names[k].move_full();
664 for (++k; k != k1; ++k)
665 tmp += ", " + db.names[k].move_full();
666 }
667 tmp += ")";
668 for (; k1 != k0; --k1)
669 db.names.pop_back();
670 db.names.push_back(std::move(tmp));
671 first = t;
672 }
673 }
674 return first;
675}
676
677// <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter
678// ::= fp <top-level CV-qualifiers> <parameter-2 non-negative
679// number> _ # L == 0, second and later parameters
680// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers>
681// _ # L > 0, first parameter
682// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers>
683// <parameter-2 non-negative number> _ # L > 0, second and
684// later parameters
685
686template <class C>
687static const char *parse_function_param(const char *first, const char *last,
688 C &db) {
689 if (last - first >= 3 && *first == 'f') {
690 if (first[1] == 'p') {
691 unsigned cv;
692 const char *t = parse_cv_qualifiers(first + 2, last, cv);
693 const char *t1 = parse_number(t, last);
694 if (t1 != last && *t1 == '_') {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000695 db.names.push_back("fp" + std::string(t, t1));
Rafael Espindolab940b662016-09-06 19:16:48 +0000696 first = t1 + 1;
697 }
698 } else if (first[1] == 'L') {
699 unsigned cv;
700 const char *t0 = parse_number(first + 2, last);
701 if (t0 != last && *t0 == 'p') {
702 ++t0;
703 const char *t = parse_cv_qualifiers(t0, last, cv);
704 const char *t1 = parse_number(t, last);
705 if (t1 != last && *t1 == '_') {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +0000706 db.names.push_back("fp" + std::string(t, t1));
Rafael Espindolab940b662016-09-06 19:16:48 +0000707 first = t1 + 1;
708 }
709 }
710 }
711 }
712 return first;
713}
714
715// sZ <function-param> # size of a function
716// parameter pack
717
718template <class C>
719static const char *parse_sizeof_function_param_pack_expr(const char *first,
720 const char *last,
721 C &db) {
722 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' &&
723 first[2] == 'f') {
724 const char *t = parse_function_param(first + 2, last, db);
725 if (t != first + 2) {
726 if (db.names.empty())
727 return first;
728 db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
729 first = t;
730 }
731 }
732 return first;
733}
734
735// te <expression> # typeid (expression)
736// ti <type> # typeid (type)
737
738template <class C>
739static const char *parse_typeid_expr(const char *first, const char *last,
740 C &db) {
741 if (last - first >= 3 && first[0] == 't' &&
742 (first[1] == 'e' || first[1] == 'i')) {
743 const char *t;
744 if (first[1] == 'e')
745 t = parse_expression(first + 2, last, db);
746 else
747 t = parse_type(first + 2, last, db);
748 if (t != first + 2) {
749 if (db.names.empty())
750 return first;
751 db.names.back() = "typeid(" + db.names.back().move_full() + ")";
752 first = t;
753 }
754 }
755 return first;
756}
757
758// tw <expression> # throw expression
759
760template <class C>
761static const char *parse_throw_expr(const char *first, const char *last,
762 C &db) {
763 if (last - first >= 3 && first[0] == 't' && first[1] == 'w') {
764 const char *t = parse_expression(first + 2, last, db);
765 if (t != first + 2) {
766 if (db.names.empty())
767 return first;
768 db.names.back() = "throw " + db.names.back().move_full();
769 first = t;
770 }
771 }
772 return first;
773}
774
775// ds <expression> <expression> # expr.*expr
776
777template <class C>
778static const char *parse_dot_star_expr(const char *first, const char *last,
779 C &db) {
780 if (last - first >= 3 && first[0] == 'd' && first[1] == 's') {
781 const char *t = parse_expression(first + 2, last, db);
782 if (t != first + 2) {
783 const char *t1 = parse_expression(t, last, db);
784 if (t1 != t) {
785 if (db.names.size() < 2)
786 return first;
787 auto expr = db.names.back().move_full();
788 db.names.pop_back();
789 db.names.back().first += ".*" + expr;
790 first = t1;
791 }
792 }
793 }
794 return first;
795}
796
797// <simple-id> ::= <source-name> [ <template-args> ]
798
799template <class C>
800static const char *parse_simple_id(const char *first, const char *last, C &db) {
801 if (first != last) {
802 const char *t = parse_source_name(first, last, db);
803 if (t != first) {
804 const char *t1 = parse_template_args(t, last, db);
805 if (t1 != t) {
806 if (db.names.size() < 2)
807 return first;
808 auto args = db.names.back().move_full();
809 db.names.pop_back();
810 db.names.back().first += std::move(args);
811 }
812 first = t1;
813 } else
814 first = t;
815 }
816 return first;
817}
818
819// <unresolved-type> ::= <template-param>
820// ::= <decltype>
821// ::= <substitution>
822
823template <class C>
824static const char *parse_unresolved_type(const char *first, const char *last,
825 C &db) {
826 if (first != last) {
827 const char *t = first;
828 switch (*first) {
829 case 'T': {
830 size_t k0 = db.names.size();
831 t = parse_template_param(first, last, db);
832 size_t k1 = db.names.size();
833 if (t != first && k1 == k0 + 1) {
834 db.subs.push_back(
835 typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
836 first = t;
837 } else {
838 for (; k1 != k0; --k1)
839 db.names.pop_back();
840 }
841 break;
842 }
843 case 'D':
844 t = parse_decltype(first, last, db);
845 if (t != first) {
846 if (db.names.empty())
847 return first;
848 db.subs.push_back(
849 typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
850 first = t;
851 }
852 break;
853 case 'S':
854 t = parse_substitution(first, last, db);
855 if (t != first)
856 first = t;
857 else {
858 if (last - first > 2 && first[1] == 't') {
859 t = parse_unqualified_name(first + 2, last, db);
860 if (t != first + 2) {
861 if (db.names.empty())
862 return first;
863 db.names.back().first.insert(0, "std::");
864 db.subs.push_back(typename C::sub_type(1, db.names.back(),
865 db.names.get_allocator()));
866 first = t;
867 }
868 }
869 }
870 break;
871 }
872 }
873 return first;
874}
875
876// <destructor-name> ::= <unresolved-type> # e.g.,
877// ~T or ~decltype(f())
878// ::= <simple-id> # e.g.,
879// ~A<2*N>
880
881template <class C>
882static const char *parse_destructor_name(const char *first, const char *last,
883 C &db) {
884 if (first != last) {
885 const char *t = parse_unresolved_type(first, last, db);
886 if (t == first)
887 t = parse_simple_id(first, last, db);
888 if (t != first) {
889 if (db.names.empty())
890 return first;
891 db.names.back().first.insert(0, "~");
892 first = t;
893 }
894 }
895 return first;
896}
897
898// <base-unresolved-name> ::= <simple-id> #
899// unresolved name
900// extension ::= <operator-name> #
901// unresolved operator-function-id
902// extension ::= <operator-name> <template-args> #
903// unresolved operator template-id
904// ::= on <operator-name> #
905// unresolved operator-function-id
906// ::= on <operator-name> <template-args> #
907// unresolved operator template-id
908// ::= dn <destructor-name> #
909// destructor or pseudo-destructor;
910// #
911// e.g.
912// ~X or
913// ~X<N-1>
914
915template <class C>
916static const char *parse_base_unresolved_name(const char *first,
917 const char *last, C &db) {
918 if (last - first >= 2) {
919 if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n') {
920 if (first[0] == 'o') {
921 const char *t = parse_operator_name(first + 2, last, db);
922 if (t != first + 2) {
923 first = parse_template_args(t, last, db);
924 if (first != t) {
925 if (db.names.size() < 2)
926 return first;
927 auto args = db.names.back().move_full();
928 db.names.pop_back();
929 db.names.back().first += std::move(args);
930 }
931 }
932 } else {
933 const char *t = parse_destructor_name(first + 2, last, db);
934 if (t != first + 2)
935 first = t;
936 }
937 } else {
938 const char *t = parse_simple_id(first, last, db);
939 if (t == first) {
940 t = parse_operator_name(first, last, db);
941 if (t != first) {
942 first = parse_template_args(t, last, db);
943 if (first != t) {
944 if (db.names.size() < 2)
945 return first;
946 auto args = db.names.back().move_full();
947 db.names.pop_back();
948 db.names.back().first += std::move(args);
949 }
950 }
951 } else
952 first = t;
953 }
954 }
955 return first;
956}
957
958// <unresolved-qualifier-level> ::= <simple-id>
959
960template <class C>
961static const char *parse_unresolved_qualifier_level(const char *first,
962 const char *last, C &db) {
963 return parse_simple_id(first, last, db);
964}
965
966// <unresolved-name>
967// extension ::= srN <unresolved-type> [<template-args>]
968// <unresolved-qualifier-level>* E <base-unresolved-name>
969// ::= [gs] <base-unresolved-name> # x or
970// (with "gs") ::x
971// ::= [gs] sr <unresolved-qualifier-level>+ E
972// <base-unresolved-name>
973// # A::x,
974// N::y,
975// A<T>::z;
976// "gs"
977// means
978// leading
979// "::"
980// ::= sr <unresolved-type> <base-unresolved-name> # T::x
981// / decltype(p)::x
982// extension ::= sr <unresolved-type> <template-args>
983// <base-unresolved-name>
984// #
985// T::N::x
986// /decltype(p)::N::x
987// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E
988// <base-unresolved-name>
989
990template <class C>
991static const char *parse_unresolved_name(const char *first, const char *last,
992 C &db) {
993 if (last - first > 2) {
994 const char *t = first;
995 bool global = false;
996 if (t[0] == 'g' && t[1] == 's') {
997 global = true;
998 t += 2;
999 }
1000 const char *t2 = parse_base_unresolved_name(t, last, db);
1001 if (t2 != t) {
1002 if (global) {
1003 if (db.names.empty())
1004 return first;
1005 db.names.back().first.insert(0, "::");
1006 }
1007 first = t2;
1008 } else if (last - t > 2 && t[0] == 's' && t[1] == 'r') {
1009 if (t[2] == 'N') {
1010 t += 3;
1011 const char *t1 = parse_unresolved_type(t, last, db);
1012 if (t1 == t || t1 == last)
1013 return first;
1014 t = t1;
1015 t1 = parse_template_args(t, last, db);
1016 if (t1 != t) {
1017 if (db.names.size() < 2)
1018 return first;
1019 auto args = db.names.back().move_full();
1020 db.names.pop_back();
1021 db.names.back().first += std::move(args);
1022 t = t1;
1023 if (t == last) {
1024 db.names.pop_back();
1025 return first;
1026 }
1027 }
1028 while (*t != 'E') {
1029 t1 = parse_unresolved_qualifier_level(t, last, db);
1030 if (t1 == t || t1 == last || db.names.size() < 2)
1031 return first;
1032 auto s = db.names.back().move_full();
1033 db.names.pop_back();
1034 db.names.back().first += "::" + std::move(s);
1035 t = t1;
1036 }
1037 ++t;
1038 t1 = parse_base_unresolved_name(t, last, db);
1039 if (t1 == t) {
1040 if (!db.names.empty())
1041 db.names.pop_back();
1042 return first;
1043 }
1044 if (db.names.size() < 2)
1045 return first;
1046 auto s = db.names.back().move_full();
1047 db.names.pop_back();
1048 db.names.back().first += "::" + std::move(s);
1049 first = t1;
1050 } else {
1051 t += 2;
1052 const char *t1 = parse_unresolved_type(t, last, db);
1053 if (t1 != t) {
1054 t = t1;
1055 t1 = parse_template_args(t, last, db);
1056 if (t1 != t) {
1057 if (db.names.size() < 2)
1058 return first;
1059 auto args = db.names.back().move_full();
1060 db.names.pop_back();
1061 db.names.back().first += std::move(args);
1062 t = t1;
1063 }
1064 t1 = parse_base_unresolved_name(t, last, db);
1065 if (t1 == t) {
1066 if (!db.names.empty())
1067 db.names.pop_back();
1068 return first;
1069 }
1070 if (db.names.size() < 2)
1071 return first;
1072 auto s = db.names.back().move_full();
1073 db.names.pop_back();
1074 db.names.back().first += "::" + std::move(s);
1075 first = t1;
1076 } else {
1077 t1 = parse_unresolved_qualifier_level(t, last, db);
1078 if (t1 == t || t1 == last)
1079 return first;
1080 t = t1;
1081 if (global) {
1082 if (db.names.empty())
1083 return first;
1084 db.names.back().first.insert(0, "::");
1085 }
1086 while (*t != 'E') {
1087 t1 = parse_unresolved_qualifier_level(t, last, db);
1088 if (t1 == t || t1 == last || db.names.size() < 2)
1089 return first;
1090 auto s = db.names.back().move_full();
1091 db.names.pop_back();
1092 db.names.back().first += "::" + std::move(s);
1093 t = t1;
1094 }
1095 ++t;
1096 t1 = parse_base_unresolved_name(t, last, db);
1097 if (t1 == t) {
1098 if (!db.names.empty())
1099 db.names.pop_back();
1100 return first;
1101 }
1102 if (db.names.size() < 2)
1103 return first;
1104 auto s = db.names.back().move_full();
1105 db.names.pop_back();
1106 db.names.back().first += "::" + std::move(s);
1107 first = t1;
1108 }
1109 }
1110 }
1111 }
1112 return first;
1113}
1114
1115// dt <expression> <unresolved-name> # expr.name
1116
1117template <class C>
1118static const char *parse_dot_expr(const char *first, const char *last, C &db) {
1119 if (last - first >= 3 && first[0] == 'd' && first[1] == 't') {
1120 const char *t = parse_expression(first + 2, last, db);
1121 if (t != first + 2) {
1122 const char *t1 = parse_unresolved_name(t, last, db);
1123 if (t1 != t) {
1124 if (db.names.size() < 2)
1125 return first;
1126 auto name = db.names.back().move_full();
1127 db.names.pop_back();
1128 if (db.names.empty())
1129 return first;
1130 db.names.back().first += "." + name;
1131 first = t1;
1132 }
1133 }
1134 }
1135 return first;
1136}
1137
1138// cl <expression>+ E # call
1139
1140template <class C>
1141static const char *parse_call_expr(const char *first, const char *last, C &db) {
1142 if (last - first >= 4 && first[0] == 'c' && first[1] == 'l') {
1143 const char *t = parse_expression(first + 2, last, db);
1144 if (t != first + 2) {
1145 if (t == last)
1146 return first;
1147 if (db.names.empty())
1148 return first;
1149 db.names.back().first += db.names.back().second;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001150 db.names.back().second = std::string();
Rafael Espindolab940b662016-09-06 19:16:48 +00001151 db.names.back().first.append("(");
1152 bool first_expr = true;
1153 while (*t != 'E') {
1154 const char *t1 = parse_expression(t, last, db);
1155 if (t1 == t || t1 == last)
1156 return first;
1157 if (db.names.empty())
1158 return first;
1159 auto tmp = db.names.back().move_full();
1160 db.names.pop_back();
1161 if (!tmp.empty()) {
1162 if (db.names.empty())
1163 return first;
1164 if (!first_expr) {
1165 db.names.back().first.append(", ");
1166 first_expr = false;
1167 }
1168 db.names.back().first.append(tmp);
1169 }
1170 t = t1;
1171 }
1172 ++t;
1173 if (db.names.empty())
1174 return first;
1175 db.names.back().first.append(")");
1176 first = t;
1177 }
1178 }
1179 return first;
1180}
1181
1182// [gs] nw <expression>* _ <type> E # new (expr-list) type
1183// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type
1184// (init)
1185// [gs] na <expression>* _ <type> E # new[] (expr-list) type
1186// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type
1187// (init)
1188// <initializer> ::= pi <expression>* E # parenthesized
1189// initialization
1190
1191template <class C>
1192static const char *parse_new_expr(const char *first, const char *last, C &db) {
1193 if (last - first >= 4) {
1194 const char *t = first;
1195 bool parsed_gs = false;
1196 if (t[0] == 'g' && t[1] == 's') {
1197 t += 2;
1198 parsed_gs = true;
1199 }
1200 if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a')) {
1201 bool is_array = t[1] == 'a';
1202 t += 2;
1203 if (t == last)
1204 return first;
1205 bool has_expr_list = false;
1206 bool first_expr = true;
1207 while (*t != '_') {
1208 const char *t1 = parse_expression(t, last, db);
1209 if (t1 == t || t1 == last)
1210 return first;
1211 has_expr_list = true;
1212 if (!first_expr) {
1213 if (db.names.empty())
1214 return first;
1215 auto tmp = db.names.back().move_full();
1216 db.names.pop_back();
1217 if (!tmp.empty()) {
1218 if (db.names.empty())
1219 return first;
1220 db.names.back().first.append(", ");
1221 db.names.back().first.append(tmp);
1222 first_expr = false;
1223 }
1224 }
1225 t = t1;
1226 }
1227 ++t;
1228 const char *t1 = parse_type(t, last, db);
1229 if (t1 == t || t1 == last)
1230 return first;
1231 t = t1;
1232 bool has_init = false;
1233 if (last - t >= 3 && t[0] == 'p' && t[1] == 'i') {
1234 t += 2;
1235 has_init = true;
1236 first_expr = true;
1237 while (*t != 'E') {
1238 t1 = parse_expression(t, last, db);
1239 if (t1 == t || t1 == last)
1240 return first;
1241 if (!first_expr) {
1242 if (db.names.empty())
1243 return first;
1244 auto tmp = db.names.back().move_full();
1245 db.names.pop_back();
1246 if (!tmp.empty()) {
1247 if (db.names.empty())
1248 return first;
1249 db.names.back().first.append(", ");
1250 db.names.back().first.append(tmp);
1251 first_expr = false;
1252 }
1253 }
1254 t = t1;
1255 }
1256 }
1257 if (*t != 'E')
1258 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001259 std::string init_list;
Rafael Espindolab940b662016-09-06 19:16:48 +00001260 if (has_init) {
1261 if (db.names.empty())
1262 return first;
1263 init_list = db.names.back().move_full();
1264 db.names.pop_back();
1265 }
1266 if (db.names.empty())
1267 return first;
1268 auto type = db.names.back().move_full();
1269 db.names.pop_back();
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001270 std::string expr_list;
Rafael Espindolab940b662016-09-06 19:16:48 +00001271 if (has_expr_list) {
1272 if (db.names.empty())
1273 return first;
1274 expr_list = db.names.back().move_full();
1275 db.names.pop_back();
1276 }
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001277 std::string r;
Rafael Espindolab940b662016-09-06 19:16:48 +00001278 if (parsed_gs)
1279 r = "::";
1280 if (is_array)
1281 r += "[] ";
1282 else
1283 r += " ";
1284 if (has_expr_list)
1285 r += "(" + expr_list + ") ";
1286 r += type;
1287 if (has_init)
1288 r += " (" + init_list + ")";
1289 db.names.push_back(std::move(r));
1290 first = t + 1;
1291 }
1292 }
1293 return first;
1294}
1295
1296// cv <type> <expression> # conversion with one
1297// argument
1298// cv <type> _ <expression>* E # conversion with a
1299// different number of arguments
1300
1301template <class C>
1302static const char *parse_conversion_expr(const char *first, const char *last,
1303 C &db) {
1304 if (last - first >= 3 && first[0] == 'c' && first[1] == 'v') {
1305 bool try_to_parse_template_args = db.try_to_parse_template_args;
1306 db.try_to_parse_template_args = false;
1307 const char *t = parse_type(first + 2, last, db);
1308 db.try_to_parse_template_args = try_to_parse_template_args;
1309 if (t != first + 2 && t != last) {
1310 if (*t != '_') {
1311 const char *t1 = parse_expression(t, last, db);
1312 if (t1 == t)
1313 return first;
1314 t = t1;
1315 } else {
1316 ++t;
1317 if (t == last)
1318 return first;
1319 if (*t == 'E')
1320 db.names.emplace_back();
1321 else {
1322 bool first_expr = true;
1323 while (*t != 'E') {
1324 const char *t1 = parse_expression(t, last, db);
1325 if (t1 == t || t1 == last)
1326 return first;
1327 if (!first_expr) {
1328 if (db.names.empty())
1329 return first;
1330 auto tmp = db.names.back().move_full();
1331 db.names.pop_back();
1332 if (!tmp.empty()) {
1333 if (db.names.empty())
1334 return first;
1335 db.names.back().first.append(", ");
1336 db.names.back().first.append(tmp);
1337 first_expr = false;
1338 }
1339 }
1340 t = t1;
1341 }
1342 }
1343 ++t;
1344 }
1345 if (db.names.size() < 2)
1346 return first;
1347 auto tmp = db.names.back().move_full();
1348 db.names.pop_back();
1349 db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
1350 first = t;
1351 }
1352 }
1353 return first;
1354}
1355
1356// pt <expression> <expression> # expr->name
1357
1358template <class C>
1359static const char *parse_arrow_expr(const char *first, const char *last,
1360 C &db) {
1361 if (last - first >= 3 && first[0] == 'p' && first[1] == 't') {
1362 const char *t = parse_expression(first + 2, last, db);
1363 if (t != first + 2) {
1364 const char *t1 = parse_expression(t, last, db);
1365 if (t1 != t) {
1366 if (db.names.size() < 2)
1367 return first;
1368 auto tmp = db.names.back().move_full();
1369 db.names.pop_back();
1370 db.names.back().first += "->";
1371 db.names.back().first += tmp;
1372 first = t1;
1373 }
1374 }
1375 }
1376 return first;
1377}
1378
1379// <ref-qualifier> ::= R # & ref-qualifier
1380// <ref-qualifier> ::= O # && ref-qualifier
1381
1382// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
1383
1384template <class C>
1385static const char *parse_function_type(const char *first, const char *last,
1386 C &db) {
1387 if (first != last && *first == 'F') {
1388 const char *t = first + 1;
1389 if (t != last) {
1390 if (*t == 'Y') {
1391 /* extern "C" */
1392 if (++t == last)
1393 return first;
1394 }
1395 const char *t1 = parse_type(t, last, db);
1396 if (t1 != t) {
1397 t = t1;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001398 std::string sig("(");
Rafael Espindolab940b662016-09-06 19:16:48 +00001399 int ref_qual = 0;
1400 while (true) {
1401 if (t == last) {
1402 db.names.pop_back();
1403 return first;
1404 }
1405 if (*t == 'E') {
1406 ++t;
1407 break;
1408 }
1409 if (*t == 'v') {
1410 ++t;
1411 continue;
1412 }
1413 if (*t == 'R' && t + 1 != last && t[1] == 'E') {
1414 ref_qual = 1;
1415 ++t;
1416 continue;
1417 }
1418 if (*t == 'O' && t + 1 != last && t[1] == 'E') {
1419 ref_qual = 2;
1420 ++t;
1421 continue;
1422 }
1423 size_t k0 = db.names.size();
1424 t1 = parse_type(t, last, db);
1425 size_t k1 = db.names.size();
1426 if (t1 == t || t1 == last)
1427 return first;
1428 for (size_t k = k0; k < k1; ++k) {
1429 if (sig.size() > 1)
1430 sig += ", ";
1431 sig += db.names[k].move_full();
1432 }
1433 for (size_t k = k0; k < k1; ++k)
1434 db.names.pop_back();
1435 t = t1;
1436 }
1437 sig += ")";
1438 switch (ref_qual) {
1439 case 1:
1440 sig += " &";
1441 break;
1442 case 2:
1443 sig += " &&";
1444 break;
1445 }
1446 if (db.names.empty())
1447 return first;
1448 db.names.back().first += " ";
1449 db.names.back().second.insert(0, sig);
1450 first = t;
1451 }
1452 }
1453 }
1454 return first;
1455}
1456
1457// <pointer-to-member-type> ::= M <class type> <member type>
1458
1459template <class C>
1460static const char *parse_pointer_to_member_type(const char *first,
1461 const char *last, C &db) {
1462 if (first != last && *first == 'M') {
1463 const char *t = parse_type(first + 1, last, db);
1464 if (t != first + 1) {
1465 const char *t2 = parse_type(t, last, db);
1466 if (t2 != t) {
1467 if (db.names.size() < 2)
1468 return first;
1469 auto func = std::move(db.names.back());
1470 db.names.pop_back();
1471 auto class_type = std::move(db.names.back());
1472 if (!func.second.empty() && func.second.front() == '(') {
1473 db.names.back().first =
1474 std::move(func.first) + "(" + class_type.move_full() + "::*";
1475 db.names.back().second = ")" + std::move(func.second);
1476 } else {
1477 db.names.back().first =
1478 std::move(func.first) + " " + class_type.move_full() + "::*";
1479 db.names.back().second = std::move(func.second);
1480 }
1481 first = t2;
1482 }
1483 }
1484 }
1485 return first;
1486}
1487
1488// <array-type> ::= A <positive dimension number> _ <element type>
1489// ::= A [<dimension expression>] _ <element type>
1490
1491template <class C>
1492static const char *parse_array_type(const char *first, const char *last,
1493 C &db) {
1494 if (first != last && *first == 'A' && first + 1 != last) {
1495 if (first[1] == '_') {
1496 const char *t = parse_type(first + 2, last, db);
1497 if (t != first + 2) {
1498 if (db.names.empty())
1499 return first;
1500 if (db.names.back().second.substr(0, 2) == " [")
1501 db.names.back().second.erase(0, 1);
1502 db.names.back().second.insert(0, " []");
1503 first = t;
1504 }
1505 } else if ('1' <= first[1] && first[1] <= '9') {
1506 const char *t = parse_number(first + 1, last);
1507 if (t != last && *t == '_') {
1508 const char *t2 = parse_type(t + 1, last, db);
1509 if (t2 != t + 1) {
1510 if (db.names.empty())
1511 return first;
1512 if (db.names.back().second.substr(0, 2) == " [")
1513 db.names.back().second.erase(0, 1);
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001514 db.names.back().second.insert(0,
1515 " [" + std::string(first + 1, t) + "]");
Rafael Espindolab940b662016-09-06 19:16:48 +00001516 first = t2;
1517 }
1518 }
1519 } else {
1520 const char *t = parse_expression(first + 1, last, db);
1521 if (t != first + 1 && t != last && *t == '_') {
1522 const char *t2 = parse_type(++t, last, db);
1523 if (t2 != t) {
1524 if (db.names.size() < 2)
1525 return first;
1526 auto type = std::move(db.names.back());
1527 db.names.pop_back();
1528 auto expr = std::move(db.names.back());
1529 db.names.back().first = std::move(type.first);
1530 if (type.second.substr(0, 2) == " [")
1531 type.second.erase(0, 1);
1532 db.names.back().second =
1533 " [" + expr.move_full() + "]" + std::move(type.second);
1534 first = t2;
1535 }
1536 }
1537 }
1538 }
1539 return first;
1540}
1541
1542// <decltype> ::= Dt <expression> E # decltype of an id-expression or class
1543// member access (C++0x)
1544// ::= DT <expression> E # decltype of an expression (C++0x)
1545
1546template <class C>
1547static const char *parse_decltype(const char *first, const char *last, C &db) {
1548 if (last - first >= 4 && first[0] == 'D') {
1549 switch (first[1]) {
1550 case 't':
1551 case 'T': {
1552 const char *t = parse_expression(first + 2, last, db);
1553 if (t != first + 2 && t != last && *t == 'E') {
1554 if (db.names.empty())
1555 return first;
1556 db.names.back() = "decltype(" + db.names.back().move_full() + ")";
1557 first = t + 1;
1558 }
1559 } break;
1560 }
1561 }
1562 return first;
1563}
1564
1565// extension:
1566// <vector-type> ::= Dv <positive dimension number> _
1567// <extended element type>
1568// ::= Dv [<dimension expression>] _ <element type>
1569// <extended element type> ::= <element type>
1570// ::= p # AltiVec vector pixel
1571
1572template <class C>
1573static const char *parse_vector_type(const char *first, const char *last,
1574 C &db) {
1575 if (last - first > 3 && first[0] == 'D' && first[1] == 'v') {
1576 if ('1' <= first[2] && first[2] <= '9') {
1577 const char *t = parse_number(first + 2, last);
1578 if (t == last || *t != '_')
1579 return first;
1580 const char *num = first + 2;
1581 size_t sz = static_cast<size_t>(t - num);
1582 if (++t != last) {
1583 if (*t != 'p') {
1584 const char *t1 = parse_type(t, last, db);
1585 if (t1 != t) {
1586 if (db.names.empty())
1587 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001588 db.names.back().first += " vector[" + std::string(num, sz) + "]";
Rafael Espindolab940b662016-09-06 19:16:48 +00001589 first = t1;
1590 }
1591 } else {
1592 ++t;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001593 db.names.push_back("pixel vector[" + std::string(num, sz) + "]");
Rafael Espindolab940b662016-09-06 19:16:48 +00001594 first = t;
1595 }
1596 }
1597 } else {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00001598 std::string num;
Rafael Espindolab940b662016-09-06 19:16:48 +00001599 const char *t1 = first + 2;
1600 if (*t1 != '_') {
1601 const char *t = parse_expression(t1, last, db);
1602 if (t != t1) {
1603 if (db.names.empty())
1604 return first;
1605 num = db.names.back().move_full();
1606 db.names.pop_back();
1607 t1 = t;
1608 }
1609 }
1610 if (t1 != last && *t1 == '_' && ++t1 != last) {
1611 const char *t = parse_type(t1, last, db);
1612 if (t != t1) {
1613 if (db.names.empty())
1614 return first;
1615 db.names.back().first += " vector[" + num + "]";
1616 first = t;
1617 }
1618 }
1619 }
1620 }
1621 return first;
1622}
1623
1624// <type> ::= <builtin-type>
1625// ::= <function-type>
1626// ::= <class-enum-type>
1627// ::= <array-type>
1628// ::= <pointer-to-member-type>
1629// ::= <template-param>
1630// ::= <template-template-param> <template-args>
1631// ::= <decltype>
1632// ::= <substitution>
1633// ::= <CV-qualifiers> <type>
1634// ::= P <type> # pointer-to
1635// ::= R <type> # reference-to
1636// ::= O <type> # rvalue reference-to (C++0x)
1637// ::= C <type> # complex pair (C 2000)
1638// ::= G <type> # imaginary (C 2000)
1639// ::= Dp <type> # pack expansion (C++0x)
1640// ::= U <source-name> <type> # vendor extended type qualifier
1641// extension := U <objc-name> <objc-type> # objc-type<identifier>
1642// extension := <vector-type> # <vector-type> starts with Dv
1643
1644// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 +
1645// <number of digits in k1> + k1
1646// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name>
1647// 11objc_object -> id<source-name>
1648
1649template <class C>
1650static const char *parse_type(const char *first, const char *last, C &db) {
1651 if (first != last) {
1652 switch (*first) {
1653 case 'r':
1654 case 'V':
1655 case 'K': {
1656 unsigned cv = 0;
1657 const char *t = parse_cv_qualifiers(first, last, cv);
1658 if (t != first) {
1659 bool is_function = *t == 'F';
1660 size_t k0 = db.names.size();
1661 const char *t1 = parse_type(t, last, db);
1662 size_t k1 = db.names.size();
1663 if (t1 != t) {
1664 if (is_function)
1665 db.subs.pop_back();
1666 db.subs.emplace_back(db.names.get_allocator());
1667 for (size_t k = k0; k < k1; ++k) {
1668 if (is_function) {
1669 size_t p = db.names[k].second.size();
1670 if (db.names[k].second[p - 2] == '&')
1671 p -= 3;
1672 else if (db.names[k].second.back() == '&')
1673 p -= 2;
1674 if (cv & 1) {
1675 db.names[k].second.insert(p, " const");
1676 p += 6;
1677 }
1678 if (cv & 2) {
1679 db.names[k].second.insert(p, " volatile");
1680 p += 9;
1681 }
1682 if (cv & 4)
1683 db.names[k].second.insert(p, " restrict");
1684 } else {
1685 if (cv & 1)
1686 db.names[k].first.append(" const");
1687 if (cv & 2)
1688 db.names[k].first.append(" volatile");
1689 if (cv & 4)
1690 db.names[k].first.append(" restrict");
1691 }
1692 db.subs.back().push_back(db.names[k]);
1693 }
1694 first = t1;
1695 }
1696 }
1697 } break;
1698 default: {
1699 const char *t = parse_builtin_type(first, last, db);
1700 if (t != first) {
1701 first = t;
1702 } else {
1703 switch (*first) {
1704 case 'A':
1705 t = parse_array_type(first, last, db);
1706 if (t != first) {
1707 if (db.names.empty())
1708 return first;
1709 first = t;
1710 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1711 db.names.get_allocator()));
1712 }
1713 break;
1714 case 'C':
1715 t = parse_type(first + 1, last, db);
1716 if (t != first + 1) {
1717 if (db.names.empty())
1718 return first;
1719 db.names.back().first.append(" complex");
1720 first = t;
1721 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1722 db.names.get_allocator()));
1723 }
1724 break;
1725 case 'F':
1726 t = parse_function_type(first, last, db);
1727 if (t != first) {
1728 if (db.names.empty())
1729 return first;
1730 first = t;
1731 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1732 db.names.get_allocator()));
1733 }
1734 break;
1735 case 'G':
1736 t = parse_type(first + 1, last, db);
1737 if (t != first + 1) {
1738 if (db.names.empty())
1739 return first;
1740 db.names.back().first.append(" imaginary");
1741 first = t;
1742 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1743 db.names.get_allocator()));
1744 }
1745 break;
1746 case 'M':
1747 t = parse_pointer_to_member_type(first, last, db);
1748 if (t != first) {
1749 if (db.names.empty())
1750 return first;
1751 first = t;
1752 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1753 db.names.get_allocator()));
1754 }
1755 break;
1756 case 'O': {
1757 size_t k0 = db.names.size();
1758 t = parse_type(first + 1, last, db);
1759 size_t k1 = db.names.size();
1760 if (t != first + 1) {
1761 db.subs.emplace_back(db.names.get_allocator());
1762 for (size_t k = k0; k < k1; ++k) {
1763 if (db.names[k].second.substr(0, 2) == " [") {
1764 db.names[k].first += " (";
1765 db.names[k].second.insert(0, ")");
1766 } else if (!db.names[k].second.empty() &&
1767 db.names[k].second.front() == '(') {
1768 db.names[k].first += "(";
1769 db.names[k].second.insert(0, ")");
1770 }
1771 db.names[k].first.append("&&");
1772 db.subs.back().push_back(db.names[k]);
1773 }
1774 first = t;
1775 }
1776 break;
1777 }
1778 case 'P': {
1779 size_t k0 = db.names.size();
1780 t = parse_type(first + 1, last, db);
1781 size_t k1 = db.names.size();
1782 if (t != first + 1) {
1783 db.subs.emplace_back(db.names.get_allocator());
1784 for (size_t k = k0; k < k1; ++k) {
1785 if (db.names[k].second.substr(0, 2) == " [") {
1786 db.names[k].first += " (";
1787 db.names[k].second.insert(0, ")");
1788 } else if (!db.names[k].second.empty() &&
1789 db.names[k].second.front() == '(') {
1790 db.names[k].first += "(";
1791 db.names[k].second.insert(0, ")");
1792 }
1793 if (first[1] != 'U' ||
1794 db.names[k].first.substr(0, 12) != "objc_object<") {
1795 db.names[k].first.append("*");
1796 } else {
1797 db.names[k].first.replace(0, 11, "id");
1798 }
1799 db.subs.back().push_back(db.names[k]);
1800 }
1801 first = t;
1802 }
1803 break;
1804 }
1805 case 'R': {
1806 size_t k0 = db.names.size();
1807 t = parse_type(first + 1, last, db);
1808 size_t k1 = db.names.size();
1809 if (t != first + 1) {
1810 db.subs.emplace_back(db.names.get_allocator());
1811 for (size_t k = k0; k < k1; ++k) {
1812 if (db.names[k].second.substr(0, 2) == " [") {
1813 db.names[k].first += " (";
1814 db.names[k].second.insert(0, ")");
1815 } else if (!db.names[k].second.empty() &&
1816 db.names[k].second.front() == '(') {
1817 db.names[k].first += "(";
1818 db.names[k].second.insert(0, ")");
1819 }
1820 db.names[k].first.append("&");
1821 db.subs.back().push_back(db.names[k]);
1822 }
1823 first = t;
1824 }
1825 break;
1826 }
1827 case 'T': {
1828 size_t k0 = db.names.size();
1829 t = parse_template_param(first, last, db);
1830 size_t k1 = db.names.size();
1831 if (t != first) {
1832 db.subs.emplace_back(db.names.get_allocator());
1833 for (size_t k = k0; k < k1; ++k)
1834 db.subs.back().push_back(db.names[k]);
1835 if (db.try_to_parse_template_args && k1 == k0 + 1) {
1836 const char *t1 = parse_template_args(t, last, db);
1837 if (t1 != t) {
1838 auto args = db.names.back().move_full();
1839 db.names.pop_back();
1840 db.names.back().first += std::move(args);
1841 db.subs.push_back(typename C::sub_type(
1842 1, db.names.back(), db.names.get_allocator()));
1843 t = t1;
1844 }
1845 }
1846 first = t;
1847 }
1848 break;
1849 }
1850 case 'U':
1851 if (first + 1 != last) {
1852 t = parse_source_name(first + 1, last, db);
1853 if (t != first + 1) {
1854 const char *t2 = parse_type(t, last, db);
1855 if (t2 != t) {
1856 if (db.names.size() < 2)
1857 return first;
1858 auto type = db.names.back().move_full();
1859 db.names.pop_back();
1860 if (db.names.back().first.substr(0, 9) != "objcproto") {
1861 db.names.back() = type + " " + db.names.back().move_full();
1862 } else {
1863 auto proto = db.names.back().move_full();
1864 db.names.pop_back();
1865 t = parse_source_name(proto.data() + 9,
1866 proto.data() + proto.size(), db);
1867 if (t != proto.data() + 9) {
1868 db.names.back() =
1869 type + "<" + db.names.back().move_full() + ">";
1870 } else {
1871 db.names.push_back(type + " " + proto);
1872 }
1873 }
1874 db.subs.push_back(typename C::sub_type(
1875 1, db.names.back(), db.names.get_allocator()));
1876 first = t2;
1877 }
1878 }
1879 }
1880 break;
1881 case 'S':
1882 if (first + 1 != last && first[1] == 't') {
1883 t = parse_name(first, last, db);
1884 if (t != first) {
1885 if (db.names.empty())
1886 return first;
1887 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1888 db.names.get_allocator()));
1889 first = t;
1890 }
1891 } else {
1892 t = parse_substitution(first, last, db);
1893 if (t != first) {
1894 first = t;
1895 // Parsed a substitution. If the substitution is a
1896 // <template-param> it might be followed by <template-args>.
1897 t = parse_template_args(first, last, db);
1898 if (t != first) {
1899 if (db.names.size() < 2)
1900 return first;
1901 auto template_args = db.names.back().move_full();
1902 db.names.pop_back();
1903 db.names.back().first += template_args;
1904 // Need to create substitution for <template-template-param>
1905 // <template-args>
1906 db.subs.push_back(typename C::sub_type(
1907 1, db.names.back(), db.names.get_allocator()));
1908 first = t;
1909 }
1910 }
1911 }
1912 break;
1913 case 'D':
1914 if (first + 1 != last) {
1915 switch (first[1]) {
1916 case 'p': {
1917 size_t k0 = db.names.size();
1918 t = parse_type(first + 2, last, db);
1919 size_t k1 = db.names.size();
1920 if (t != first + 2) {
1921 db.subs.emplace_back(db.names.get_allocator());
1922 for (size_t k = k0; k < k1; ++k)
1923 db.subs.back().push_back(db.names[k]);
1924 first = t;
1925 return first;
1926 }
1927 break;
1928 }
1929 case 't':
1930 case 'T':
1931 t = parse_decltype(first, last, db);
1932 if (t != first) {
1933 if (db.names.empty())
1934 return first;
1935 db.subs.push_back(typename C::sub_type(
1936 1, db.names.back(), db.names.get_allocator()));
1937 first = t;
1938 return first;
1939 }
1940 break;
1941 case 'v':
1942 t = parse_vector_type(first, last, db);
1943 if (t != first) {
1944 if (db.names.empty())
1945 return first;
1946 db.subs.push_back(typename C::sub_type(
1947 1, db.names.back(), db.names.get_allocator()));
1948 first = t;
1949 return first;
1950 }
1951 break;
1952 }
1953 }
1954 // drop through
1955 default:
1956 // must check for builtin-types before class-enum-types to avoid
1957 // ambiguities with operator-names
1958 t = parse_builtin_type(first, last, db);
1959 if (t != first) {
1960 first = t;
1961 } else {
1962 t = parse_name(first, last, db);
1963 if (t != first) {
1964 if (db.names.empty())
1965 return first;
1966 db.subs.push_back(typename C::sub_type(1, db.names.back(),
1967 db.names.get_allocator()));
1968 first = t;
1969 }
1970 }
1971 break;
1972 }
1973 }
1974 break;
1975 }
1976 }
1977 }
1978 return first;
1979}
1980
1981// <operator-name>
1982// ::= aa # &&
1983// ::= ad # & (unary)
1984// ::= an # &
1985// ::= aN # &=
1986// ::= aS # =
1987// ::= cl # ()
1988// ::= cm # ,
1989// ::= co # ~
1990// ::= cv <type> # (cast)
1991// ::= da # delete[]
1992// ::= de # * (unary)
1993// ::= dl # delete
1994// ::= dv # /
1995// ::= dV # /=
1996// ::= eo # ^
1997// ::= eO # ^=
1998// ::= eq # ==
1999// ::= ge # >=
2000// ::= gt # >
2001// ::= ix # []
2002// ::= le # <=
2003// ::= li <source-name> # operator ""
2004// ::= ls # <<
2005// ::= lS # <<=
2006// ::= lt # <
2007// ::= mi # -
2008// ::= mI # -=
2009// ::= ml # *
2010// ::= mL # *=
2011// ::= mm # -- (postfix in <expression> context)
2012// ::= na # new[]
2013// ::= ne # !=
2014// ::= ng # - (unary)
2015// ::= nt # !
2016// ::= nw # new
2017// ::= oo # ||
2018// ::= or # |
2019// ::= oR # |=
2020// ::= pm # ->*
2021// ::= pl # +
2022// ::= pL # +=
2023// ::= pp # ++ (postfix in <expression> context)
2024// ::= ps # + (unary)
2025// ::= pt # ->
2026// ::= qu # ?
2027// ::= rm # %
2028// ::= rM # %=
2029// ::= rs # >>
2030// ::= rS # >>=
2031// ::= v <digit> <source-name> # vendor extended
2032// operator
2033
2034template <class C>
2035static const char *parse_operator_name(const char *first, const char *last,
2036 C &db) {
2037 if (last - first >= 2) {
2038 switch (first[0]) {
2039 case 'a':
2040 switch (first[1]) {
2041 case 'a':
2042 db.names.push_back("operator&&");
2043 first += 2;
2044 break;
2045 case 'd':
2046 case 'n':
2047 db.names.push_back("operator&");
2048 first += 2;
2049 break;
2050 case 'N':
2051 db.names.push_back("operator&=");
2052 first += 2;
2053 break;
2054 case 'S':
2055 db.names.push_back("operator=");
2056 first += 2;
2057 break;
2058 }
2059 break;
2060 case 'c':
2061 switch (first[1]) {
2062 case 'l':
2063 db.names.push_back("operator()");
2064 first += 2;
2065 break;
2066 case 'm':
2067 db.names.push_back("operator,");
2068 first += 2;
2069 break;
2070 case 'o':
2071 db.names.push_back("operator~");
2072 first += 2;
2073 break;
2074 case 'v': {
2075 bool try_to_parse_template_args = db.try_to_parse_template_args;
2076 db.try_to_parse_template_args = false;
2077 const char *t = parse_type(first + 2, last, db);
2078 db.try_to_parse_template_args = try_to_parse_template_args;
2079 if (t != first + 2) {
2080 if (db.names.empty())
2081 return first;
2082 db.names.back().first.insert(0, "operator ");
2083 db.parsed_ctor_dtor_cv = true;
2084 first = t;
2085 }
2086 } break;
2087 }
2088 break;
2089 case 'd':
2090 switch (first[1]) {
2091 case 'a':
2092 db.names.push_back("operator delete[]");
2093 first += 2;
2094 break;
2095 case 'e':
2096 db.names.push_back("operator*");
2097 first += 2;
2098 break;
2099 case 'l':
2100 db.names.push_back("operator delete");
2101 first += 2;
2102 break;
2103 case 'v':
2104 db.names.push_back("operator/");
2105 first += 2;
2106 break;
2107 case 'V':
2108 db.names.push_back("operator/=");
2109 first += 2;
2110 break;
2111 }
2112 break;
2113 case 'e':
2114 switch (first[1]) {
2115 case 'o':
2116 db.names.push_back("operator^");
2117 first += 2;
2118 break;
2119 case 'O':
2120 db.names.push_back("operator^=");
2121 first += 2;
2122 break;
2123 case 'q':
2124 db.names.push_back("operator==");
2125 first += 2;
2126 break;
2127 }
2128 break;
2129 case 'g':
2130 switch (first[1]) {
2131 case 'e':
2132 db.names.push_back("operator>=");
2133 first += 2;
2134 break;
2135 case 't':
2136 db.names.push_back("operator>");
2137 first += 2;
2138 break;
2139 }
2140 break;
2141 case 'i':
2142 if (first[1] == 'x') {
2143 db.names.push_back("operator[]");
2144 first += 2;
2145 }
2146 break;
2147 case 'l':
2148 switch (first[1]) {
2149 case 'e':
2150 db.names.push_back("operator<=");
2151 first += 2;
2152 break;
2153 case 'i': {
2154 const char *t = parse_source_name(first + 2, last, db);
2155 if (t != first + 2) {
2156 if (db.names.empty())
2157 return first;
2158 db.names.back().first.insert(0, "operator\"\" ");
2159 first = t;
2160 }
2161 } break;
2162 case 's':
2163 db.names.push_back("operator<<");
2164 first += 2;
2165 break;
2166 case 'S':
2167 db.names.push_back("operator<<=");
2168 first += 2;
2169 break;
2170 case 't':
2171 db.names.push_back("operator<");
2172 first += 2;
2173 break;
2174 }
2175 break;
2176 case 'm':
2177 switch (first[1]) {
2178 case 'i':
2179 db.names.push_back("operator-");
2180 first += 2;
2181 break;
2182 case 'I':
2183 db.names.push_back("operator-=");
2184 first += 2;
2185 break;
2186 case 'l':
2187 db.names.push_back("operator*");
2188 first += 2;
2189 break;
2190 case 'L':
2191 db.names.push_back("operator*=");
2192 first += 2;
2193 break;
2194 case 'm':
2195 db.names.push_back("operator--");
2196 first += 2;
2197 break;
2198 }
2199 break;
2200 case 'n':
2201 switch (first[1]) {
2202 case 'a':
2203 db.names.push_back("operator new[]");
2204 first += 2;
2205 break;
2206 case 'e':
2207 db.names.push_back("operator!=");
2208 first += 2;
2209 break;
2210 case 'g':
2211 db.names.push_back("operator-");
2212 first += 2;
2213 break;
2214 case 't':
2215 db.names.push_back("operator!");
2216 first += 2;
2217 break;
2218 case 'w':
2219 db.names.push_back("operator new");
2220 first += 2;
2221 break;
2222 }
2223 break;
2224 case 'o':
2225 switch (first[1]) {
2226 case 'o':
2227 db.names.push_back("operator||");
2228 first += 2;
2229 break;
2230 case 'r':
2231 db.names.push_back("operator|");
2232 first += 2;
2233 break;
2234 case 'R':
2235 db.names.push_back("operator|=");
2236 first += 2;
2237 break;
2238 }
2239 break;
2240 case 'p':
2241 switch (first[1]) {
2242 case 'm':
2243 db.names.push_back("operator->*");
2244 first += 2;
2245 break;
2246 case 'l':
2247 db.names.push_back("operator+");
2248 first += 2;
2249 break;
2250 case 'L':
2251 db.names.push_back("operator+=");
2252 first += 2;
2253 break;
2254 case 'p':
2255 db.names.push_back("operator++");
2256 first += 2;
2257 break;
2258 case 's':
2259 db.names.push_back("operator+");
2260 first += 2;
2261 break;
2262 case 't':
2263 db.names.push_back("operator->");
2264 first += 2;
2265 break;
2266 }
2267 break;
2268 case 'q':
2269 if (first[1] == 'u') {
2270 db.names.push_back("operator?");
2271 first += 2;
2272 }
2273 break;
2274 case 'r':
2275 switch (first[1]) {
2276 case 'm':
2277 db.names.push_back("operator%");
2278 first += 2;
2279 break;
2280 case 'M':
2281 db.names.push_back("operator%=");
2282 first += 2;
2283 break;
2284 case 's':
2285 db.names.push_back("operator>>");
2286 first += 2;
2287 break;
2288 case 'S':
2289 db.names.push_back("operator>>=");
2290 first += 2;
2291 break;
2292 }
2293 break;
2294 case 'v':
2295 if (std::isdigit(first[1])) {
2296 const char *t = parse_source_name(first + 2, last, db);
2297 if (t != first + 2) {
2298 if (db.names.empty())
2299 return first;
2300 db.names.back().first.insert(0, "operator ");
2301 first = t;
2302 }
2303 }
2304 break;
2305 }
2306 }
2307 return first;
2308}
2309
2310template <class C>
2311static const char *parse_integer_literal(const char *first, const char *last,
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002312 const std::string &lit, C &db) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002313 const char *t = parse_number(first, last);
2314 if (t != first && t != last && *t == 'E') {
2315 if (lit.size() > 3)
2316 db.names.push_back("(" + lit + ")");
2317 else
2318 db.names.emplace_back();
2319 if (*first == 'n') {
2320 db.names.back().first += '-';
2321 ++first;
2322 }
2323 db.names.back().first.append(first, t);
2324 if (lit.size() <= 3)
2325 db.names.back().first += lit;
2326 first = t + 1;
2327 }
2328 return first;
2329}
2330
2331// <expr-primary> ::= L <type> <value number> E #
2332// integer literal
2333// ::= L <type> <value float> E #
2334// floating literal
2335// ::= L <string type> E #
2336// string literal
2337// ::= L <nullptr type> E #
2338// nullptr literal (i.e., "LDnE")
2339// ::= L <type> <real-part float> _ <imag-part float> E #
2340// complex floating point literal (C 2000)
2341// ::= L <mangled-name> E #
2342// external name
2343
2344template <class C>
2345static const char *parse_expr_primary(const char *first, const char *last,
2346 C &db) {
2347 if (last - first >= 4 && *first == 'L') {
2348 switch (first[1]) {
2349 case 'w': {
2350 const char *t = parse_integer_literal(first + 2, last, "wchar_t", db);
2351 if (t != first + 2)
2352 first = t;
2353 } break;
2354 case 'b':
2355 if (first[3] == 'E') {
2356 switch (first[2]) {
2357 case '0':
2358 db.names.push_back("false");
2359 first += 4;
2360 break;
2361 case '1':
2362 db.names.push_back("true");
2363 first += 4;
2364 break;
2365 }
2366 }
2367 break;
2368 case 'c': {
2369 const char *t = parse_integer_literal(first + 2, last, "char", db);
2370 if (t != first + 2)
2371 first = t;
2372 } break;
2373 case 'a': {
2374 const char *t = parse_integer_literal(first + 2, last, "signed char", db);
2375 if (t != first + 2)
2376 first = t;
2377 } break;
2378 case 'h': {
2379 const char *t =
2380 parse_integer_literal(first + 2, last, "unsigned char", db);
2381 if (t != first + 2)
2382 first = t;
2383 } break;
2384 case 's': {
2385 const char *t = parse_integer_literal(first + 2, last, "short", db);
2386 if (t != first + 2)
2387 first = t;
2388 } break;
2389 case 't': {
2390 const char *t =
2391 parse_integer_literal(first + 2, last, "unsigned short", db);
2392 if (t != first + 2)
2393 first = t;
2394 } break;
2395 case 'i': {
2396 const char *t = parse_integer_literal(first + 2, last, "", db);
2397 if (t != first + 2)
2398 first = t;
2399 } break;
2400 case 'j': {
2401 const char *t = parse_integer_literal(first + 2, last, "u", db);
2402 if (t != first + 2)
2403 first = t;
2404 } break;
2405 case 'l': {
2406 const char *t = parse_integer_literal(first + 2, last, "l", db);
2407 if (t != first + 2)
2408 first = t;
2409 } break;
2410 case 'm': {
2411 const char *t = parse_integer_literal(first + 2, last, "ul", db);
2412 if (t != first + 2)
2413 first = t;
2414 } break;
2415 case 'x': {
2416 const char *t = parse_integer_literal(first + 2, last, "ll", db);
2417 if (t != first + 2)
2418 first = t;
2419 } break;
2420 case 'y': {
2421 const char *t = parse_integer_literal(first + 2, last, "ull", db);
2422 if (t != first + 2)
2423 first = t;
2424 } break;
2425 case 'n': {
2426 const char *t = parse_integer_literal(first + 2, last, "__int128", db);
2427 if (t != first + 2)
2428 first = t;
2429 } break;
2430 case 'o': {
2431 const char *t =
2432 parse_integer_literal(first + 2, last, "unsigned __int128", db);
2433 if (t != first + 2)
2434 first = t;
2435 } break;
2436 case 'f': {
2437 const char *t = parse_floating_number<float>(first + 2, last, db);
2438 if (t != first + 2)
2439 first = t;
2440 } break;
2441 case 'd': {
2442 const char *t = parse_floating_number<double>(first + 2, last, db);
2443 if (t != first + 2)
2444 first = t;
2445 } break;
2446 case 'e': {
2447 const char *t = parse_floating_number<long double>(first + 2, last, db);
2448 if (t != first + 2)
2449 first = t;
2450 } break;
2451 case '_':
2452 if (first[2] == 'Z') {
2453 const char *t = parse_encoding(first + 3, last, db);
2454 if (t != first + 3 && t != last && *t == 'E')
2455 first = t + 1;
2456 }
2457 break;
2458 case 'T':
2459 // Invalid mangled name per
2460 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2461 break;
2462 default: {
2463 // might be named type
2464 const char *t = parse_type(first + 1, last, db);
2465 if (t != first + 1 && t != last) {
2466 if (*t != 'E') {
2467 const char *n = t;
2468 for (; n != last && isdigit(*n); ++n)
2469 ;
2470 if (n != t && n != last && *n == 'E') {
2471 if (db.names.empty())
2472 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002473 db.names.back() =
2474 "(" + db.names.back().move_full() + ")" + std::string(t, n);
Rafael Espindolab940b662016-09-06 19:16:48 +00002475 first = n + 1;
2476 break;
2477 }
2478 } else {
2479 first = t + 1;
2480 break;
2481 }
2482 }
2483 }
2484 }
2485 }
2486 return first;
2487}
2488
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002489static std::string base_name(std::string &s) {
Rafael Espindolab940b662016-09-06 19:16:48 +00002490 if (s.empty())
2491 return s;
2492 if (s == "std::string") {
2493 s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> "
2494 ">";
2495 return "basic_string";
2496 }
2497 if (s == "std::istream") {
2498 s = "std::basic_istream<char, std::char_traits<char> >";
2499 return "basic_istream";
2500 }
2501 if (s == "std::ostream") {
2502 s = "std::basic_ostream<char, std::char_traits<char> >";
2503 return "basic_ostream";
2504 }
2505 if (s == "std::iostream") {
2506 s = "std::basic_iostream<char, std::char_traits<char> >";
2507 return "basic_iostream";
2508 }
2509 const char *const pf = s.data();
2510 const char *pe = pf + s.size();
2511 if (pe[-1] == '>') {
2512 unsigned c = 1;
2513 while (true) {
2514 if (--pe == pf)
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002515 return std::string();
Rafael Espindolab940b662016-09-06 19:16:48 +00002516 if (pe[-1] == '<') {
2517 if (--c == 0) {
2518 --pe;
2519 break;
2520 }
2521 } else if (pe[-1] == '>')
2522 ++c;
2523 }
2524 }
2525 if (pe - pf <= 1)
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002526 return std::string();
Rafael Espindolab940b662016-09-06 19:16:48 +00002527 const char *p0 = pe - 1;
2528 for (; p0 != pf; --p0) {
2529 if (*p0 == ':') {
2530 ++p0;
2531 break;
2532 }
2533 }
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002534 return std::string(p0, pe);
Rafael Espindolab940b662016-09-06 19:16:48 +00002535}
2536
2537// <ctor-dtor-name> ::= C1 # complete object constructor
2538// ::= C2 # base object constructor
2539// ::= C3 # complete object allocating constructor
2540// extension ::= C5 # ?
2541// ::= D0 # deleting destructor
2542// ::= D1 # complete object destructor
2543// ::= D2 # base object destructor
2544// extension ::= D5 # ?
2545
2546template <class C>
2547static const char *parse_ctor_dtor_name(const char *first, const char *last,
2548 C &db) {
2549 if (last - first >= 2 && !db.names.empty()) {
2550 switch (first[0]) {
2551 case 'C':
2552 switch (first[1]) {
2553 case '1':
2554 case '2':
2555 case '3':
2556 case '5':
2557 if (db.names.empty())
2558 return first;
2559 db.names.push_back(base_name(db.names.back().first));
2560 first += 2;
2561 db.parsed_ctor_dtor_cv = true;
2562 break;
2563 }
2564 break;
2565 case 'D':
2566 switch (first[1]) {
2567 case '0':
2568 case '1':
2569 case '2':
2570 case '5':
2571 if (db.names.empty())
2572 return first;
2573 db.names.push_back("~" + base_name(db.names.back().first));
2574 first += 2;
2575 db.parsed_ctor_dtor_cv = true;
2576 break;
2577 }
2578 break;
2579 }
2580 }
2581 return first;
2582}
2583
2584// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
2585// ::= <closure-type-name>
2586//
2587// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2588//
2589// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda
2590// has no parameters
2591
2592template <class C>
2593static const char *parse_unnamed_type_name(const char *first, const char *last,
2594 C &db) {
2595 if (last - first > 2 && first[0] == 'U') {
2596 char type = first[1];
2597 switch (type) {
2598 case 't': {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002599 db.names.push_back(std::string("'unnamed"));
Rafael Espindolab940b662016-09-06 19:16:48 +00002600 const char *t0 = first + 2;
2601 if (t0 == last) {
2602 db.names.pop_back();
2603 return first;
2604 }
2605 if (std::isdigit(*t0)) {
2606 const char *t1 = t0 + 1;
2607 while (t1 != last && std::isdigit(*t1))
2608 ++t1;
2609 db.names.back().first.append(t0, t1);
2610 t0 = t1;
2611 }
2612 db.names.back().first.push_back('\'');
2613 if (t0 == last || *t0 != '_') {
2614 db.names.pop_back();
2615 return first;
2616 }
2617 first = t0 + 1;
2618 } break;
2619 case 'l': {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002620 db.names.push_back(std::string("'lambda'("));
Rafael Espindolab940b662016-09-06 19:16:48 +00002621 const char *t0 = first + 2;
2622 if (first[2] == 'v') {
2623 db.names.back().first += ')';
2624 ++t0;
2625 } else {
2626 const char *t1 = parse_type(t0, last, db);
2627 if (t1 == t0) {
2628 if (!db.names.empty())
2629 db.names.pop_back();
2630 return first;
2631 }
2632 if (db.names.size() < 2)
2633 return first;
2634 auto tmp = db.names.back().move_full();
2635 db.names.pop_back();
2636 db.names.back().first.append(tmp);
2637 t0 = t1;
2638 while (true) {
2639 t1 = parse_type(t0, last, db);
2640 if (t1 == t0)
2641 break;
2642 if (db.names.size() < 2)
2643 return first;
2644 tmp = db.names.back().move_full();
2645 db.names.pop_back();
2646 if (!tmp.empty()) {
2647 db.names.back().first.append(", ");
2648 db.names.back().first.append(tmp);
2649 }
2650 t0 = t1;
2651 }
2652 if (db.names.empty())
2653 return first;
2654 db.names.back().first.append(")");
2655 }
2656 if (t0 == last || *t0 != 'E') {
2657 if (!db.names.empty())
2658 db.names.pop_back();
2659 return first;
2660 }
2661 ++t0;
2662 if (t0 == last) {
2663 if (!db.names.empty())
2664 db.names.pop_back();
2665 return first;
2666 }
2667 if (std::isdigit(*t0)) {
2668 const char *t1 = t0 + 1;
2669 while (t1 != last && std::isdigit(*t1))
2670 ++t1;
2671 db.names.back().first.insert(db.names.back().first.begin() + 7, t0, t1);
2672 t0 = t1;
2673 }
2674 if (t0 == last || *t0 != '_') {
2675 if (!db.names.empty())
2676 db.names.pop_back();
2677 return first;
2678 }
2679 first = t0 + 1;
2680 } break;
2681 }
2682 }
2683 return first;
2684}
2685
2686// <unqualified-name> ::= <operator-name>
2687// ::= <ctor-dtor-name>
2688// ::= <source-name>
2689// ::= <unnamed-type-name>
2690
2691template <class C>
2692static const char *parse_unqualified_name(const char *first, const char *last,
2693 C &db) {
2694 if (first != last) {
2695 const char *t;
2696 switch (*first) {
2697 case 'C':
2698 case 'D':
2699 t = parse_ctor_dtor_name(first, last, db);
2700 if (t != first)
2701 first = t;
2702 break;
2703 case 'U':
2704 t = parse_unnamed_type_name(first, last, db);
2705 if (t != first)
2706 first = t;
2707 break;
2708 case '1':
2709 case '2':
2710 case '3':
2711 case '4':
2712 case '5':
2713 case '6':
2714 case '7':
2715 case '8':
2716 case '9':
2717 t = parse_source_name(first, last, db);
2718 if (t != first)
2719 first = t;
2720 break;
2721 default:
2722 t = parse_operator_name(first, last, db);
2723 if (t != first)
2724 first = t;
2725 break;
2726 };
2727 }
2728 return first;
2729}
2730
2731// <unscoped-name> ::= <unqualified-name>
2732// ::= St <unqualified-name> # ::std::
2733// extension ::= StL<unqualified-name>
2734
2735template <class C>
2736static const char *parse_unscoped_name(const char *first, const char *last,
2737 C &db) {
2738 if (last - first >= 2) {
2739 const char *t0 = first;
2740 bool St = false;
2741 if (first[0] == 'S' && first[1] == 't') {
2742 t0 += 2;
2743 St = true;
2744 if (t0 != last && *t0 == 'L')
2745 ++t0;
2746 }
2747 const char *t1 = parse_unqualified_name(t0, last, db);
2748 if (t1 != t0) {
2749 if (St) {
2750 if (db.names.empty())
2751 return first;
2752 db.names.back().first.insert(0, "std::");
2753 }
2754 first = t1;
2755 }
2756 }
2757 return first;
2758}
2759
2760// at <type> # alignof (a type)
2761
2762template <class C>
2763static const char *parse_alignof_type(const char *first, const char *last,
2764 C &db) {
2765 if (last - first >= 3 && first[0] == 'a' && first[1] == 't') {
2766 const char *t = parse_type(first + 2, last, db);
2767 if (t != first + 2) {
2768 if (db.names.empty())
2769 return first;
2770 db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
2771 first = t;
2772 }
2773 }
2774 return first;
2775}
2776
2777// az <expression> # alignof (a
2778// expression)
2779
2780template <class C>
2781static const char *parse_alignof_expr(const char *first, const char *last,
2782 C &db) {
2783 if (last - first >= 3 && first[0] == 'a' && first[1] == 'z') {
2784 const char *t = parse_expression(first + 2, last, db);
2785 if (t != first + 2) {
2786 if (db.names.empty())
2787 return first;
2788 db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
2789 first = t;
2790 }
2791 }
2792 return first;
2793}
2794
2795template <class C>
2796static const char *parse_noexcept_expression(const char *first,
2797 const char *last, C &db) {
2798 const char *t1 = parse_expression(first, last, db);
2799 if (t1 != first) {
2800 if (db.names.empty())
2801 return first;
2802 db.names.back().first = "noexcept (" + db.names.back().move_full() + ")";
2803 first = t1;
2804 }
2805 return first;
2806}
2807
2808template <class C>
2809static const char *parse_prefix_expression(const char *first, const char *last,
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002810 const std::string &op,
Rafael Espindolab940b662016-09-06 19:16:48 +00002811 C &db) {
2812 const char *t1 = parse_expression(first, last, db);
2813 if (t1 != first) {
2814 if (db.names.empty())
2815 return first;
2816 db.names.back().first = op + "(" + db.names.back().move_full() + ")";
2817 first = t1;
2818 }
2819 return first;
2820}
2821
2822template <class C>
2823static const char *parse_binary_expression(const char *first, const char *last,
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00002824 const std::string &op,
Rafael Espindolab940b662016-09-06 19:16:48 +00002825 C &db) {
2826 const char *t1 = parse_expression(first, last, db);
2827 if (t1 != first) {
2828 const char *t2 = parse_expression(t1, last, db);
2829 if (t2 != t1) {
2830 if (db.names.size() < 2)
2831 return first;
2832 auto op2 = db.names.back().move_full();
2833 db.names.pop_back();
2834 auto op1 = db.names.back().move_full();
2835 auto &nm = db.names.back().first;
2836 nm.clear();
2837 if (op == ">")
2838 nm += '(';
2839 nm += "(" + op1 + ") " + op + " (" + op2 + ")";
2840 if (op == ">")
2841 nm += ')';
2842 first = t2;
2843 } else if (!db.names.empty())
2844 db.names.pop_back();
2845 }
2846 return first;
2847}
2848
2849// <expression> ::= <unary operator-name> <expression>
2850// ::= <binary operator-name> <expression> <expression>
2851// ::= <ternary operator-name> <expression> <expression>
2852// <expression>
2853// ::= cl <expression>+ E # call
2854// ::= cv <type> <expression> #
2855// conversion with one argument
2856// ::= cv <type> _ <expression>* E #
2857// conversion with a different number of arguments
2858// ::= [gs] nw <expression>* _ <type> E # new
2859// (expr-list) type
2860// ::= [gs] nw <expression>* _ <type> <initializer> # new
2861// (expr-list) type (init)
2862// ::= [gs] na <expression>* _ <type> E # new[]
2863// (expr-list) type
2864// ::= [gs] na <expression>* _ <type> <initializer> # new[]
2865// (expr-list) type (init)
2866// ::= [gs] dl <expression> #
2867// delete expression
2868// ::= [gs] da <expression> #
2869// delete[] expression
2870// ::= pp_ <expression> #
2871// prefix ++
2872// ::= mm_ <expression> #
2873// prefix --
2874// ::= ti <type> #
2875// typeid (type)
2876// ::= te <expression> #
2877// typeid (expression)
2878// ::= dc <type> <expression> #
2879// dynamic_cast<type> (expression)
2880// ::= sc <type> <expression> #
2881// static_cast<type> (expression)
2882// ::= cc <type> <expression> #
2883// const_cast<type> (expression)
2884// ::= rc <type> <expression> #
2885// reinterpret_cast<type> (expression)
2886// ::= st <type> #
2887// sizeof (a type)
2888// ::= sz <expression> #
2889// sizeof (an expression)
2890// ::= at <type> #
2891// alignof (a type)
2892// ::= az <expression> #
2893// alignof (an expression)
2894// ::= nx <expression> #
2895// noexcept (expression)
2896// ::= <template-param>
2897// ::= <function-param>
2898// ::= dt <expression> <unresolved-name> #
2899// expr.name
2900// ::= pt <expression> <unresolved-name> #
2901// expr->name
2902// ::= ds <expression> <expression> #
2903// expr.*expr
2904// ::= sZ <template-param> # size
2905// of a parameter pack
2906// ::= sZ <function-param> # size
2907// of a function parameter pack
2908// ::= sp <expression> # pack
2909// expansion
2910// ::= tw <expression> # throw
2911// expression
2912// ::= tr # throw
2913// with no operand (rethrow)
2914// ::= <unresolved-name> # f(p),
2915// N::f(p), ::f(p),
2916// #
2917// freestanding
2918// dependent
2919// name
2920// (e.g.,
2921// T::x),
2922// #
2923// objectless
2924// nonstatic
2925// member
2926// reference
2927// ::= <expr-primary>
2928
2929template <class C>
2930static const char *parse_expression(const char *first, const char *last,
2931 C &db) {
2932 if (last - first >= 2) {
2933 const char *t = first;
2934 bool parsed_gs = false;
2935 if (last - first >= 4 && t[0] == 'g' && t[1] == 's') {
2936 t += 2;
2937 parsed_gs = true;
2938 }
2939 switch (*t) {
2940 case 'L':
2941 first = parse_expr_primary(first, last, db);
2942 break;
2943 case 'T':
2944 first = parse_template_param(first, last, db);
2945 break;
2946 case 'f':
2947 first = parse_function_param(first, last, db);
2948 break;
2949 case 'a':
2950 switch (t[1]) {
2951 case 'a':
2952 t = parse_binary_expression(first + 2, last, "&&", db);
2953 if (t != first + 2)
2954 first = t;
2955 break;
2956 case 'd':
2957 t = parse_prefix_expression(first + 2, last, "&", db);
2958 if (t != first + 2)
2959 first = t;
2960 break;
2961 case 'n':
2962 t = parse_binary_expression(first + 2, last, "&", db);
2963 if (t != first + 2)
2964 first = t;
2965 break;
2966 case 'N':
2967 t = parse_binary_expression(first + 2, last, "&=", db);
2968 if (t != first + 2)
2969 first = t;
2970 break;
2971 case 'S':
2972 t = parse_binary_expression(first + 2, last, "=", db);
2973 if (t != first + 2)
2974 first = t;
2975 break;
2976 case 't':
2977 first = parse_alignof_type(first, last, db);
2978 break;
2979 case 'z':
2980 first = parse_alignof_expr(first, last, db);
2981 break;
2982 }
2983 break;
2984 case 'c':
2985 switch (t[1]) {
2986 case 'c':
2987 first = parse_const_cast_expr(first, last, db);
2988 break;
2989 case 'l':
2990 first = parse_call_expr(first, last, db);
2991 break;
2992 case 'm':
2993 t = parse_binary_expression(first + 2, last, ",", db);
2994 if (t != first + 2)
2995 first = t;
2996 break;
2997 case 'o':
2998 t = parse_prefix_expression(first + 2, last, "~", db);
2999 if (t != first + 2)
3000 first = t;
3001 break;
3002 case 'v':
3003 first = parse_conversion_expr(first, last, db);
3004 break;
3005 }
3006 break;
3007 case 'd':
3008 switch (t[1]) {
3009 case 'a': {
3010 const char *t1 = parse_expression(t + 2, last, db);
3011 if (t1 != t + 2) {
3012 if (db.names.empty())
3013 return first;
3014 db.names.back().first =
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00003015 (parsed_gs ? std::string("::") : std::string()) + "delete[] " +
3016 db.names.back().move_full();
Rafael Espindolab940b662016-09-06 19:16:48 +00003017 first = t1;
3018 }
3019 } break;
3020 case 'c':
3021 first = parse_dynamic_cast_expr(first, last, db);
3022 break;
3023 case 'e':
3024 t = parse_prefix_expression(first + 2, last, "*", db);
3025 if (t != first + 2)
3026 first = t;
3027 break;
3028 case 'l': {
3029 const char *t1 = parse_expression(t + 2, last, db);
3030 if (t1 != t + 2) {
3031 if (db.names.empty())
3032 return first;
3033 db.names.back().first =
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00003034 (parsed_gs ? std::string("::") : std::string()) + "delete " +
3035 db.names.back().move_full();
Rafael Espindolab940b662016-09-06 19:16:48 +00003036 first = t1;
3037 }
3038 } break;
3039 case 'n':
3040 return parse_unresolved_name(first, last, db);
3041 case 's':
3042 first = parse_dot_star_expr(first, last, db);
3043 break;
3044 case 't':
3045 first = parse_dot_expr(first, last, db);
3046 break;
3047 case 'v':
3048 t = parse_binary_expression(first + 2, last, "/", db);
3049 if (t != first + 2)
3050 first = t;
3051 break;
3052 case 'V':
3053 t = parse_binary_expression(first + 2, last, "/=", db);
3054 if (t != first + 2)
3055 first = t;
3056 break;
3057 }
3058 break;
3059 case 'e':
3060 switch (t[1]) {
3061 case 'o':
3062 t = parse_binary_expression(first + 2, last, "^", db);
3063 if (t != first + 2)
3064 first = t;
3065 break;
3066 case 'O':
3067 t = parse_binary_expression(first + 2, last, "^=", db);
3068 if (t != first + 2)
3069 first = t;
3070 break;
3071 case 'q':
3072 t = parse_binary_expression(first + 2, last, "==", db);
3073 if (t != first + 2)
3074 first = t;
3075 break;
3076 }
3077 break;
3078 case 'g':
3079 switch (t[1]) {
3080 case 'e':
3081 t = parse_binary_expression(first + 2, last, ">=", db);
3082 if (t != first + 2)
3083 first = t;
3084 break;
3085 case 't':
3086 t = parse_binary_expression(first + 2, last, ">", db);
3087 if (t != first + 2)
3088 first = t;
3089 break;
3090 }
3091 break;
3092 case 'i':
3093 if (t[1] == 'x') {
3094 const char *t1 = parse_expression(first + 2, last, db);
3095 if (t1 != first + 2) {
3096 const char *t2 = parse_expression(t1, last, db);
3097 if (t2 != t1) {
3098 if (db.names.size() < 2)
3099 return first;
3100 auto op2 = db.names.back().move_full();
3101 db.names.pop_back();
3102 auto op1 = db.names.back().move_full();
3103 db.names.back() = "(" + op1 + ")[" + op2 + "]";
3104 first = t2;
3105 } else if (!db.names.empty())
3106 db.names.pop_back();
3107 }
3108 }
3109 break;
3110 case 'l':
3111 switch (t[1]) {
3112 case 'e':
3113 t = parse_binary_expression(first + 2, last, "<=", db);
3114 if (t != first + 2)
3115 first = t;
3116 break;
3117 case 's':
3118 t = parse_binary_expression(first + 2, last, "<<", db);
3119 if (t != first + 2)
3120 first = t;
3121 break;
3122 case 'S':
3123 t = parse_binary_expression(first + 2, last, "<<=", db);
3124 if (t != first + 2)
3125 first = t;
3126 break;
3127 case 't':
3128 t = parse_binary_expression(first + 2, last, "<", db);
3129 if (t != first + 2)
3130 first = t;
3131 break;
3132 }
3133 break;
3134 case 'm':
3135 switch (t[1]) {
3136 case 'i':
3137 t = parse_binary_expression(first + 2, last, "-", db);
3138 if (t != first + 2)
3139 first = t;
3140 break;
3141 case 'I':
3142 t = parse_binary_expression(first + 2, last, "-=", db);
3143 if (t != first + 2)
3144 first = t;
3145 break;
3146 case 'l':
3147 t = parse_binary_expression(first + 2, last, "*", db);
3148 if (t != first + 2)
3149 first = t;
3150 break;
3151 case 'L':
3152 t = parse_binary_expression(first + 2, last, "*=", db);
3153 if (t != first + 2)
3154 first = t;
3155 break;
3156 case 'm':
3157 if (first + 2 != last && first[2] == '_') {
3158 t = parse_prefix_expression(first + 3, last, "--", db);
3159 if (t != first + 3)
3160 first = t;
3161 } else {
3162 const char *t1 = parse_expression(first + 2, last, db);
3163 if (t1 != first + 2) {
3164 if (db.names.empty())
3165 return first;
3166 db.names.back() = "(" + db.names.back().move_full() + ")--";
3167 first = t1;
3168 }
3169 }
3170 break;
3171 }
3172 break;
3173 case 'n':
3174 switch (t[1]) {
3175 case 'a':
3176 case 'w':
3177 first = parse_new_expr(first, last, db);
3178 break;
3179 case 'e':
3180 t = parse_binary_expression(first + 2, last, "!=", db);
3181 if (t != first + 2)
3182 first = t;
3183 break;
3184 case 'g':
3185 t = parse_prefix_expression(first + 2, last, "-", db);
3186 if (t != first + 2)
3187 first = t;
3188 break;
3189 case 't':
3190 t = parse_prefix_expression(first + 2, last, "!", db);
3191 if (t != first + 2)
3192 first = t;
3193 break;
3194 case 'x':
3195 t = parse_noexcept_expression(first + 2, last, db);
3196 if (t != first + 2)
3197 first = t;
3198 break;
3199 }
3200 break;
3201 case 'o':
3202 switch (t[1]) {
3203 case 'n':
3204 return parse_unresolved_name(first, last, db);
3205 case 'o':
3206 t = parse_binary_expression(first + 2, last, "||", db);
3207 if (t != first + 2)
3208 first = t;
3209 break;
3210 case 'r':
3211 t = parse_binary_expression(first + 2, last, "|", db);
3212 if (t != first + 2)
3213 first = t;
3214 break;
3215 case 'R':
3216 t = parse_binary_expression(first + 2, last, "|=", db);
3217 if (t != first + 2)
3218 first = t;
3219 break;
3220 }
3221 break;
3222 case 'p':
3223 switch (t[1]) {
3224 case 'm':
3225 t = parse_binary_expression(first + 2, last, "->*", db);
3226 if (t != first + 2)
3227 first = t;
3228 break;
3229 case 'l':
3230 t = parse_binary_expression(first + 2, last, "+", db);
3231 if (t != first + 2)
3232 first = t;
3233 break;
3234 case 'L':
3235 t = parse_binary_expression(first + 2, last, "+=", db);
3236 if (t != first + 2)
3237 first = t;
3238 break;
3239 case 'p':
3240 if (first + 2 != last && first[2] == '_') {
3241 t = parse_prefix_expression(first + 3, last, "++", db);
3242 if (t != first + 3)
3243 first = t;
3244 } else {
3245 const char *t1 = parse_expression(first + 2, last, db);
3246 if (t1 != first + 2) {
3247 if (db.names.empty())
3248 return first;
3249 db.names.back() = "(" + db.names.back().move_full() + ")++";
3250 first = t1;
3251 }
3252 }
3253 break;
3254 case 's':
3255 t = parse_prefix_expression(first + 2, last, "+", db);
3256 if (t != first + 2)
3257 first = t;
3258 break;
3259 case 't':
3260 first = parse_arrow_expr(first, last, db);
3261 break;
3262 }
3263 break;
3264 case 'q':
3265 if (t[1] == 'u') {
3266 const char *t1 = parse_expression(first + 2, last, db);
3267 if (t1 != first + 2) {
3268 const char *t2 = parse_expression(t1, last, db);
3269 if (t2 != t1) {
3270 const char *t3 = parse_expression(t2, last, db);
3271 if (t3 != t2) {
3272 if (db.names.size() < 3)
3273 return first;
3274 auto op3 = db.names.back().move_full();
3275 db.names.pop_back();
3276 auto op2 = db.names.back().move_full();
3277 db.names.pop_back();
3278 auto op1 = db.names.back().move_full();
3279 db.names.back() = "(" + op1 + ") ? (" + op2 + ") : (" + op3 + ")";
3280 first = t3;
3281 } else {
3282 if (db.names.size() < 2)
3283 return first;
3284 db.names.pop_back();
3285 db.names.pop_back();
3286 }
3287 } else if (!db.names.empty())
3288 db.names.pop_back();
3289 }
3290 }
3291 break;
3292 case 'r':
3293 switch (t[1]) {
3294 case 'c':
3295 first = parse_reinterpret_cast_expr(first, last, db);
3296 break;
3297 case 'm':
3298 t = parse_binary_expression(first + 2, last, "%", db);
3299 if (t != first + 2)
3300 first = t;
3301 break;
3302 case 'M':
3303 t = parse_binary_expression(first + 2, last, "%=", db);
3304 if (t != first + 2)
3305 first = t;
3306 break;
3307 case 's':
3308 t = parse_binary_expression(first + 2, last, ">>", db);
3309 if (t != first + 2)
3310 first = t;
3311 break;
3312 case 'S':
3313 t = parse_binary_expression(first + 2, last, ">>=", db);
3314 if (t != first + 2)
3315 first = t;
3316 break;
3317 }
3318 break;
3319 case 's':
3320 switch (t[1]) {
3321 case 'c':
3322 first = parse_static_cast_expr(first, last, db);
3323 break;
3324 case 'p':
3325 first = parse_pack_expansion(first, last, db);
3326 break;
3327 case 'r':
3328 return parse_unresolved_name(first, last, db);
3329 case 't':
3330 first = parse_sizeof_type_expr(first, last, db);
3331 break;
3332 case 'z':
3333 first = parse_sizeof_expr_expr(first, last, db);
3334 break;
3335 case 'Z':
3336 if (last - t >= 3) {
3337 switch (t[2]) {
3338 case 'T':
3339 first = parse_sizeof_param_pack_expr(first, last, db);
3340 break;
3341 case 'f':
3342 first = parse_sizeof_function_param_pack_expr(first, last, db);
3343 break;
3344 }
3345 }
3346 break;
3347 }
3348 break;
3349 case 't':
3350 switch (t[1]) {
3351 case 'e':
3352 case 'i':
3353 first = parse_typeid_expr(first, last, db);
3354 break;
3355 case 'r':
3356 db.names.push_back("throw");
3357 first += 2;
3358 break;
3359 case 'w':
3360 first = parse_throw_expr(first, last, db);
3361 break;
3362 }
3363 break;
3364 case '1':
3365 case '2':
3366 case '3':
3367 case '4':
3368 case '5':
3369 case '6':
3370 case '7':
3371 case '8':
3372 case '9':
3373 return parse_unresolved_name(first, last, db);
3374 }
3375 }
3376 return first;
3377}
3378
3379// <template-arg> ::= <type> # type
3380// or template
3381// ::= X <expression> E #
3382// expression
3383// ::= <expr-primary> #
3384// simple expressions
3385// ::= J <template-arg>* E #
3386// argument pack
3387// ::= LZ <encoding> E #
3388// extension
3389
3390template <class C>
3391static const char *parse_template_arg(const char *first, const char *last,
3392 C &db) {
3393 if (first != last) {
3394 const char *t;
3395 switch (*first) {
3396 case 'X':
3397 t = parse_expression(first + 1, last, db);
3398 if (t != first + 1) {
3399 if (t != last && *t == 'E')
3400 first = t + 1;
3401 }
3402 break;
3403 case 'J':
3404 t = first + 1;
3405 if (t == last)
3406 return first;
3407 while (*t != 'E') {
3408 const char *t1 = parse_template_arg(t, last, db);
3409 if (t1 == t)
3410 return first;
3411 t = t1;
3412 }
3413 first = t + 1;
3414 break;
3415 case 'L':
3416 // <expr-primary> or LZ <encoding> E
3417 if (first + 1 != last && first[1] == 'Z') {
3418 t = parse_encoding(first + 2, last, db);
3419 if (t != first + 2 && t != last && *t == 'E')
3420 first = t + 1;
3421 } else
3422 first = parse_expr_primary(first, last, db);
3423 break;
3424 default:
3425 // <type>
3426 first = parse_type(first, last, db);
3427 break;
3428 }
3429 }
3430 return first;
3431}
3432
3433// <template-args> ::= I <template-arg>* E
3434// extension, the abi says <template-arg>+
3435
3436template <class C>
3437static const char *parse_template_args(const char *first, const char *last,
3438 C &db) {
3439 if (last - first >= 2 && *first == 'I') {
3440 if (db.tag_templates)
3441 db.template_param.back().clear();
3442 const char *t = first + 1;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00003443 std::string args("<");
Rafael Espindolab940b662016-09-06 19:16:48 +00003444 while (*t != 'E') {
3445 if (db.tag_templates)
3446 db.template_param.emplace_back(db.names.get_allocator());
3447 size_t k0 = db.names.size();
3448 const char *t1 = parse_template_arg(t, last, db);
3449 size_t k1 = db.names.size();
3450 if (db.tag_templates)
3451 db.template_param.pop_back();
3452 if (t1 == t || t1 == last)
3453 return first;
3454 if (db.tag_templates) {
3455 db.template_param.back().emplace_back(db.names.get_allocator());
3456 for (size_t k = k0; k < k1; ++k)
3457 db.template_param.back().back().push_back(db.names[k]);
3458 }
3459 for (size_t k = k0; k < k1; ++k) {
3460 if (args.size() > 1)
3461 args += ", ";
3462 args += db.names[k].move_full();
3463 }
3464 for (; k1 > k0; --k1)
3465 if (!db.names.empty())
3466 db.names.pop_back();
3467 t = t1;
3468 }
3469 first = t + 1;
3470 if (args.back() != '>')
3471 args += ">";
3472 else
3473 args += " >";
3474 db.names.push_back(std::move(args));
3475 }
3476 return first;
3477}
3478
3479// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix>
3480// <unqualified-name> E
3481// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix>
3482// <template-args> E
3483//
3484// <prefix> ::= <prefix> <unqualified-name>
3485// ::= <template-prefix> <template-args>
3486// ::= <template-param>
3487// ::= <decltype>
3488// ::= # empty
3489// ::= <substitution>
3490// ::= <prefix> <data-member-prefix>
3491// extension ::= L
3492//
3493// <template-prefix> ::= <prefix> <template unqualified-name>
3494// ::= <template-param>
3495// ::= <substitution>
3496
3497template <class C>
3498static const char *parse_nested_name(const char *first, const char *last, C &db,
3499 bool *ends_with_template_args) {
3500 if (first != last && *first == 'N') {
3501 unsigned cv;
3502 const char *t0 = parse_cv_qualifiers(first + 1, last, cv);
3503 if (t0 == last)
3504 return first;
3505 db.ref = 0;
3506 if (*t0 == 'R') {
3507 db.ref = 1;
3508 ++t0;
3509 } else if (*t0 == 'O') {
3510 db.ref = 2;
3511 ++t0;
3512 }
3513 db.names.emplace_back();
3514 if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't') {
3515 t0 += 2;
3516 db.names.back().first = "std";
3517 }
3518 if (t0 == last) {
3519 db.names.pop_back();
3520 return first;
3521 }
3522 bool pop_subs = false;
3523 bool component_ends_with_template_args = false;
3524 while (*t0 != 'E') {
3525 component_ends_with_template_args = false;
3526 const char *t1;
3527 switch (*t0) {
3528 case 'S':
3529 if (t0 + 1 != last && t0[1] == 't')
3530 goto do_parse_unqualified_name;
3531 t1 = parse_substitution(t0, last, db);
3532 if (t1 != t0 && t1 != last) {
3533 auto name = db.names.back().move_full();
3534 db.names.pop_back();
3535 if (db.names.empty())
3536 return first;
3537 if (!db.names.back().first.empty()) {
3538 db.names.back().first += "::" + name;
3539 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3540 db.names.get_allocator()));
3541 } else
3542 db.names.back().first = name;
3543 pop_subs = true;
3544 t0 = t1;
3545 } else
3546 return first;
3547 break;
3548 case 'T':
3549 t1 = parse_template_param(t0, last, db);
3550 if (t1 != t0 && t1 != last) {
3551 auto name = db.names.back().move_full();
3552 db.names.pop_back();
3553 if (db.names.empty())
3554 return first;
3555 if (!db.names.back().first.empty())
3556 db.names.back().first += "::" + name;
3557 else
3558 db.names.back().first = name;
3559 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3560 db.names.get_allocator()));
3561 pop_subs = true;
3562 t0 = t1;
3563 } else
3564 return first;
3565 break;
3566 case 'D':
3567 if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
3568 goto do_parse_unqualified_name;
3569 t1 = parse_decltype(t0, last, db);
3570 if (t1 != t0 && t1 != last) {
3571 auto name = db.names.back().move_full();
3572 db.names.pop_back();
3573 if (db.names.empty())
3574 return first;
3575 if (!db.names.back().first.empty())
3576 db.names.back().first += "::" + name;
3577 else
3578 db.names.back().first = name;
3579 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3580 db.names.get_allocator()));
3581 pop_subs = true;
3582 t0 = t1;
3583 } else
3584 return first;
3585 break;
3586 case 'I':
3587 t1 = parse_template_args(t0, last, db);
3588 if (t1 != t0 && t1 != last) {
3589 auto name = db.names.back().move_full();
3590 db.names.pop_back();
3591 if (db.names.empty())
3592 return first;
3593 db.names.back().first += name;
3594 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3595 db.names.get_allocator()));
3596 t0 = t1;
3597 component_ends_with_template_args = true;
3598 } else
3599 return first;
3600 break;
3601 case 'L':
3602 if (++t0 == last)
3603 return first;
3604 break;
3605 default:
3606 do_parse_unqualified_name:
3607 t1 = parse_unqualified_name(t0, last, db);
3608 if (t1 != t0 && t1 != last) {
3609 auto name = db.names.back().move_full();
3610 db.names.pop_back();
3611 if (db.names.empty())
3612 return first;
3613 if (!db.names.back().first.empty())
3614 db.names.back().first += "::" + name;
3615 else
3616 db.names.back().first = name;
3617 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3618 db.names.get_allocator()));
3619 pop_subs = true;
3620 t0 = t1;
3621 } else
3622 return first;
3623 }
3624 }
3625 first = t0 + 1;
3626 db.cv = cv;
3627 if (pop_subs && !db.subs.empty())
3628 db.subs.pop_back();
3629 if (ends_with_template_args)
3630 *ends_with_template_args = component_ends_with_template_args;
3631 }
3632 return first;
3633}
3634
3635// <discriminator> := _ <non-negative number> # when number < 10
3636// := __ <non-negative number> _ # when number >= 10
3637// extension := decimal-digit+ # at the end of string
3638
3639static const char *parse_discriminator(const char *first, const char *last) {
3640 // parse but ignore discriminator
3641 if (first != last) {
3642 if (*first == '_') {
3643 const char *t1 = first + 1;
3644 if (t1 != last) {
3645 if (std::isdigit(*t1))
3646 first = t1 + 1;
3647 else if (*t1 == '_') {
3648 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
3649 ;
3650 if (t1 != last && *t1 == '_')
3651 first = t1 + 1;
3652 }
3653 }
3654 } else if (std::isdigit(*first)) {
3655 const char *t1 = first + 1;
3656 for (; t1 != last && std::isdigit(*t1); ++t1)
3657 ;
3658 if (t1 == last)
3659 first = last;
3660 }
3661 }
3662 return first;
3663}
3664
3665// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3666// := Z <function encoding> E s [<discriminator>]
3667// := Z <function encoding> Ed [ <parameter number> ] _ <entity
3668// name>
3669
3670template <class C>
3671static const char *parse_local_name(const char *first, const char *last, C &db,
3672 bool *ends_with_template_args) {
3673 if (first != last && *first == 'Z') {
3674 const char *t = parse_encoding(first + 1, last, db);
3675 if (t != first + 1 && t != last && *t == 'E' && ++t != last) {
3676 switch (*t) {
3677 case 's':
3678 first = parse_discriminator(t + 1, last);
3679 if (db.names.empty())
3680 return first;
3681 db.names.back().first.append("::string literal");
3682 break;
3683 case 'd':
3684 if (++t != last) {
3685 const char *t1 = parse_number(t, last);
3686 if (t1 != last && *t1 == '_') {
3687 t = t1 + 1;
3688 t1 = parse_name(t, last, db, ends_with_template_args);
3689 if (t1 != t) {
3690 if (db.names.size() < 2)
3691 return first;
3692 auto name = db.names.back().move_full();
3693 db.names.pop_back();
3694 if (db.names.empty())
3695 return first;
3696 db.names.back().first.append("::");
3697 db.names.back().first.append(name);
3698 first = t1;
3699 } else if (!db.names.empty())
3700 db.names.pop_back();
3701 }
3702 }
3703 break;
3704 default: {
3705 const char *t1 = parse_name(t, last, db, ends_with_template_args);
3706 if (t1 != t) {
3707 // parse but ignore discriminator
3708 first = parse_discriminator(t1, last);
3709 if (db.names.size() < 2)
3710 return first;
3711 auto name = db.names.back().move_full();
3712 db.names.pop_back();
3713 if (db.names.empty())
3714 return first;
3715 db.names.back().first.append("::");
3716 db.names.back().first.append(name);
3717 } else if (!db.names.empty())
3718 db.names.pop_back();
3719 } break;
3720 }
3721 }
3722 }
3723 return first;
3724}
3725
3726// <name> ::= <nested-name> // N
3727// ::= <local-name> # See Scope Encoding below // Z
3728// ::= <unscoped-template-name> <template-args>
3729// ::= <unscoped-name>
3730
3731// <unscoped-template-name> ::= <unscoped-name>
3732// ::= <substitution>
3733
3734template <class C>
3735static const char *parse_name(const char *first, const char *last, C &db,
3736 bool *ends_with_template_args) {
3737 if (last - first >= 2) {
3738 const char *t0 = first;
3739 // extension: ignore L here
3740 if (*t0 == 'L')
3741 ++t0;
3742 switch (*t0) {
3743 case 'N': {
3744 const char *t1 = parse_nested_name(t0, last, db, ends_with_template_args);
3745 if (t1 != t0)
3746 first = t1;
3747 break;
3748 }
3749 case 'Z': {
3750 const char *t1 = parse_local_name(t0, last, db, ends_with_template_args);
3751 if (t1 != t0)
3752 first = t1;
3753 break;
3754 }
3755 default: {
3756 const char *t1 = parse_unscoped_name(t0, last, db);
3757 if (t1 != t0) {
3758 if (t1 != last &&
3759 *t1 == 'I') // <unscoped-template-name> <template-args>
3760 {
3761 if (db.names.empty())
3762 return first;
3763 db.subs.push_back(typename C::sub_type(1, db.names.back(),
3764 db.names.get_allocator()));
3765 t0 = t1;
3766 t1 = parse_template_args(t0, last, db);
3767 if (t1 != t0) {
3768 if (db.names.size() < 2)
3769 return first;
3770 auto tmp = db.names.back().move_full();
3771 db.names.pop_back();
3772 if (db.names.empty())
3773 return first;
3774 db.names.back().first += tmp;
3775 first = t1;
3776 if (ends_with_template_args)
3777 *ends_with_template_args = true;
3778 }
3779 } else // <unscoped-name>
3780 first = t1;
3781 } else { // try <substitution> <template-args>
3782 t1 = parse_substitution(t0, last, db);
3783 if (t1 != t0 && t1 != last && *t1 == 'I') {
3784 t0 = t1;
3785 t1 = parse_template_args(t0, last, db);
3786 if (t1 != t0) {
3787 if (db.names.size() < 2)
3788 return first;
3789 auto tmp = db.names.back().move_full();
3790 db.names.pop_back();
3791 if (db.names.empty())
3792 return first;
3793 db.names.back().first += tmp;
3794 first = t1;
3795 if (ends_with_template_args)
3796 *ends_with_template_args = true;
3797 }
3798 }
3799 }
3800 break;
3801 }
3802 }
3803 }
3804 return first;
3805}
3806
3807// <call-offset> ::= h <nv-offset> _
3808// ::= v <v-offset> _
3809//
3810// <nv-offset> ::= <offset number>
3811// # non-virtual base override
3812//
3813// <v-offset> ::= <offset number> _ <virtual offset number>
3814// # virtual base override, with vcall offset
3815
3816static const char *parse_call_offset(const char *first, const char *last) {
3817 if (first != last) {
3818 switch (*first) {
3819 case 'h': {
3820 const char *t = parse_number(first + 1, last);
3821 if (t != first + 1 && t != last && *t == '_')
3822 first = t + 1;
3823 } break;
3824 case 'v': {
3825 const char *t = parse_number(first + 1, last);
3826 if (t != first + 1 && t != last && *t == '_') {
3827 const char *t2 = parse_number(++t, last);
3828 if (t2 != t && t2 != last && *t2 == '_')
3829 first = t2 + 1;
3830 }
3831 } break;
3832 }
3833 }
3834 return first;
3835}
3836
3837// <special-name> ::= TV <type> # virtual table
3838// ::= TT <type> # VTT structure (construction vtable index)
3839// ::= TI <type> # typeinfo structure
3840// ::= TS <type> # typeinfo name (null-terminated byte string)
3841// ::= Tc <call-offset> <call-offset> <base encoding>
3842// # base is the nominal target function of thunk
3843// # first call-offset is 'this' adjustment
3844// # second call-offset is result adjustment
3845// ::= T <call-offset> <base encoding>
3846// # base is the nominal target function of thunk
3847// ::= GV <object name> # Guard variable for one-time
3848// initialization
3849// # No <type>
3850// extension ::= TC <first type> <number> _ <second type> # construction
3851// vtable for second-in-first
3852// extension ::= GR <object name> # reference temporary for object
3853
3854template <class C>
3855static const char *parse_special_name(const char *first, const char *last,
3856 C &db) {
3857 if (last - first > 2) {
3858 const char *t;
3859 switch (*first) {
3860 case 'T':
3861 switch (first[1]) {
3862 case 'V':
3863 // TV <type> # virtual table
3864 t = parse_type(first + 2, last, db);
3865 if (t != first + 2) {
3866 if (db.names.empty())
3867 return first;
3868 db.names.back().first.insert(0, "vtable for ");
3869 first = t;
3870 }
3871 break;
3872 case 'T':
3873 // TT <type> # VTT structure (construction vtable index)
3874 t = parse_type(first + 2, last, db);
3875 if (t != first + 2) {
3876 if (db.names.empty())
3877 return first;
3878 db.names.back().first.insert(0, "VTT for ");
3879 first = t;
3880 }
3881 break;
3882 case 'I':
3883 // TI <type> # typeinfo structure
3884 t = parse_type(first + 2, last, db);
3885 if (t != first + 2) {
3886 if (db.names.empty())
3887 return first;
3888 db.names.back().first.insert(0, "typeinfo for ");
3889 first = t;
3890 }
3891 break;
3892 case 'S':
3893 // TS <type> # typeinfo name (null-terminated byte string)
3894 t = parse_type(first + 2, last, db);
3895 if (t != first + 2) {
3896 if (db.names.empty())
3897 return first;
3898 db.names.back().first.insert(0, "typeinfo name for ");
3899 first = t;
3900 }
3901 break;
3902 case 'c':
3903 // Tc <call-offset> <call-offset> <base encoding>
3904 {
3905 const char *t0 = parse_call_offset(first + 2, last);
3906 if (t0 == first + 2)
3907 break;
3908 const char *t1 = parse_call_offset(t0, last);
3909 if (t1 == t0)
3910 break;
3911 t = parse_encoding(t1, last, db);
3912 if (t != t1) {
3913 if (db.names.empty())
3914 return first;
3915 db.names.back().first.insert(0, "covariant return thunk to ");
3916 first = t;
3917 }
3918 }
3919 break;
3920 case 'C':
3921 // extension ::= TC <first type> <number> _ <second type> # construction
3922 // vtable for second-in-first
3923 t = parse_type(first + 2, last, db);
3924 if (t != first + 2) {
3925 const char *t0 = parse_number(t, last);
3926 if (t0 != t && t0 != last && *t0 == '_') {
3927 const char *t1 = parse_type(++t0, last, db);
3928 if (t1 != t0) {
3929 if (db.names.size() < 2)
3930 return first;
3931 auto left = db.names.back().move_full();
3932 db.names.pop_back();
3933 if (db.names.empty())
3934 return first;
3935 db.names.back().first = "construction vtable for " +
3936 std::move(left) + "-in-" +
3937 db.names.back().move_full();
3938 first = t1;
3939 }
3940 }
3941 }
3942 break;
3943 default:
3944 // T <call-offset> <base encoding>
3945 {
3946 const char *t0 = parse_call_offset(first + 1, last);
3947 if (t0 == first + 1)
3948 break;
3949 t = parse_encoding(t0, last, db);
3950 if (t != t0) {
3951 if (db.names.empty())
3952 return first;
3953 if (first[1] == 'v') {
3954 db.names.back().first.insert(0, "virtual thunk to ");
3955 first = t;
3956 } else {
3957 db.names.back().first.insert(0, "non-virtual thunk to ");
3958 first = t;
3959 }
3960 }
3961 }
3962 break;
3963 }
3964 break;
3965 case 'G':
3966 switch (first[1]) {
3967 case 'V':
3968 // GV <object name> # Guard variable for one-time initialization
3969 t = parse_name(first + 2, last, db);
3970 if (t != first + 2) {
3971 if (db.names.empty())
3972 return first;
3973 db.names.back().first.insert(0, "guard variable for ");
3974 first = t;
3975 }
3976 break;
3977 case 'R':
3978 // extension ::= GR <object name> # reference temporary for object
3979 t = parse_name(first + 2, last, db);
3980 if (t != first + 2) {
3981 if (db.names.empty())
3982 return first;
3983 db.names.back().first.insert(0, "reference temporary for ");
3984 first = t;
3985 }
3986 break;
3987 }
3988 break;
3989 }
3990 }
3991 return first;
3992}
3993
3994namespace {
3995template <class T> class save_value {
3996 T &restore_;
3997 T original_value_;
3998
3999public:
4000 save_value(T &restore) : restore_(restore), original_value_(restore) {}
4001
4002 ~save_value() { restore_ = std::move(original_value_); }
4003
4004 save_value(const save_value &) = delete;
4005 save_value &operator=(const save_value &) = delete;
4006};
4007}
4008
4009// <encoding> ::= <function name> <bare-function-type>
4010// ::= <data name>
4011// ::= <special-name>
4012
4013template <class C>
4014static const char *parse_encoding(const char *first, const char *last, C &db) {
4015 if (first != last) {
4016 save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
4017 ++db.encoding_depth;
4018 save_value<decltype(db.tag_templates)> sb(db.tag_templates);
4019 if (db.encoding_depth > 1)
4020 db.tag_templates = true;
4021 switch (*first) {
4022 case 'G':
4023 case 'T':
4024 first = parse_special_name(first, last, db);
4025 break;
4026 default: {
4027 bool ends_with_template_args = false;
4028 const char *t = parse_name(first, last, db, &ends_with_template_args);
4029 unsigned cv = db.cv;
4030 unsigned ref = db.ref;
4031 if (t != first) {
4032 if (t != last && *t != 'E' && *t != '.') {
4033 save_value<bool> sb2(db.tag_templates);
4034 db.tag_templates = false;
4035 const char *t2;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00004036 std::string ret2;
Rafael Espindolab940b662016-09-06 19:16:48 +00004037 if (db.names.empty())
4038 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00004039 const std::string &nm = db.names.back().first;
Rafael Espindolab940b662016-09-06 19:16:48 +00004040 if (nm.empty())
4041 return first;
4042 if (!db.parsed_ctor_dtor_cv && ends_with_template_args) {
4043 t2 = parse_type(t, last, db);
4044 if (t2 == t)
4045 return first;
4046 if (db.names.size() < 2)
4047 return first;
4048 auto ret1 = std::move(db.names.back().first);
4049 ret2 = std::move(db.names.back().second);
4050 if (ret2.empty())
4051 ret1 += ' ';
4052 db.names.pop_back();
4053 if (db.names.empty())
4054 return first;
4055
4056 db.names.back().first.insert(0, ret1);
4057 t = t2;
4058 }
4059 db.names.back().first += '(';
4060 if (t != last && *t == 'v') {
4061 ++t;
4062 } else {
4063 bool first_arg = true;
4064 while (true) {
4065 size_t k0 = db.names.size();
4066 t2 = parse_type(t, last, db);
4067 size_t k1 = db.names.size();
4068 if (t2 == t)
4069 break;
4070 if (k1 > k0) {
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00004071 std::string tmp;
Rafael Espindolab940b662016-09-06 19:16:48 +00004072 for (size_t k = k0; k < k1; ++k) {
4073 if (!tmp.empty())
4074 tmp += ", ";
4075 tmp += db.names[k].move_full();
4076 }
4077 for (size_t k = k0; k < k1; ++k) {
4078 if (db.names.empty())
4079 return first;
4080 db.names.pop_back();
4081 }
4082 if (!tmp.empty()) {
4083 if (db.names.empty())
4084 return first;
4085 if (!first_arg)
4086 db.names.back().first += ", ";
4087 else
4088 first_arg = false;
4089 db.names.back().first += tmp;
4090 }
4091 }
4092 t = t2;
4093 }
4094 }
4095 if (db.names.empty())
4096 return first;
4097 db.names.back().first += ')';
4098 if (cv & 1)
4099 db.names.back().first.append(" const");
4100 if (cv & 2)
4101 db.names.back().first.append(" volatile");
4102 if (cv & 4)
4103 db.names.back().first.append(" restrict");
4104 if (ref == 1)
4105 db.names.back().first.append(" &");
4106 else if (ref == 2)
4107 db.names.back().first.append(" &&");
4108 db.names.back().first += ret2;
4109 first = t;
4110 } else
4111 first = t;
4112 }
4113 break;
4114 }
4115 }
4116 }
4117 return first;
4118}
4119
4120// _block_invoke
4121// _block_invoke<decimal-digit>+
4122// _block_invoke_<decimal-digit>+
4123
4124template <class C>
4125static const char *parse_block_invoke(const char *first, const char *last,
4126 C &db) {
4127 if (last - first >= 13) {
4128 const char test[] = "_block_invoke";
4129 const char *t = first;
4130 for (int i = 0; i < 13; ++i, ++t) {
4131 if (*t != test[i])
4132 return first;
4133 }
4134 if (t != last) {
4135 if (*t == '_') {
4136 // must have at least 1 decimal digit
4137 if (++t == last || !std::isdigit(*t))
4138 return first;
4139 ++t;
4140 }
4141 // parse zero or more digits
4142 while (t != last && isdigit(*t))
4143 ++t;
4144 }
4145 if (db.names.empty())
4146 return first;
4147 db.names.back().first.insert(0, "invocation function for block in ");
4148 first = t;
4149 }
4150 return first;
4151}
4152
4153// extension
4154// <dot-suffix> := .<anything and everything>
4155
4156template <class C>
4157static const char *parse_dot_suffix(const char *first, const char *last,
4158 C &db) {
4159 if (first != last && *first == '.') {
4160 if (db.names.empty())
4161 return first;
Saleem Abdulrasoolbe1fd542016-11-20 00:20:23 +00004162 db.names.back().first += " (" + std::string(first, last) + ")";
Rafael Espindolab940b662016-09-06 19:16:48 +00004163 first = last;
4164 }
4165 return first;
4166}
4167
4168// <block-involcaton-function> ___Z<encoding>_block_invoke
4169// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
4170// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
4171// <mangled-name> ::= _Z<encoding>
4172// ::= <type>
4173
4174template <class C>
4175static void demangle(const char *first, const char *last, C &db, int &status) {
4176 if (first >= last) {
4177 status = invalid_mangled_name;
4178 return;
4179 }
4180 if (*first == '_') {
4181 if (last - first >= 4) {
4182 if (first[1] == 'Z') {
4183 const char *t = parse_encoding(first + 2, last, db);
4184 if (t != first + 2 && t != last && *t == '.')
4185 t = parse_dot_suffix(t, last, db);
4186 if (t != last)
4187 status = invalid_mangled_name;
4188 } else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z') {
4189 const char *t = parse_encoding(first + 4, last, db);
4190 if (t != first + 4 && t != last) {
4191 const char *t1 = parse_block_invoke(t, last, db);
4192 if (t1 != last)
4193 status = invalid_mangled_name;
4194 } else
4195 status = invalid_mangled_name;
4196 } else
4197 status = invalid_mangled_name;
4198 } else
4199 status = invalid_mangled_name;
4200 } else {
4201 const char *t = parse_type(first, last, db);
4202 if (t != last)
4203 status = invalid_mangled_name;
4204 }
4205 if (status == success && db.names.empty())
4206 status = invalid_mangled_name;
4207}
4208
4209namespace {
Rafael Espindolab940b662016-09-06 19:16:48 +00004210template <class StrT> struct string_pair {
4211 StrT first;
4212 StrT second;
4213
4214 string_pair() = default;
4215 string_pair(StrT f) : first(std::move(f)) {}
4216 string_pair(StrT f, StrT s) : first(std::move(f)), second(std::move(s)) {}
4217 template <size_t N> string_pair(const char (&s)[N]) : first(s, N - 1) {}
4218
4219 size_t size() const { return first.size() + second.size(); }
4220 StrT full() const { return first + second; }
4221 StrT move_full() { return std::move(first) + std::move(second); }
4222};
4223
4224struct Db {
Saleem Abdulrasool54ec3f92016-11-20 00:20:25 +00004225 typedef std::vector<string_pair<std::string>> sub_type;
4226 typedef std::vector<sub_type> template_param_type;
Rafael Espindolab940b662016-09-06 19:16:48 +00004227 sub_type names;
4228 template_param_type subs;
Saleem Abdulrasool54ec3f92016-11-20 00:20:25 +00004229 std::vector<template_param_type> template_param;
Saleem Abdulrasool0da90502016-11-20 00:20:20 +00004230 unsigned cv = 0;
4231 unsigned ref = 0;
4232 unsigned encoding_depth = 0;
4233 bool parsed_ctor_dtor_cv = false;
4234 bool tag_templates = true;
4235 bool fix_forward_references = false;
4236 bool try_to_parse_template_args = true;
Rafael Espindolab940b662016-09-06 19:16:48 +00004237
Rafael Espindolad5aa7332016-09-06 20:36:24 +00004238 Db() : subs(0, names), template_param(0, subs) {}
Rafael Espindolab940b662016-09-06 19:16:48 +00004239};
4240}
4241
4242char *llvm::itaniumDemangle(const char *mangled_name, char *buf, size_t *n,
4243 int *status) {
4244 if (mangled_name == nullptr || (buf != nullptr && n == nullptr)) {
4245 if (status)
4246 *status = invalid_args;
4247 return nullptr;
4248 }
Saleem Abdulrasoold6da74f2016-11-14 04:54:47 +00004249
4250 size_t len = std::strlen(mangled_name);
4251 if (len < 2 || strncmp(mangled_name, "_Z", 2)) {
4252 if (len < 4 || strncmp(mangled_name, "___Z", 4)) {
4253 if (status)
4254 *status = invalid_mangled_name;
4255 return nullptr;
4256 }
4257 }
4258
Rafael Espindolab940b662016-09-06 19:16:48 +00004259 size_t internal_size = buf != nullptr ? *n : 0;
Rafael Espindolad5aa7332016-09-06 20:36:24 +00004260 Db db;
Rafael Espindolad5aa7332016-09-06 20:36:24 +00004261 db.template_param.emplace_back();
Rafael Espindolab940b662016-09-06 19:16:48 +00004262 int internal_status = success;
Rafael Espindolab940b662016-09-06 19:16:48 +00004263 demangle(mangled_name, mangled_name + len, db, internal_status);
4264 if (internal_status == success && db.fix_forward_references &&
4265 !db.template_param.empty() && !db.template_param.front().empty()) {
4266 db.fix_forward_references = false;
4267 db.tag_templates = false;
4268 db.names.clear();
4269 db.subs.clear();
4270 demangle(mangled_name, mangled_name + len, db, internal_status);
4271 if (db.fix_forward_references)
4272 internal_status = invalid_mangled_name;
4273 }
4274 if (internal_status == success) {
4275 size_t sz = db.names.back().size() + 1;
4276 if (sz > internal_size) {
4277 char *newbuf = static_cast<char *>(std::realloc(buf, sz));
4278 if (newbuf == nullptr) {
4279 internal_status = memory_alloc_failure;
4280 buf = nullptr;
4281 } else {
4282 buf = newbuf;
4283 if (n != nullptr)
4284 *n = sz;
4285 }
4286 }
4287 if (buf != nullptr) {
4288 db.names.back().first += db.names.back().second;
4289 std::memcpy(buf, db.names.back().first.data(), sz - 1);
4290 buf[sz - 1] = char(0);
4291 }
4292 } else
4293 buf = nullptr;
4294 if (status)
4295 *status = internal_status;
4296 return buf;
4297}