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