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