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