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