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


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:02