1254721Semaste//===-- Mangled.cpp ---------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste
11254721Semaste// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
12254721Semaste#include <cstddef>
13263367Semaste#if defined(_MSC_VER)
14263367Semaste// Cannot enable the builtin demangler on msvc as it does not support the cpp11 within the implementation.
15263367Semaste#elif defined (__FreeBSD__)
16263363Semaste#define LLDB_USE_BUILTIN_DEMANGLER
17263363Semaste#else
18254721Semaste#include <cxxabi.h>
19263363Semaste#endif
20254721Semaste
21263363Semaste#ifdef LLDB_USE_BUILTIN_DEMANGLER
22254721Semaste
23263363Semaste//----------------------------------------------------------------------
24263363Semaste// Inlined copy of:
25263363Semaste// http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp
26269024Semaste// revision 199944.
27263363Semaste//
28263363Semaste// Changes include:
29263363Semaste// - remove the "__cxxabiv1" namespace
30263363Semaste// - stripped GCC attributes()
31263363Semaste// - removed extern "C" from the cxa_demangle function
32263363Semaste// - Changed the scope of the unnamed namespace to include cxa_demangle
33263363Semaste//   function.
34269024Semaste// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning
35263363Semaste//----------------------------------------------------------------------
36263363Semaste
37269024Semaste#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
38269024Semaste
39269024Semaste//===-------------------------- cxa_demangle.cpp --------------------------===//
40269024Semaste//
41269024Semaste//                     The LLVM Compiler Infrastructure
42269024Semaste//
43269024Semaste// This file is dual licensed under the MIT and the University of Illinois Open
44269024Semaste// Source Licenses. See LICENSE.TXT for details.
45269024Semaste//
46269024Semaste//===----------------------------------------------------------------------===//
47269024Semaste
48269024Semaste#define _LIBCPP_EXTERN_TEMPLATE(...)
49269024Semaste#define _LIBCPP_NO_EXCEPTIONS
50269024Semaste
51269024Semaste#include <vector>
52269024Semaste#include <algorithm>
53269024Semaste#include <string>
54269024Semaste#include <numeric>
55269024Semaste#include <cstdlib>
56269024Semaste#include <cstring>
57269024Semaste#include <cctype>
58269024Semaste
59269024Semaste
60263363Semastenamespace
61263363Semaste{
62263363Semaste
63263363Semasteenum
64263363Semaste{
65263363Semaste    unknown_error = -4,
66263363Semaste    invalid_args = -3,
67263363Semaste    invalid_mangled_name,
68263363Semaste    memory_alloc_failure,
69263363Semaste    success
70263363Semaste};
71263363Semaste
72263363Semastetemplate <class C>
73263363Semaste    const char* parse_type(const char* first, const char* last, C& db);
74263363Semastetemplate <class C>
75263363Semaste    const char* parse_encoding(const char* first, const char* last, C& db);
76263363Semastetemplate <class C>
77263363Semaste    const char* parse_name(const char* first, const char* last, C& db);
78263363Semastetemplate <class C>
79263363Semaste    const char* parse_expression(const char* first, const char* last, C& db);
80263363Semastetemplate <class C>
81263363Semaste    const char* parse_template_args(const char* first, const char* last, C& db);
82263363Semastetemplate <class C>
83263363Semaste    const char* parse_operator_name(const char* first, const char* last, C& db);
84263363Semastetemplate <class C>
85263363Semaste    const char* parse_unqualified_name(const char* first, const char* last, C& db);
86263363Semastetemplate <class C>
87263363Semaste    const char* parse_decltype(const char* first, const char* last, C& db);
88263363Semaste
89263363Semastetemplate <class C>
90263363Semastevoid
91263363Semasteprint_stack(const C& db)
92263363Semaste{
93263363Semaste    printf("---------\n");
94263363Semaste    printf("names:\n");
95263363Semaste    for (auto& s : db.names)
96263363Semaste        printf("{%s#%s}\n", s.first.c_str(), s.second.c_str());
97263363Semaste    int i = -1;
98263363Semaste    printf("subs:\n");
99263363Semaste    for (auto& v : db.subs)
100263363Semaste    {
101263363Semaste        if (i >= 0)
102263363Semaste            printf("S%i_ = {", i);
103263363Semaste        else
104263363Semaste            printf("S_  = {");
105263363Semaste        for (auto& s : v)
106263363Semaste            printf("{%s#%s}", s.first.c_str(), s.second.c_str());
107263363Semaste        printf("}\n");
108263363Semaste        ++i;
109263363Semaste    }
110263363Semaste    printf("template_param:\n");
111263363Semaste    for (auto& t : db.template_param)
112263363Semaste    {
113263363Semaste        printf("--\n");
114263363Semaste        i = -1;
115263363Semaste        for (auto& v : t)
116263363Semaste        {
117263363Semaste            if (i >= 0)
118263363Semaste                printf("T%i_ = {", i);
119263363Semaste            else
120263363Semaste                printf("T_  = {");
121263363Semaste            for (auto& s : v)
122263363Semaste                printf("{%s#%s}", s.first.c_str(), s.second.c_str());
123263363Semaste            printf("}\n");
124263363Semaste            ++i;
125263363Semaste        }
126263363Semaste    }
127263363Semaste    printf("---------\n\n");
128263363Semaste}
129263363Semaste
130263363Semastetemplate <class C>
131263363Semastevoid
132263363Semasteprint_state(const char* msg, const char* first, const char* last, const C& db)
133263363Semaste{
134263363Semaste    printf("%s: ", msg);
135263363Semaste    for (; first != last; ++first)
136263363Semaste        printf("%c", *first);
137263363Semaste    printf("\n");
138263363Semaste    print_stack(db);
139263363Semaste}
140263363Semaste
141263363Semaste// <number> ::= [n] <non-negative decimal integer>
142263363Semaste
143263363Semasteconst char*
144263363Semasteparse_number(const char* first, const char* last)
145263363Semaste{
146263363Semaste    if (first != last)
147263363Semaste    {
148263363Semaste        const char* t = first;
149263363Semaste        if (*t == 'n')
150263363Semaste            ++t;
151263363Semaste        if (t != last)
152263363Semaste        {
153263363Semaste            if (*t == '0')
154263363Semaste            {
155263363Semaste                first = t+1;
156263363Semaste            }
157263363Semaste            else if ('1' <= *t && *t <= '9')
158263363Semaste            {
159263363Semaste                first = t+1;
160263363Semaste                while (first != last && std::isdigit(*first))
161263363Semaste                    ++first;
162263363Semaste            }
163263363Semaste        }
164263363Semaste    }
165263363Semaste    return first;
166263363Semaste}
167263363Semaste
168263363Semastetemplate <class Float>
169263363Semastestruct float_data;
170263363Semaste
171263363Semastetemplate <>
172263363Semastestruct float_data<float>
173263363Semaste{
174263363Semaste    static const size_t mangled_size = 8;
175263363Semaste    static const size_t max_demangled_size = 24;
176263363Semaste    static constexpr const char* spec = "%af";
177263363Semaste};
178263363Semaste
179263363Semasteconstexpr const char* float_data<float>::spec;
180263363Semaste
181263363Semastetemplate <>
182263363Semastestruct float_data<double>
183263363Semaste{
184263363Semaste    static const size_t mangled_size = 16;
185263363Semaste    static const size_t max_demangled_size = 32;
186263363Semaste    static constexpr const char* spec = "%a";
187263363Semaste};
188263363Semaste
189263363Semasteconstexpr const char* float_data<double>::spec;
190263363Semaste
191263363Semastetemplate <>
192263363Semastestruct float_data<long double>
193263363Semaste{
194263363Semaste    static const size_t mangled_size = 20;  // May need to be adjusted to 16 or 24 on other platforms
195263363Semaste    static const size_t max_demangled_size = 40;
196263363Semaste    static constexpr const char* spec = "%LaL";
197263363Semaste};
198263363Semaste
199263363Semasteconstexpr const char* float_data<long double>::spec;
200263363Semaste
201263363Semastetemplate <class Float, class C>
202263363Semasteconst char*
203263363Semasteparse_floating_number(const char* first, const char* last, C& db)
204263363Semaste{
205263363Semaste    const size_t N = float_data<Float>::mangled_size;
206263363Semaste    if (static_cast<std::size_t>(last - first) > N)
207263363Semaste    {
208263363Semaste        last = first + N;
209263363Semaste        union
210263363Semaste        {
211263363Semaste            Float value;
212263363Semaste            char buf[sizeof(Float)];
213263363Semaste        };
214263363Semaste        const char* t = first;
215263363Semaste        char* e = buf;
216263363Semaste        for (; t != last; ++t, ++e)
217263363Semaste        {
218263363Semaste            if (!isxdigit(*t))
219263363Semaste                return first;
220263363Semaste            unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
221263363Semaste                                        static_cast<unsigned>(*t - 'a' + 10);
222263363Semaste            ++t;
223263363Semaste            unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
224263363Semaste                                        static_cast<unsigned>(*t - 'a' + 10);
225263363Semaste            *e = static_cast<char>((d1 << 4) + d0);
226263363Semaste        }
227263363Semaste        if (*t == 'E')
228263363Semaste        {
229263363Semaste#if __LITTLE_ENDIAN__
230263363Semaste            std::reverse(buf, e);
231263363Semaste#endif
232263363Semaste            char num[float_data<Float>::max_demangled_size] = {0};
233263363Semaste            int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);
234263363Semaste            if (static_cast<std::size_t>(n) >= sizeof(num))
235263363Semaste                return first;
236263363Semaste            db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));
237263363Semaste            first = t+1;
238263363Semaste        }
239263363Semaste    }
240263363Semaste    return first;
241263363Semaste}
242263363Semaste
243263363Semaste// <source-name> ::= <positive length number> <identifier>
244263363Semaste
245263363Semastetemplate <class C>
246263363Semasteconst char*
247263363Semasteparse_source_name(const char* first, const char* last, C& db)
248263363Semaste{
249263363Semaste    if (first != last)
250263363Semaste    {
251263363Semaste        char c = *first;
252263363Semaste        if (isdigit(c) && first+1 != last)
253263363Semaste        {
254263363Semaste            const char* t = first+1;
255263363Semaste            size_t n = static_cast<size_t>(c - '0');
256263363Semaste            for (c = *t; isdigit(c); c = *t)
257263363Semaste            {
258263363Semaste                n = n * 10 + static_cast<size_t>(c - '0');
259263363Semaste                if (++t == last)
260263363Semaste                    return first;
261263363Semaste            }
262263363Semaste            if (static_cast<size_t>(last - t) >= n)
263263363Semaste            {
264263363Semaste                typename C::String r(t, n);
265263363Semaste                if (r.substr(0, 10) == "_GLOBAL__N")
266263363Semaste                    db.names.push_back("(anonymous namespace)");
267263363Semaste                else
268263363Semaste                    db.names.push_back(std::move(r));
269263363Semaste                first = t + n;
270263363Semaste            }
271263363Semaste        }
272263363Semaste    }
273263363Semaste    return first;
274263363Semaste}
275263363Semaste
276263363Semaste// <substitution> ::= S <seq-id> _
277263363Semaste//                ::= S_
278263363Semaste// <substitution> ::= Sa # ::std::allocator
279263363Semaste// <substitution> ::= Sb # ::std::basic_string
280263363Semaste// <substitution> ::= Ss # ::std::basic_string < char,
281263363Semaste//                                               ::std::char_traits<char>,
282263363Semaste//                                               ::std::allocator<char> >
283263363Semaste// <substitution> ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
284263363Semaste// <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
285263363Semaste// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
286263363Semaste
287263363Semastetemplate <class C>
288263363Semasteconst char*
289263363Semasteparse_substitution(const char* first, const char* last, C& db)
290263363Semaste{
291263363Semaste    if (last - first >= 2)
292263363Semaste    {
293263363Semaste        if (*first == 'S')
294263363Semaste        {
295263363Semaste            switch (first[1])
296263363Semaste            {
297263363Semaste            case 'a':
298263363Semaste                db.names.push_back("std::allocator");
299263363Semaste                first += 2;
300263363Semaste                break;
301263363Semaste            case 'b':
302263363Semaste                db.names.push_back("std::basic_string");
303263363Semaste                first += 2;
304263363Semaste                break;
305263363Semaste            case 's':
306263363Semaste                db.names.push_back("std::string");
307263363Semaste                first += 2;
308263363Semaste                break;
309263363Semaste            case 'i':
310263363Semaste                db.names.push_back("std::istream");
311263363Semaste                first += 2;
312263363Semaste                break;
313263363Semaste            case 'o':
314263363Semaste                db.names.push_back("std::ostream");
315263363Semaste                first += 2;
316263363Semaste                break;
317263363Semaste            case 'd':
318263363Semaste                db.names.push_back("std::iostream");
319263363Semaste                first += 2;
320263363Semaste                break;
321263363Semaste            case '_':
322263363Semaste                if (!db.subs.empty())
323263363Semaste                {
324263363Semaste                    for (const auto& n : db.subs.front())
325263363Semaste                        db.names.push_back(n);
326263363Semaste                    first += 2;
327263363Semaste                }
328263363Semaste                break;
329263363Semaste            default:
330263363Semaste                if (std::isdigit(first[1]) || std::isupper(first[1]))
331263363Semaste                {
332263363Semaste                    size_t sub = 0;
333263363Semaste                    const char* t = first+1;
334263363Semaste                    if (std::isdigit(*t))
335263363Semaste                        sub = static_cast<size_t>(*t - '0');
336263363Semaste                    else
337263363Semaste                        sub = static_cast<size_t>(*t - 'A') + 10;
338263363Semaste                    for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
339263363Semaste                    {
340263363Semaste                        sub *= 36;
341263363Semaste                        if (std::isdigit(*t))
342263363Semaste                            sub += static_cast<size_t>(*t - '0');
343263363Semaste                        else
344263363Semaste                            sub += static_cast<size_t>(*t - 'A') + 10;
345263363Semaste                    }
346263363Semaste                    if (t == last || *t != '_')
347263363Semaste                        return first;
348263363Semaste                    ++sub;
349263363Semaste                    if (sub < db.subs.size())
350263363Semaste                    {
351263363Semaste                        for (const auto& n : db.subs[sub])
352263363Semaste                            db.names.push_back(n);
353263363Semaste                        first = t+1;
354263363Semaste                    }
355263363Semaste                }
356263363Semaste                break;
357263363Semaste            }
358263363Semaste        }
359263363Semaste    }
360263363Semaste    return first;
361263363Semaste}
362263363Semaste
363263363Semaste// <builtin-type> ::= v    # void
364263363Semaste//                ::= w    # wchar_t
365263363Semaste//                ::= b    # bool
366263363Semaste//                ::= c    # char
367263363Semaste//                ::= a    # signed char
368263363Semaste//                ::= h    # unsigned char
369263363Semaste//                ::= s    # short
370263363Semaste//                ::= t    # unsigned short
371263363Semaste//                ::= i    # int
372263363Semaste//                ::= j    # unsigned int
373263363Semaste//                ::= l    # long
374263363Semaste//                ::= m    # unsigned long
375263363Semaste//                ::= x    # long long, __int64
376263363Semaste//                ::= y    # unsigned long long, __int64
377263363Semaste//                ::= n    # __int128
378263363Semaste//                ::= o    # unsigned __int128
379263363Semaste//                ::= f    # float
380263363Semaste//                ::= d    # double
381263363Semaste//                ::= e    # long double, __float80
382263363Semaste//                ::= g    # __float128
383263363Semaste//                ::= z    # ellipsis
384263363Semaste//                ::= Dd   # IEEE 754r decimal floating point (64 bits)
385263363Semaste//                ::= De   # IEEE 754r decimal floating point (128 bits)
386263363Semaste//                ::= Df   # IEEE 754r decimal floating point (32 bits)
387263363Semaste//                ::= Dh   # IEEE 754r half-precision floating point (16 bits)
388263363Semaste//                ::= Di   # char32_t
389263363Semaste//                ::= Ds   # char16_t
390263363Semaste//                ::= Da   # auto (in dependent new-expressions)
391263363Semaste//                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))
392263363Semaste//                ::= u <source-name>    # vendor extended type
393263363Semaste
394263363Semastetemplate <class C>
395263363Semasteconst char*
396263363Semasteparse_builtin_type(const char* first, const char* last, C& db)
397263363Semaste{
398263363Semaste    if (first != last)
399263363Semaste    {
400263363Semaste        switch (*first)
401263363Semaste        {
402263363Semaste        case 'v':
403263363Semaste            db.names.push_back("void");
404263363Semaste            ++first;
405263363Semaste            break;
406263363Semaste        case 'w':
407263363Semaste            db.names.push_back("wchar_t");
408263363Semaste            ++first;
409263363Semaste            break;
410263363Semaste        case 'b':
411263363Semaste            db.names.push_back("bool");
412263363Semaste            ++first;
413263363Semaste            break;
414263363Semaste        case 'c':
415263363Semaste            db.names.push_back("char");
416263363Semaste            ++first;
417263363Semaste            break;
418263363Semaste        case 'a':
419263363Semaste            db.names.push_back("signed char");
420263363Semaste            ++first;
421263363Semaste            break;
422263363Semaste        case 'h':
423263363Semaste            db.names.push_back("unsigned char");
424263363Semaste            ++first;
425263363Semaste            break;
426263363Semaste        case 's':
427263363Semaste            db.names.push_back("short");
428263363Semaste            ++first;
429263363Semaste            break;
430263363Semaste        case 't':
431263363Semaste            db.names.push_back("unsigned short");
432263363Semaste            ++first;
433263363Semaste            break;
434263363Semaste        case 'i':
435263363Semaste            db.names.push_back("int");
436263363Semaste            ++first;
437263363Semaste            break;
438263363Semaste        case 'j':
439263363Semaste            db.names.push_back("unsigned int");
440263363Semaste            ++first;
441263363Semaste            break;
442263363Semaste        case 'l':
443263363Semaste            db.names.push_back("long");
444263363Semaste            ++first;
445263363Semaste            break;
446263363Semaste        case 'm':
447263363Semaste            db.names.push_back("unsigned long");
448263363Semaste            ++first;
449263363Semaste            break;
450263363Semaste        case 'x':
451263363Semaste            db.names.push_back("long long");
452263363Semaste            ++first;
453263363Semaste            break;
454263363Semaste        case 'y':
455263363Semaste            db.names.push_back("unsigned long long");
456263363Semaste            ++first;
457263363Semaste            break;
458263363Semaste        case 'n':
459263363Semaste            db.names.push_back("__int128");
460263363Semaste            ++first;
461263363Semaste            break;
462263363Semaste        case 'o':
463263363Semaste            db.names.push_back("unsigned __int128");
464263363Semaste            ++first;
465263363Semaste            break;
466263363Semaste        case 'f':
467263363Semaste            db.names.push_back("float");
468263363Semaste            ++first;
469263363Semaste            break;
470263363Semaste        case 'd':
471263363Semaste            db.names.push_back("double");
472263363Semaste            ++first;
473263363Semaste            break;
474263363Semaste        case 'e':
475263363Semaste            db.names.push_back("long double");
476263363Semaste            ++first;
477263363Semaste            break;
478263363Semaste        case 'g':
479263363Semaste            db.names.push_back("__float128");
480263363Semaste            ++first;
481263363Semaste            break;
482263363Semaste        case 'z':
483263363Semaste            db.names.push_back("...");
484263363Semaste            ++first;
485263363Semaste            break;
486263363Semaste        case 'u':
487263363Semaste            {
488263363Semaste                const char*t = parse_source_name(first+1, last, db);
489263363Semaste                if (t != first+1)
490263363Semaste                    first = t;
491263363Semaste            }
492263363Semaste            break;
493263363Semaste        case 'D':
494263363Semaste            if (first+1 != last)
495263363Semaste            {
496263363Semaste                switch (first[1])
497263363Semaste                {
498263363Semaste                case 'd':
499263363Semaste                    db.names.push_back("decimal64");
500263363Semaste                    first += 2;
501263363Semaste                    break;
502263363Semaste                case 'e':
503263363Semaste                    db.names.push_back("decimal128");
504263363Semaste                    first += 2;
505263363Semaste                    break;
506263363Semaste                case 'f':
507263363Semaste                    db.names.push_back("decimal32");
508263363Semaste                    first += 2;
509263363Semaste                    break;
510263363Semaste                case 'h':
511263363Semaste                    db.names.push_back("decimal16");
512263363Semaste                    first += 2;
513263363Semaste                    break;
514263363Semaste                case 'i':
515263363Semaste                    db.names.push_back("char32_t");
516263363Semaste                    first += 2;
517263363Semaste                    break;
518263363Semaste                case 's':
519263363Semaste                    db.names.push_back("char16_t");
520263363Semaste                    first += 2;
521263363Semaste                    break;
522263363Semaste                case 'a':
523263363Semaste                    db.names.push_back("auto");
524263363Semaste                    first += 2;
525263363Semaste                    break;
526263363Semaste                case 'n':
527263363Semaste                    db.names.push_back("std::nullptr_t");
528263363Semaste                    first += 2;
529263363Semaste                    break;
530263363Semaste                }
531263363Semaste            }
532263363Semaste            break;
533263363Semaste        }
534263363Semaste    }
535263363Semaste    return first;
536263363Semaste}
537263363Semaste
538263363Semaste// <CV-qualifiers> ::= [r] [V] [K]
539263363Semaste
540263363Semasteconst char*
541263363Semasteparse_cv_qualifiers(const char* first, const char* last, unsigned& cv)
542263363Semaste{
543263363Semaste    cv = 0;
544263363Semaste    if (first != last)
545263363Semaste    {
546263363Semaste        if (*first == 'r')
547263363Semaste        {
548263363Semaste            cv |= 4;
549263363Semaste            ++first;
550263363Semaste        }
551263363Semaste        if (*first == 'V')
552263363Semaste        {
553263363Semaste            cv |= 2;
554263363Semaste            ++first;
555263363Semaste        }
556263363Semaste        if (*first == 'K')
557263363Semaste        {
558263363Semaste            cv |= 1;
559263363Semaste            ++first;
560263363Semaste        }
561263363Semaste    }
562263363Semaste    return first;
563263363Semaste}
564263363Semaste
565263363Semaste// <template-param> ::= T_    # first template parameter
566263363Semaste//                  ::= T <parameter-2 non-negative number> _
567263363Semaste
568263363Semastetemplate <class C>
569263363Semasteconst char*
570263363Semasteparse_template_param(const char* first, const char* last, C& db)
571263363Semaste{
572263363Semaste    if (last - first >= 2)
573263363Semaste    {
574263363Semaste        if (*first == 'T')
575263363Semaste        {
576263363Semaste            if (first[1] == '_')
577263363Semaste            {
578269024Semaste                if (db.template_param.empty())
579269024Semaste                    return first;
580263363Semaste                if (!db.template_param.back().empty())
581263363Semaste                {
582263363Semaste                    for (auto& t : db.template_param.back().front())
583263363Semaste                        db.names.push_back(t);
584263363Semaste                    first += 2;
585263363Semaste                }
586263363Semaste                else
587263363Semaste                {
588263363Semaste                    db.names.push_back("T_");
589263363Semaste                    first += 2;
590263363Semaste                    db.fix_forward_references = true;
591263363Semaste                }
592263363Semaste            }
593263363Semaste            else if (isdigit(first[1]))
594263363Semaste            {
595263363Semaste                const char* t = first+1;
596263363Semaste                size_t sub = static_cast<size_t>(*t - '0');
597263363Semaste                for (++t; t != last && isdigit(*t); ++t)
598263363Semaste                {
599263363Semaste                    sub *= 10;
600263363Semaste                    sub += static_cast<size_t>(*t - '0');
601263363Semaste                }
602269024Semaste                if (t == last || *t != '_' || db.template_param.empty())
603263363Semaste                    return first;
604263363Semaste                ++sub;
605263363Semaste                if (sub < db.template_param.back().size())
606263363Semaste                {
607263363Semaste                    for (auto& temp : db.template_param.back()[sub])
608263363Semaste                        db.names.push_back(temp);
609263363Semaste                    first = t+1;
610263363Semaste                }
611263363Semaste                else
612263363Semaste                {
613263363Semaste                    db.names.push_back(typename C::String(first, t+1));
614263363Semaste                    first = t+1;
615263363Semaste                    db.fix_forward_references = true;
616263363Semaste                }
617263363Semaste            }
618263363Semaste        }
619263363Semaste    }
620263363Semaste    return first;
621263363Semaste}
622263363Semaste
623263363Semaste// cc <type> <expression>                               # const_cast<type> (expression)
624263363Semaste
625263363Semastetemplate <class C>
626263363Semasteconst char*
627263363Semasteparse_const_cast_expr(const char* first, const char* last, C& db)
628263363Semaste{
629263363Semaste    if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
630263363Semaste    {
631263363Semaste        const char* t = parse_type(first+2, last, db);
632263363Semaste        if (t != first+2)
633263363Semaste        {
634263363Semaste            const char* t1 = parse_expression(t, last, db);
635263363Semaste            if (t1 != t)
636263363Semaste            {
637269024Semaste                if (db.names.size() < 2)
638269024Semaste                    return first;
639263363Semaste                auto expr = db.names.back().move_full();
640263363Semaste                db.names.pop_back();
641263363Semaste                db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
642263363Semaste                first = t1;
643263363Semaste            }
644263363Semaste        }
645263363Semaste    }
646263363Semaste    return first;
647263363Semaste}
648263363Semaste
649263363Semaste// dc <type> <expression>                               # dynamic_cast<type> (expression)
650263363Semaste
651263363Semastetemplate <class C>
652263363Semasteconst char*
653263363Semasteparse_dynamic_cast_expr(const char* first, const char* last, C& db)
654263363Semaste{
655263363Semaste    if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')
656263363Semaste    {
657263363Semaste        const char* t = parse_type(first+2, last, db);
658263363Semaste        if (t != first+2)
659263363Semaste        {
660263363Semaste            const char* t1 = parse_expression(t, last, db);
661263363Semaste            if (t1 != t)
662263363Semaste            {
663269024Semaste                if (db.names.size() < 2)
664269024Semaste                    return first;
665263363Semaste                auto expr = db.names.back().move_full();
666263363Semaste                db.names.pop_back();
667263363Semaste                db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";
668263363Semaste                first = t1;
669263363Semaste            }
670263363Semaste        }
671263363Semaste    }
672263363Semaste    return first;
673263363Semaste}
674263363Semaste
675263363Semaste// rc <type> <expression>                               # reinterpret_cast<type> (expression)
676263363Semaste
677263363Semastetemplate <class C>
678263363Semasteconst char*
679263363Semasteparse_reinterpret_cast_expr(const char* first, const char* last, C& db)
680263363Semaste{
681263363Semaste    if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')
682263363Semaste    {
683263363Semaste        const char* t = parse_type(first+2, last, db);
684263363Semaste        if (t != first+2)
685263363Semaste        {
686263363Semaste            const char* t1 = parse_expression(t, last, db);
687263363Semaste            if (t1 != t)
688263363Semaste            {
689269024Semaste                if (db.names.size() < 2)
690269024Semaste                    return first;
691263363Semaste                auto expr = db.names.back().move_full();
692263363Semaste                db.names.pop_back();
693263363Semaste                db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")";
694263363Semaste                first = t1;
695263363Semaste            }
696263363Semaste        }
697263363Semaste    }
698263363Semaste    return first;
699263363Semaste}
700263363Semaste
701263363Semaste// sc <type> <expression>                               # static_cast<type> (expression)
702263363Semaste
703263363Semastetemplate <class C>
704263363Semasteconst char*
705263363Semasteparse_static_cast_expr(const char* first, const char* last, C& db)
706263363Semaste{
707263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 'c')
708263363Semaste    {
709263363Semaste        const char* t = parse_type(first+2, last, db);
710263363Semaste        if (t != first+2)
711263363Semaste        {
712263363Semaste            const char* t1 = parse_expression(t, last, db);
713263363Semaste            if (t1 != t)
714263363Semaste            {
715269024Semaste                if (db.names.size() < 2)
716269024Semaste                    return first;
717263363Semaste                auto expr = db.names.back().move_full();
718263363Semaste                db.names.pop_back();
719263363Semaste                db.names.back() = "static_cast<" + db.names.back().move_full() + ">(" + expr + ")";
720263363Semaste                first = t1;
721263363Semaste            }
722263363Semaste        }
723263363Semaste    }
724263363Semaste    return first;
725263363Semaste}
726263363Semaste
727263363Semaste// sp <expression>                                  # pack expansion
728263363Semaste
729263363Semastetemplate <class C>
730263363Semasteconst char*
731263363Semasteparse_pack_expansion(const char* first, const char* last, C& db)
732263363Semaste{
733263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 'p')
734263363Semaste    {
735263363Semaste        const char* t = parse_expression(first+2, last, db);
736263363Semaste        if (t != first+2)
737263363Semaste            first = t;
738263363Semaste    }
739263363Semaste    return first;
740263363Semaste}
741263363Semaste
742263363Semaste// st <type>                                            # sizeof (a type)
743263363Semaste
744263363Semastetemplate <class C>
745263363Semasteconst char*
746263363Semasteparse_sizeof_type_expr(const char* first, const char* last, C& db)
747263363Semaste{
748263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 't')
749263363Semaste    {
750263363Semaste        const char* t = parse_type(first+2, last, db);
751263363Semaste        if (t != first+2)
752263363Semaste        {
753269024Semaste            if (db.names.empty())
754269024Semaste                return first;
755263363Semaste            db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
756263363Semaste            first = t;
757263363Semaste        }
758263363Semaste    }
759263363Semaste    return first;
760263363Semaste}
761263363Semaste
762263363Semaste// sz <expr>                                            # sizeof (a expression)
763263363Semaste
764263363Semastetemplate <class C>
765263363Semasteconst char*
766263363Semasteparse_sizeof_expr_expr(const char* first, const char* last, C& db)
767263363Semaste{
768263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 'z')
769263363Semaste    {
770263363Semaste        const char* t = parse_expression(first+2, last, db);
771263363Semaste        if (t != first+2)
772263363Semaste        {
773269024Semaste            if (db.names.empty())
774269024Semaste                return first;
775263363Semaste            db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
776263363Semaste            first = t;
777263363Semaste        }
778263363Semaste    }
779263363Semaste    return first;
780263363Semaste}
781263363Semaste
782263363Semaste// sZ <template-param>                                  # size of a parameter pack
783263363Semaste
784263363Semastetemplate <class C>
785263363Semasteconst char*
786263363Semasteparse_sizeof_param_pack_expr(const char* first, const char* last, C& db)
787263363Semaste{
788263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')
789263363Semaste    {
790263363Semaste        size_t k0 = db.names.size();
791263363Semaste        const char* t = parse_template_param(first+2, last, db);
792263363Semaste        size_t k1 = db.names.size();
793263363Semaste        if (t != first+2)
794263363Semaste        {
795263363Semaste            typename C::String tmp("sizeof...(");
796263363Semaste            size_t k = k0;
797263363Semaste            if (k != k1)
798263363Semaste            {
799263363Semaste                tmp += db.names[k].move_full();
800263363Semaste                for (++k; k != k1; ++k)
801263363Semaste                    tmp += ", " + db.names[k].move_full();
802263363Semaste            }
803263363Semaste            tmp += ")";
804263363Semaste            for (; k1 != k0; --k1)
805263363Semaste                db.names.pop_back();
806263363Semaste            db.names.push_back(std::move(tmp));
807263363Semaste            first = t;
808263363Semaste        }
809263363Semaste    }
810263363Semaste    return first;
811263363Semaste}
812263363Semaste
813263363Semaste// <function-param> ::= fp <top-level CV-qualifiers> _                                     # L == 0, first parameter
814263363Semaste//                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
815263363Semaste//                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter
816263363Semaste//                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
817263363Semaste
818263363Semastetemplate <class C>
819263363Semasteconst char*
820263363Semasteparse_function_param(const char* first, const char* last, C& db)
821263363Semaste{
822263363Semaste    if (last - first >= 3 && *first == 'f')
823263363Semaste    {
824263363Semaste        if (first[1] == 'p')
825263363Semaste        {
826263363Semaste            unsigned cv;
827263363Semaste            const char* t = parse_cv_qualifiers(first+2, last, cv);
828263363Semaste            const char* t1 = parse_number(t, last);
829263363Semaste            if (t1 != last && *t1 == '_')
830263363Semaste            {
831263363Semaste                db.names.push_back("fp" + typename C::String(t, t1));
832263363Semaste                first = t1+1;
833263363Semaste            }
834263363Semaste        }
835263363Semaste        else if (first[1] == 'L')
836263363Semaste        {
837263363Semaste            unsigned cv;
838263363Semaste            const char* t0 = parse_number(first+2, last);
839263363Semaste            if (t0 != last && *t0 == 'p')
840263363Semaste            {
841263363Semaste                ++t0;
842263363Semaste                const char* t = parse_cv_qualifiers(t0, last, cv);
843263363Semaste                const char* t1 = parse_number(t, last);
844263363Semaste                if (t1 != last && *t1 == '_')
845263363Semaste                {
846263363Semaste                    db.names.push_back("fp" + typename C::String(t, t1));
847263363Semaste                    first = t1+1;
848263363Semaste                }
849263363Semaste            }
850263363Semaste        }
851263363Semaste    }
852263363Semaste    return first;
853263363Semaste}
854263363Semaste
855263363Semaste// sZ <function-param>                                  # size of a function parameter pack
856263363Semaste
857263363Semastetemplate <class C>
858263363Semasteconst char*
859263363Semasteparse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db)
860263363Semaste{
861263363Semaste    if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')
862263363Semaste    {
863263363Semaste        const char* t = parse_function_param(first+2, last, db);
864263363Semaste        if (t != first+2)
865263363Semaste        {
866269024Semaste            if (db.names.empty())
867269024Semaste                return first;
868263363Semaste            db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
869263363Semaste            first = t;
870263363Semaste        }
871263363Semaste    }
872263363Semaste    return first;
873263363Semaste}
874263363Semaste
875263363Semaste// te <expression>                                      # typeid (expression)
876263363Semaste// ti <type>                                            # typeid (type)
877263363Semaste
878263363Semastetemplate <class C>
879263363Semasteconst char*
880263363Semasteparse_typeid_expr(const char* first, const char* last, C& db)
881263363Semaste{
882263363Semaste    if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
883263363Semaste    {
884263363Semaste        const char* t;
885263363Semaste        if (first[1] == 'e')
886263363Semaste            t = parse_expression(first+2, last, db);
887263363Semaste        else
888263363Semaste            t = parse_type(first+2, last, db);
889263363Semaste        if (t != first+2)
890263363Semaste        {
891269024Semaste            if (db.names.empty())
892269024Semaste                return first;
893263363Semaste            db.names.back() = "typeid(" + db.names.back().move_full() + ")";
894263363Semaste            first = t;
895263363Semaste        }
896263363Semaste    }
897263363Semaste    return first;
898263363Semaste}
899263363Semaste
900263363Semaste// tw <expression>                                      # throw expression
901263363Semaste
902263363Semastetemplate <class C>
903263363Semasteconst char*
904263363Semasteparse_throw_expr(const char* first, const char* last, C& db)
905263363Semaste{
906263363Semaste    if (last - first >= 3 && first[0] == 't' && first[1] == 'w')
907263363Semaste    {
908263363Semaste        const char* t = parse_expression(first+2, last, db);
909263363Semaste        if (t != first+2)
910263363Semaste        {
911269024Semaste            if (db.names.empty())
912269024Semaste                return first;
913263363Semaste            db.names.back() = "throw " + db.names.back().move_full();
914263363Semaste            first = t;
915263363Semaste        }
916263363Semaste    }
917263363Semaste    return first;
918263363Semaste}
919263363Semaste
920263363Semaste// ds <expression> <expression>                         # expr.*expr
921263363Semaste
922263363Semastetemplate <class C>
923263363Semasteconst char*
924263363Semasteparse_dot_star_expr(const char* first, const char* last, C& db)
925263363Semaste{
926263363Semaste    if (last - first >= 3 && first[0] == 'd' && first[1] == 's')
927263363Semaste    {
928263363Semaste        const char* t = parse_expression(first+2, last, db);
929263363Semaste        if (t != first+2)
930263363Semaste        {
931263363Semaste            const char* t1 = parse_expression(t, last, db);
932263363Semaste            if (t1 != t)
933263363Semaste            {
934269024Semaste                if (db.names.size() < 2)
935269024Semaste                    return first;
936263363Semaste                auto expr = db.names.back().move_full();
937263363Semaste                db.names.pop_back();
938263363Semaste                db.names.back().first += ".*" + expr;
939263363Semaste                first = t1;
940263363Semaste            }
941263363Semaste        }
942263363Semaste    }
943263363Semaste    return first;
944263363Semaste}
945263363Semaste
946263363Semaste// <simple-id> ::= <source-name> [ <template-args> ]
947263363Semaste
948263363Semastetemplate <class C>
949263363Semasteconst char*
950263363Semasteparse_simple_id(const char* first, const char* last, C& db)
951263363Semaste{
952263363Semaste    if (first != last)
953263363Semaste    {
954263363Semaste        const char* t = parse_source_name(first, last, db);
955263363Semaste        if (t != first)
956263363Semaste        {
957263363Semaste            const char* t1 = parse_template_args(t, last, db);
958263363Semaste            if (t1 != t)
959263363Semaste            {
960269024Semaste                if (db.names.size() < 2)
961269024Semaste                    return first;
962263363Semaste                auto args = db.names.back().move_full();
963263363Semaste                db.names.pop_back();
964263363Semaste                db.names.back().first += std::move(args);
965263363Semaste            }
966263363Semaste            first = t1;
967263363Semaste        }
968263363Semaste        else
969263363Semaste            first = t;
970263363Semaste    }
971263363Semaste    return first;
972263363Semaste}
973263363Semaste
974263363Semaste// <unresolved-type> ::= <template-param>
975263363Semaste//                   ::= <decltype>
976263363Semaste//                   ::= <substitution>
977263363Semaste
978263363Semastetemplate <class C>
979263363Semasteconst char*
980263363Semasteparse_unresolved_type(const char* first, const char* last, C& db)
981263363Semaste{
982263363Semaste    if (first != last)
983263363Semaste    {
984263363Semaste        const char* t = first;
985263363Semaste        switch (*first)
986263363Semaste        {
987263363Semaste        case 'T':
988263363Semaste          {
989263363Semaste            size_t k0 = db.names.size();
990263363Semaste            t = parse_template_param(first, last, db);
991263363Semaste            size_t k1 = db.names.size();
992263363Semaste            if (t != first && k1 == k0 + 1)
993263363Semaste            {
994263363Semaste                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
995263363Semaste                first = t;
996263363Semaste            }
997263363Semaste            else
998263363Semaste            {
999263363Semaste                for (; k1 != k0; --k1)
1000263363Semaste                    db.names.pop_back();
1001263363Semaste            }
1002263363Semaste            break;
1003263363Semaste          }
1004263363Semaste        case 'D':
1005263363Semaste            t = parse_decltype(first, last, db);
1006263363Semaste            if (t != first)
1007263363Semaste            {
1008269024Semaste                if (db.names.empty())
1009269024Semaste                    return first;
1010263363Semaste                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1011263363Semaste                first = t;
1012263363Semaste            }
1013263363Semaste            break;
1014263363Semaste        case 'S':
1015263363Semaste            t = parse_substitution(first, last, db);
1016263363Semaste            if (t != first)
1017263363Semaste                first = t;
1018263363Semaste            else
1019263363Semaste            {
1020263363Semaste                if (last - first > 2 && first[1] == 't')
1021263363Semaste                {
1022263363Semaste                    t = parse_unqualified_name(first+2, last, db);
1023263363Semaste                    if (t != first+2)
1024263363Semaste                    {
1025269024Semaste                        if (db.names.empty())
1026269024Semaste                            return first;
1027263363Semaste                        db.names.back().first.insert(0, "std::");
1028263363Semaste                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1029263363Semaste                        first = t;
1030263363Semaste                    }
1031263363Semaste                }
1032263363Semaste            }
1033263363Semaste            break;
1034263363Semaste       }
1035263363Semaste    }
1036263363Semaste    return first;
1037263363Semaste}
1038263363Semaste
1039263363Semaste// <destructor-name> ::= <unresolved-type>                               # e.g., ~T or ~decltype(f())
1040263363Semaste//                   ::= <simple-id>                                     # e.g., ~A<2*N>
1041263363Semaste
1042263363Semastetemplate <class C>
1043263363Semasteconst char*
1044263363Semasteparse_destructor_name(const char* first, const char* last, C& db)
1045263363Semaste{
1046263363Semaste    if (first != last)
1047263363Semaste    {
1048263363Semaste        const char* t = parse_unresolved_type(first, last, db);
1049263363Semaste        if (t == first)
1050263363Semaste            t = parse_simple_id(first, last, db);
1051263363Semaste        if (t != first)
1052263363Semaste        {
1053269024Semaste            if (db.names.empty())
1054269024Semaste                return first;
1055263363Semaste            db.names.back().first.insert(0, "~");
1056263363Semaste            first = t;
1057263363Semaste        }
1058263363Semaste    }
1059263363Semaste    return first;
1060263363Semaste}
1061263363Semaste
1062263363Semaste// <base-unresolved-name> ::= <simple-id>                                # unresolved name
1063263363Semaste//          extension     ::= <operator-name>                            # unresolved operator-function-id
1064263363Semaste//          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
1065263363Semaste//                        ::= on <operator-name>                         # unresolved operator-function-id
1066263363Semaste//                        ::= on <operator-name> <template-args>         # unresolved operator template-id
1067263363Semaste//                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
1068263363Semaste//                                                                         # e.g. ~X or ~X<N-1>
1069263363Semaste
1070263363Semastetemplate <class C>
1071263363Semasteconst char*
1072263363Semasteparse_base_unresolved_name(const char* first, const char* last, C& db)
1073263363Semaste{
1074263363Semaste    if (last - first >= 2)
1075263363Semaste    {
1076263363Semaste        if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
1077263363Semaste        {
1078263363Semaste            if (first[0] == 'o')
1079263363Semaste            {
1080263363Semaste                const char* t = parse_operator_name(first+2, last, db);
1081263363Semaste                if (t != first+2)
1082263363Semaste                {
1083263363Semaste                    first = parse_template_args(t, last, db);
1084263363Semaste                    if (first != t)
1085263363Semaste                    {
1086269024Semaste                        if (db.names.size() < 2)
1087269024Semaste                            return first;
1088263363Semaste                        auto args = db.names.back().move_full();
1089263363Semaste                        db.names.pop_back();
1090263363Semaste                        db.names.back().first += std::move(args);
1091263363Semaste                    }
1092263363Semaste                }
1093263363Semaste            }
1094263363Semaste            else
1095263363Semaste            {
1096263363Semaste                const char* t = parse_destructor_name(first+2, last, db);
1097263363Semaste                if (t != first+2)
1098263363Semaste                    first = t;
1099263363Semaste            }
1100263363Semaste        }
1101263363Semaste        else
1102263363Semaste        {
1103263363Semaste            const char* t = parse_simple_id(first, last, db);
1104263363Semaste            if (t == first)
1105263363Semaste            {
1106263363Semaste                t = parse_operator_name(first, last, db);
1107263363Semaste                if (t != first)
1108263363Semaste                {
1109263363Semaste                    first = parse_template_args(t, last, db);
1110263363Semaste                    if (first != t)
1111263363Semaste                    {
1112269024Semaste                        if (db.names.size() < 2)
1113269024Semaste                            return first;
1114263363Semaste                        auto args = db.names.back().move_full();
1115263363Semaste                        db.names.pop_back();
1116263363Semaste                        db.names.back().first += std::move(args);
1117263363Semaste                    }
1118263363Semaste                }
1119263363Semaste            }
1120263363Semaste            else
1121263363Semaste                first = t;
1122263363Semaste        }
1123263363Semaste    }
1124263363Semaste    return first;
1125263363Semaste}
1126263363Semaste
1127263363Semaste// <unresolved-qualifier-level> ::= <simple-id>
1128263363Semaste
1129263363Semastetemplate <class C>
1130263363Semasteconst char*
1131263363Semasteparse_unresolved_qualifier_level(const char* first, const char* last, C& db)
1132263363Semaste{
1133263363Semaste    return parse_simple_id(first, last, db);
1134263363Semaste}
1135263363Semaste
1136263363Semaste// <unresolved-name>
1137263363Semaste//  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
1138263363Semaste//                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
1139263363Semaste//                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
1140263363Semaste//                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
1141263363Semaste//                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
1142263363Semaste//  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
1143263363Semaste//                                                                       # T::N::x /decltype(p)::N::x
1144263363Semaste//  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
1145263363Semaste
1146263363Semastetemplate <class C>
1147263363Semasteconst char*
1148263363Semasteparse_unresolved_name(const char* first, const char* last, C& db)
1149263363Semaste{
1150263363Semaste    if (last - first > 2)
1151263363Semaste    {
1152263363Semaste        const char* t = first;
1153263363Semaste        bool global = false;
1154263363Semaste        if (t[0] == 'g' && t[1] == 's')
1155263363Semaste        {
1156263363Semaste            global = true;
1157263363Semaste            t += 2;
1158263363Semaste        }
1159263363Semaste        const char* t2 = parse_base_unresolved_name(t, last, db);
1160263363Semaste        if (t2 != t)
1161263363Semaste        {
1162263363Semaste            if (global)
1163269024Semaste            {
1164269024Semaste                if (db.names.empty())
1165269024Semaste                    return first;
1166263363Semaste                db.names.back().first.insert(0, "::");
1167269024Semaste            }
1168263363Semaste            first = t2;
1169263363Semaste        }
1170263363Semaste        else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
1171263363Semaste        {
1172263363Semaste            if (t[2] == 'N')
1173263363Semaste            {
1174263363Semaste                t += 3;
1175263363Semaste                const char* t1 = parse_unresolved_type(t, last, db);
1176263363Semaste                if (t1 == t || t1 == last)
1177263363Semaste                    return first;
1178263363Semaste                t = t1;
1179263363Semaste                t1 = parse_template_args(t, last, db);
1180263363Semaste                if (t1 != t)
1181263363Semaste                {
1182269024Semaste                    if (db.names.size() < 2)
1183269024Semaste                        return first;
1184263363Semaste                    auto args = db.names.back().move_full();
1185263363Semaste                    db.names.pop_back();
1186263363Semaste                    db.names.back().first += std::move(args);
1187263363Semaste                    t = t1;
1188263363Semaste                    if (t == last)
1189263363Semaste                    {
1190263363Semaste                        db.names.pop_back();
1191263363Semaste                        return first;
1192263363Semaste                    }
1193263363Semaste                }
1194263363Semaste                while (*t != 'E')
1195263363Semaste                {
1196263363Semaste                    t1 = parse_unresolved_qualifier_level(t, last, db);
1197269024Semaste                    if (t1 == t || t1 == last || db.names.size() < 2)
1198263363Semaste                        return first;
1199263363Semaste                    auto s = db.names.back().move_full();
1200263363Semaste                    db.names.pop_back();
1201263363Semaste                    db.names.back().first += "::" + std::move(s);
1202263363Semaste                    t = t1;
1203263363Semaste                }
1204263363Semaste                ++t;
1205263363Semaste                t1 = parse_base_unresolved_name(t, last, db);
1206263363Semaste                if (t1 == t)
1207263363Semaste                {
1208269024Semaste                    if (!db.names.empty())
1209269024Semaste                        db.names.pop_back();
1210263363Semaste                    return first;
1211263363Semaste                }
1212269024Semaste                if (db.names.size() < 2)
1213269024Semaste                    return first;
1214263363Semaste                auto s = db.names.back().move_full();
1215263363Semaste                db.names.pop_back();
1216263363Semaste                db.names.back().first += "::" + std::move(s);
1217263363Semaste                first = t1;
1218263363Semaste            }
1219263363Semaste            else
1220263363Semaste            {
1221263363Semaste                t += 2;
1222263363Semaste                const char* t1 = parse_unresolved_type(t, last, db);
1223263363Semaste                if (t1 != t)
1224263363Semaste                {
1225263363Semaste                    t = t1;
1226263363Semaste                    t1 = parse_template_args(t, last, db);
1227263363Semaste                    if (t1 != t)
1228263363Semaste                    {
1229269024Semaste                        if (db.names.size() < 2)
1230269024Semaste                            return first;
1231263363Semaste                        auto args = db.names.back().move_full();
1232263363Semaste                        db.names.pop_back();
1233263363Semaste                        db.names.back().first += std::move(args);
1234263363Semaste                        t = t1;
1235263363Semaste                    }
1236263363Semaste                    t1 = parse_base_unresolved_name(t, last, db);
1237263363Semaste                    if (t1 == t)
1238263363Semaste                    {
1239269024Semaste                        if (!db.names.empty())
1240269024Semaste                            db.names.pop_back();
1241263363Semaste                        return first;
1242263363Semaste                    }
1243269024Semaste                    if (db.names.size() < 2)
1244269024Semaste                        return first;
1245263363Semaste                    auto s = db.names.back().move_full();
1246263363Semaste                    db.names.pop_back();
1247263363Semaste                    db.names.back().first += "::" + std::move(s);
1248263363Semaste                    first = t1;
1249263363Semaste                }
1250263363Semaste                else
1251263363Semaste                {
1252263363Semaste                    t1 = parse_unresolved_qualifier_level(t, last, db);
1253263363Semaste                    if (t1 == t || t1 == last)
1254263363Semaste                        return first;
1255263363Semaste                    t = t1;
1256263363Semaste                    if (global)
1257269024Semaste                    {
1258269024Semaste                        if (db.names.empty())
1259269024Semaste                            return first;
1260263363Semaste                        db.names.back().first.insert(0, "::");
1261269024Semaste                    }
1262263363Semaste                    while (*t != 'E')
1263263363Semaste                    {
1264263363Semaste                        t1 = parse_unresolved_qualifier_level(t, last, db);
1265269024Semaste                        if (t1 == t || t1 == last || db.names.size() < 2)
1266263363Semaste                            return first;
1267263363Semaste                        auto s = db.names.back().move_full();
1268263363Semaste                        db.names.pop_back();
1269263363Semaste                        db.names.back().first += "::" + std::move(s);
1270263363Semaste                        t = t1;
1271263363Semaste                    }
1272263363Semaste                    ++t;
1273263363Semaste                    t1 = parse_base_unresolved_name(t, last, db);
1274263363Semaste                    if (t1 == t)
1275263363Semaste                    {
1276269024Semaste                        if (!db.names.empty())
1277269024Semaste                            db.names.pop_back();
1278263363Semaste                        return first;
1279263363Semaste                    }
1280269024Semaste                    if (db.names.size() < 2)
1281269024Semaste                        return first;
1282263363Semaste                    auto s = db.names.back().move_full();
1283263363Semaste                    db.names.pop_back();
1284263363Semaste                    db.names.back().first += "::" + std::move(s);
1285263363Semaste                    first = t1;
1286263363Semaste                }
1287263363Semaste            }
1288263363Semaste        }
1289263363Semaste    }
1290263363Semaste    return first;
1291263363Semaste}
1292263363Semaste
1293263363Semaste// dt <expression> <unresolved-name>                    # expr.name
1294263363Semaste
1295263363Semastetemplate <class C>
1296263363Semasteconst char*
1297263363Semasteparse_dot_expr(const char* first, const char* last, C& db)
1298263363Semaste{
1299263363Semaste    if (last - first >= 3 && first[0] == 'd' && first[1] == 't')
1300263363Semaste    {
1301263363Semaste        const char* t = parse_expression(first+2, last, db);
1302263363Semaste        if (t != first+2)
1303263363Semaste        {
1304263363Semaste            const char* t1 = parse_unresolved_name(t, last, db);
1305263363Semaste            if (t1 != t)
1306263363Semaste            {
1307269024Semaste                if (db.names.size() < 2)
1308269024Semaste                    return first;
1309263363Semaste                auto name = db.names.back().move_full();
1310263363Semaste                db.names.pop_back();
1311263363Semaste                db.names.back().first += "." + name;
1312263363Semaste                first = t1;
1313263363Semaste            }
1314263363Semaste        }
1315263363Semaste    }
1316263363Semaste    return first;
1317263363Semaste}
1318263363Semaste
1319263363Semaste// cl <expression>+ E                                   # call
1320263363Semaste
1321263363Semastetemplate <class C>
1322263363Semasteconst char*
1323263363Semasteparse_call_expr(const char* first, const char* last, C& db)
1324263363Semaste{
1325263363Semaste    if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')
1326263363Semaste    {
1327263363Semaste        const char* t = parse_expression(first+2, last, db);
1328263363Semaste        if (t != first+2)
1329263363Semaste        {
1330263363Semaste            if (t == last)
1331263363Semaste                return first;
1332269024Semaste            if (db.names.empty())
1333269024Semaste                return first;
1334263363Semaste            db.names.back().first += db.names.back().second;
1335263363Semaste            db.names.back().second = typename C::String();
1336263363Semaste            db.names.back().first.append("(");
1337263363Semaste            bool first_expr = true;
1338263363Semaste            while (*t != 'E')
1339263363Semaste            {
1340263363Semaste                const char* t1 = parse_expression(t, last, db);
1341263363Semaste                if (t1 == t || t1 == last)
1342263363Semaste                    return first;
1343269024Semaste                if (db.names.empty())
1344269024Semaste                    return first;
1345263363Semaste                auto tmp = db.names.back().move_full();
1346263363Semaste                db.names.pop_back();
1347263363Semaste                if (!tmp.empty())
1348263363Semaste                {
1349269024Semaste                    if (db.names.empty())
1350269024Semaste                        return first;
1351263363Semaste                    if (!first_expr)
1352263363Semaste                    {
1353263363Semaste                        db.names.back().first.append(", ");
1354263363Semaste                        first_expr = false;
1355263363Semaste                    }
1356263363Semaste                    db.names.back().first.append(tmp);
1357263363Semaste                }
1358263363Semaste                t = t1;
1359263363Semaste            }
1360263363Semaste            ++t;
1361269024Semaste            if (db.names.empty())
1362269024Semaste                return first;
1363263363Semaste            db.names.back().first.append(")");
1364263363Semaste            first = t;
1365263363Semaste        }
1366263363Semaste    }
1367263363Semaste    return first;
1368263363Semaste}
1369263363Semaste
1370263363Semaste// [gs] nw <expression>* _ <type> E                     # new (expr-list) type
1371263363Semaste// [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
1372263363Semaste// [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
1373263363Semaste// [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
1374263363Semaste// <initializer> ::= pi <expression>* E                 # parenthesized initialization
1375263363Semaste
1376263363Semastetemplate <class C>
1377263363Semasteconst char*
1378263363Semasteparse_new_expr(const char* first, const char* last, C& db)
1379263363Semaste{
1380263363Semaste    if (last - first >= 4)
1381263363Semaste    {
1382263363Semaste        const char* t = first;
1383263363Semaste        bool parsed_gs = false;
1384263363Semaste        if (t[0] == 'g' && t[1] == 's')
1385263363Semaste        {
1386263363Semaste            t += 2;
1387263363Semaste            parsed_gs = true;
1388263363Semaste        }
1389263363Semaste        if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))
1390263363Semaste        {
1391263363Semaste            bool is_array = t[1] == 'a';
1392263363Semaste            t += 2;
1393263363Semaste            if (t == last)
1394263363Semaste                return first;
1395263363Semaste            bool has_expr_list = false;
1396263363Semaste            bool first_expr = true;
1397263363Semaste            while (*t != '_')
1398263363Semaste            {
1399263363Semaste                const char* t1 = parse_expression(t, last, db);
1400263363Semaste                if (t1 == t || t1 == last)
1401263363Semaste                    return first;
1402263363Semaste                has_expr_list = true;
1403263363Semaste                if (!first_expr)
1404263363Semaste                {
1405269024Semaste                    if (db.names.empty())
1406269024Semaste                        return first;
1407263363Semaste                    auto tmp = db.names.back().move_full();
1408263363Semaste                    db.names.pop_back();
1409263363Semaste                    if (!tmp.empty())
1410263363Semaste                    {
1411269024Semaste                        if (db.names.empty())
1412269024Semaste                            return first;
1413263363Semaste                        db.names.back().first.append(", ");
1414263363Semaste                        db.names.back().first.append(tmp);
1415263363Semaste                        first_expr = false;
1416263363Semaste                    }
1417263363Semaste                }
1418263363Semaste                t = t1;
1419263363Semaste            }
1420263363Semaste            ++t;
1421263363Semaste            const char* t1 = parse_type(t, last, db);
1422263363Semaste            if (t1 == t || t1 == last)
1423263363Semaste                return first;
1424263363Semaste            t = t1;
1425263363Semaste            bool has_init = false;
1426263363Semaste            if (last - t >= 3 && t[0] == 'p' && t[1] == 'i')
1427263363Semaste            {
1428263363Semaste                t += 2;
1429263363Semaste                has_init = true;
1430263363Semaste                first_expr = true;
1431263363Semaste                while (*t != 'E')
1432263363Semaste                {
1433263363Semaste                    t1 = parse_expression(t, last, db);
1434263363Semaste                    if (t1 == t || t1 == last)
1435263363Semaste                        return first;
1436263363Semaste                    if (!first_expr)
1437263363Semaste                    {
1438269024Semaste                        if (db.names.empty())
1439269024Semaste                            return first;
1440263363Semaste                        auto tmp = db.names.back().move_full();
1441263363Semaste                        db.names.pop_back();
1442263363Semaste                        if (!tmp.empty())
1443263363Semaste                        {
1444269024Semaste                            if (db.names.empty())
1445269024Semaste                                return first;
1446263363Semaste                            db.names.back().first.append(", ");
1447263363Semaste                            db.names.back().first.append(tmp);
1448263363Semaste                            first_expr = false;
1449263363Semaste                        }
1450263363Semaste                    }
1451263363Semaste                    t = t1;
1452263363Semaste                }
1453263363Semaste            }
1454263363Semaste            if (*t != 'E')
1455263363Semaste                return first;
1456263363Semaste            typename C::String init_list;
1457263363Semaste            if (has_init)
1458263363Semaste            {
1459269024Semaste                if (db.names.empty())
1460269024Semaste                    return first;
1461263363Semaste                init_list = db.names.back().move_full();
1462263363Semaste                db.names.pop_back();
1463263363Semaste            }
1464269024Semaste            if (db.names.empty())
1465269024Semaste                return first;
1466263363Semaste            auto type = db.names.back().move_full();
1467263363Semaste            db.names.pop_back();
1468263363Semaste            typename C::String expr_list;
1469263363Semaste            if (has_expr_list)
1470263363Semaste            {
1471269024Semaste                if (db.names.empty())
1472269024Semaste                    return first;
1473263363Semaste                expr_list = db.names.back().move_full();
1474263363Semaste                db.names.pop_back();
1475263363Semaste            }
1476263363Semaste            typename C::String r;
1477263363Semaste            if (parsed_gs)
1478263363Semaste                r = "::";
1479263363Semaste            if (is_array)
1480263363Semaste                r += "[] ";
1481263363Semaste            else
1482263363Semaste                r += " ";
1483263363Semaste            if (has_expr_list)
1484263363Semaste                r += "(" + expr_list + ") ";
1485263363Semaste            r += type;
1486263363Semaste            if (has_init)
1487263363Semaste                r += " (" + init_list + ")";
1488263363Semaste            db.names.push_back(std::move(r));
1489263363Semaste            first = t+1;
1490263363Semaste        }
1491263363Semaste    }
1492263363Semaste    return first;
1493263363Semaste}
1494263363Semaste
1495263363Semaste// cv <type> <expression>                               # conversion with one argument
1496263363Semaste// cv <type> _ <expression>* E                          # conversion with a different number of arguments
1497263363Semaste
1498263363Semastetemplate <class C>
1499263363Semasteconst char*
1500263363Semasteparse_conversion_expr(const char* first, const char* last, C& db)
1501263363Semaste{
1502263363Semaste    if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
1503263363Semaste    {
1504263363Semaste        bool try_to_parse_template_args = db.try_to_parse_template_args;
1505263363Semaste        db.try_to_parse_template_args = false;
1506263363Semaste        const char* t = parse_type(first+2, last, db);
1507263363Semaste        db.try_to_parse_template_args = try_to_parse_template_args;
1508263363Semaste        if (t != first+2 && t != last)
1509263363Semaste        {
1510263363Semaste            if (*t != '_')
1511263363Semaste            {
1512263363Semaste                const char* t1 = parse_expression(t, last, db);
1513263363Semaste                if (t1 == t)
1514263363Semaste                    return first;
1515263363Semaste                t = t1;
1516263363Semaste            }
1517263363Semaste            else
1518263363Semaste            {
1519263363Semaste                ++t;
1520263363Semaste                if (t == last)
1521263363Semaste                    return first;
1522263363Semaste                if (*t == 'E')
1523263363Semaste                    db.names.emplace_back();
1524263363Semaste                else
1525263363Semaste                {
1526263363Semaste                    bool first_expr = true;
1527263363Semaste                    while (*t != 'E')
1528263363Semaste                    {
1529263363Semaste                        const char* t1 = parse_expression(t, last, db);
1530263363Semaste                        if (t1 == t || t1 == last)
1531263363Semaste                            return first;
1532263363Semaste                        if (!first_expr)
1533263363Semaste                        {
1534269024Semaste                            if (db.names.empty())
1535269024Semaste                                return first;
1536263363Semaste                            auto tmp = db.names.back().move_full();
1537263363Semaste                            db.names.pop_back();
1538263363Semaste                            if (!tmp.empty())
1539263363Semaste                            {
1540269024Semaste                                if (db.names.empty())
1541269024Semaste                                    return first;
1542263363Semaste                                db.names.back().first.append(", ");
1543263363Semaste                                db.names.back().first.append(tmp);
1544263363Semaste                                first_expr = false;
1545263363Semaste                            }
1546263363Semaste                        }
1547263363Semaste                        t = t1;
1548263363Semaste                    }
1549263363Semaste                }
1550263363Semaste                ++t;
1551263363Semaste            }
1552269024Semaste            if (db.names.size() < 2)
1553269024Semaste                return first;
1554263363Semaste            auto tmp = db.names.back().move_full();
1555263363Semaste            db.names.pop_back();
1556263363Semaste            db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
1557263363Semaste            first = t;
1558263363Semaste        }
1559263363Semaste    }
1560263363Semaste    return first;
1561263363Semaste}
1562263363Semaste
1563263363Semaste// pt <expression> <expression>                    # expr->name
1564263363Semaste
1565263363Semastetemplate <class C>
1566263363Semasteconst char*
1567263363Semasteparse_arrow_expr(const char* first, const char* last, C& db)
1568263363Semaste{
1569263363Semaste    if (last - first >= 3 && first[0] == 'p' && first[1] == 't')
1570263363Semaste    {
1571263363Semaste        const char* t = parse_expression(first+2, last, db);
1572263363Semaste        if (t != first+2)
1573263363Semaste        {
1574263363Semaste            const char* t1 = parse_expression(t, last, db);
1575263363Semaste            if (t1 != t)
1576263363Semaste            {
1577269024Semaste                if (db.names.size() < 2)
1578269024Semaste                    return first;
1579263363Semaste                auto tmp = db.names.back().move_full();
1580263363Semaste                db.names.pop_back();
1581263363Semaste                db.names.back().first += "->";
1582263363Semaste                db.names.back().first += tmp;
1583263363Semaste                first = t1;
1584263363Semaste            }
1585263363Semaste        }
1586263363Semaste    }
1587263363Semaste    return first;
1588263363Semaste}
1589263363Semaste
1590263363Semaste//  <ref-qualifier> ::= R                   # & ref-qualifier
1591263363Semaste//  <ref-qualifier> ::= O                   # && ref-qualifier
1592263363Semaste
1593263363Semaste// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
1594263363Semaste
1595263363Semastetemplate <class C>
1596263363Semasteconst char*
1597263363Semasteparse_function_type(const char* first, const char* last, C& db)
1598263363Semaste{
1599263363Semaste    if (first != last && *first == 'F')
1600263363Semaste    {
1601263363Semaste        const char* t = first+1;
1602263363Semaste        if (t != last)
1603263363Semaste        {
1604263363Semaste            bool externC = false;
1605263363Semaste            if (*t == 'Y')
1606263363Semaste            {
1607263363Semaste                externC = true;
1608263363Semaste                if (++t == last)
1609263363Semaste                    return first;
1610263363Semaste            }
1611263363Semaste            const char* t1 = parse_type(t, last, db);
1612263363Semaste            if (t1 != t)
1613263363Semaste            {
1614263363Semaste                t = t1;
1615263363Semaste                typename C::String sig("(");
1616263363Semaste                int ref_qual = 0;
1617263363Semaste                while (true)
1618263363Semaste                {
1619263363Semaste                    if (t == last)
1620263363Semaste                    {
1621263363Semaste                        db.names.pop_back();
1622263363Semaste                        return first;
1623263363Semaste                    }
1624263363Semaste                    if (*t == 'E')
1625263363Semaste                    {
1626263363Semaste                        ++t;
1627263363Semaste                        break;
1628263363Semaste                    }
1629263363Semaste                    if (*t == 'v')
1630263363Semaste                    {
1631263363Semaste                        ++t;
1632263363Semaste                        continue;
1633263363Semaste                    }
1634263363Semaste                    if (*t == 'R' && t+1 != last && t[1] == 'E')
1635263363Semaste                    {
1636263363Semaste                        ref_qual = 1;
1637263363Semaste                        ++t;
1638263363Semaste                        continue;
1639263363Semaste                    }
1640263363Semaste                    if (*t == 'O' && t+1 != last && t[1] == 'E')
1641263363Semaste                    {
1642263363Semaste                        ref_qual = 2;
1643263363Semaste                        ++t;
1644263363Semaste                        continue;
1645263363Semaste                    }
1646263363Semaste                    size_t k0 = db.names.size();
1647263363Semaste                    t1 = parse_type(t, last, db);
1648263363Semaste                    size_t k1 = db.names.size();
1649263363Semaste                    if (t1 == t || t1 == last)
1650263363Semaste                        return first;
1651263363Semaste                    for (size_t k = k0; k < k1; ++k)
1652263363Semaste                    {
1653263363Semaste                        if (sig.size() > 1)
1654263363Semaste                            sig += ", ";
1655263363Semaste                        sig += db.names[k].move_full();
1656263363Semaste                    }
1657263363Semaste                    for (size_t k = k0; k < k1; ++k)
1658263363Semaste                        db.names.pop_back();
1659263363Semaste                    t = t1;
1660263363Semaste                }
1661263363Semaste                sig += ")";
1662263363Semaste                switch (ref_qual)
1663263363Semaste                {
1664263363Semaste                case 1:
1665263363Semaste                    sig += " &";
1666263363Semaste                    break;
1667263363Semaste                case 2:
1668263363Semaste                    sig += " &&";
1669263363Semaste                    break;
1670263363Semaste                }
1671269024Semaste                if (db.names.empty())
1672269024Semaste                    return first;
1673263363Semaste                db.names.back().first += " ";
1674263363Semaste                db.names.back().second.insert(0, sig);
1675263363Semaste                first = t;
1676263363Semaste            }
1677263363Semaste        }
1678263363Semaste    }
1679263363Semaste    return first;
1680263363Semaste}
1681263363Semaste
1682263363Semaste// <pointer-to-member-type> ::= M <class type> <member type>
1683263363Semaste
1684263363Semastetemplate <class C>
1685263363Semasteconst char*
1686263363Semasteparse_pointer_to_member_type(const char* first, const char* last, C& db)
1687263363Semaste{
1688263363Semaste    if (first != last && *first == 'M')
1689263363Semaste    {
1690263363Semaste        const char* t = parse_type(first+1, last, db);
1691263363Semaste        if (t != first+1)
1692263363Semaste        {
1693263363Semaste            const char* t2 = parse_type(t, last, db);
1694263363Semaste            if (t2 != t)
1695263363Semaste            {
1696269024Semaste                if (db.names.size() < 2)
1697269024Semaste                    return first;
1698263363Semaste                auto func = std::move(db.names.back());
1699263363Semaste                db.names.pop_back();
1700263363Semaste                auto class_type = std::move(db.names.back());
1701263363Semaste                if (func.second.front() == '(')
1702263363Semaste                {
1703263363Semaste                    db.names.back().first = std::move(func.first) + "(" + class_type.move_full() + "::*";
1704263363Semaste                    db.names.back().second = ")" + std::move(func.second);
1705263363Semaste                }
1706263363Semaste                else
1707263363Semaste                {
1708263363Semaste                    db.names.back().first = std::move(func.first) + " " + class_type.move_full() + "::*";
1709263363Semaste                    db.names.back().second = std::move(func.second);
1710263363Semaste                }
1711263363Semaste                first = t2;
1712263363Semaste            }
1713263363Semaste        }
1714263363Semaste    }
1715263363Semaste    return first;
1716263363Semaste}
1717263363Semaste
1718263363Semaste// <array-type> ::= A <positive dimension number> _ <element type>
1719263363Semaste//              ::= A [<dimension expression>] _ <element type>
1720263363Semaste
1721263363Semastetemplate <class C>
1722263363Semasteconst char*
1723263363Semasteparse_array_type(const char* first, const char* last, C& db)
1724263363Semaste{
1725263363Semaste    if (first != last && *first == 'A' && first+1 != last)
1726263363Semaste    {
1727263363Semaste        if (first[1] == '_')
1728263363Semaste        {
1729263363Semaste            const char* t = parse_type(first+2, last, db);
1730263363Semaste            if (t != first+2)
1731263363Semaste            {
1732269024Semaste                if (db.names.empty())
1733269024Semaste                    return first;
1734263363Semaste                if (db.names.back().second.substr(0, 2) == " [")
1735263363Semaste                    db.names.back().second.erase(0, 1);
1736263363Semaste                db.names.back().second.insert(0, " []");
1737263363Semaste                first = t;
1738263363Semaste            }
1739263363Semaste        }
1740263363Semaste        else if ('1' <= first[1] && first[1] <= '9')
1741263363Semaste        {
1742263363Semaste            const char* t = parse_number(first+1, last);
1743263363Semaste            if (t != last && *t == '_')
1744263363Semaste            {
1745263363Semaste                const char* t2 = parse_type(t+1, last, db);
1746263363Semaste                if (t2 != t+1)
1747263363Semaste                {
1748269024Semaste                    if (db.names.empty())
1749269024Semaste                        return first;
1750263363Semaste                    if (db.names.back().second.substr(0, 2) == " [")
1751263363Semaste                        db.names.back().second.erase(0, 1);
1752263363Semaste                    db.names.back().second.insert(0, " [" + typename C::String(first+1, t) + "]");
1753263363Semaste                    first = t2;
1754263363Semaste                }
1755263363Semaste            }
1756263363Semaste        }
1757263363Semaste        else
1758263363Semaste        {
1759263363Semaste            const char* t = parse_expression(first+1, last, db);
1760263363Semaste            if (t != first+1 && t != last && *t == '_')
1761263363Semaste            {
1762263363Semaste                const char* t2 = parse_type(++t, last, db);
1763263363Semaste                if (t2 != t)
1764263363Semaste                {
1765269024Semaste                    if (db.names.size() < 2)
1766269024Semaste                        return first;
1767263363Semaste                    auto type = std::move(db.names.back());
1768263363Semaste                    db.names.pop_back();
1769263363Semaste                    auto expr = std::move(db.names.back());
1770263363Semaste                    db.names.back().first = std::move(type.first);
1771263363Semaste                    if (type.second.substr(0, 2) == " [")
1772263363Semaste                        type.second.erase(0, 1);
1773263363Semaste                    db.names.back().second = " [" + expr.move_full() + "]" + std::move(type.second);
1774263363Semaste                    first = t2;
1775263363Semaste                }
1776263363Semaste            }
1777263363Semaste        }
1778263363Semaste    }
1779263363Semaste    return first;
1780263363Semaste}
1781263363Semaste
1782263363Semaste// <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
1783263363Semaste//             ::= DT <expression> E  # decltype of an expression (C++0x)
1784263363Semaste
1785263363Semastetemplate <class C>
1786263363Semasteconst char*
1787263363Semasteparse_decltype(const char* first, const char* last, C& db)
1788263363Semaste{
1789263363Semaste    if (last - first >= 4 && first[0] == 'D')
1790263363Semaste    {
1791263363Semaste        switch (first[1])
1792263363Semaste        {
1793263363Semaste        case 't':
1794263363Semaste        case 'T':
1795263363Semaste            {
1796263363Semaste                const char* t = parse_expression(first+2, last, db);
1797263363Semaste                if (t != first+2 && t != last && *t == 'E')
1798263363Semaste                {
1799269024Semaste                    if (db.names.empty())
1800269024Semaste                        return first;
1801263363Semaste                    db.names.back() = "decltype(" + db.names.back().move_full() + ")";
1802263363Semaste                    first = t+1;
1803263363Semaste                }
1804263363Semaste            }
1805263363Semaste            break;
1806263363Semaste        }
1807263363Semaste    }
1808263363Semaste    return first;
1809263363Semaste}
1810263363Semaste
1811263363Semaste// extension:
1812263363Semaste// <vector-type>           ::= Dv <positive dimension number> _
1813263363Semaste//                                    <extended element type>
1814263363Semaste//                         ::= Dv [<dimension expression>] _ <element type>
1815263363Semaste// <extended element type> ::= <element type>
1816263363Semaste//                         ::= p # AltiVec vector pixel
1817263363Semaste
1818263363Semastetemplate <class C>
1819263363Semasteconst char*
1820263363Semasteparse_vector_type(const char* first, const char* last, C& db)
1821263363Semaste{
1822263363Semaste    if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
1823263363Semaste    {
1824263363Semaste        if ('1' <= first[2] && first[2] <= '9')
1825263363Semaste        {
1826263363Semaste            const char* t = parse_number(first+2, last);
1827263363Semaste            if (t == last || *t != '_')
1828263363Semaste                return first;
1829263363Semaste            const char* num = first + 2;
1830263363Semaste            size_t sz = static_cast<size_t>(t - num);
1831263363Semaste            if (++t != last)
1832263363Semaste            {
1833263363Semaste                if (*t != 'p')
1834263363Semaste                {
1835263363Semaste                    const char* t1 = parse_type(t, last, db);
1836263363Semaste                    if (t1 != t)
1837263363Semaste                    {
1838269024Semaste                        if (db.names.empty())
1839269024Semaste                            return first;
1840263363Semaste                        db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
1841263363Semaste                        first = t1;
1842263363Semaste                    }
1843263363Semaste                }
1844263363Semaste                else
1845263363Semaste                {
1846263363Semaste                    ++t;
1847263363Semaste                    db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]");
1848263363Semaste                    first = t;
1849263363Semaste                }
1850263363Semaste            }
1851263363Semaste        }
1852263363Semaste        else
1853263363Semaste        {
1854263363Semaste            typename C::String num;
1855263363Semaste            const char* t1 = first+2;
1856263363Semaste            if (*t1 != '_')
1857263363Semaste            {
1858263363Semaste                const char* t = parse_expression(t1, last, db);
1859263363Semaste                if (t != t1)
1860263363Semaste                {
1861269024Semaste                    if (db.names.empty())
1862269024Semaste                        return first;
1863263363Semaste                    num = db.names.back().move_full();
1864263363Semaste                    db.names.pop_back();
1865263363Semaste                    t1 = t;
1866263363Semaste                }
1867263363Semaste            }
1868263363Semaste            if (t1 != last && *t1 == '_' && ++t1 != last)
1869263363Semaste            {
1870263363Semaste                const char* t = parse_type(t1, last, db);
1871263363Semaste                if (t != t1)
1872263363Semaste                {
1873269024Semaste                    if (db.names.empty())
1874269024Semaste                        return first;
1875263363Semaste                    db.names.back().first += " vector[" + num + "]";
1876263363Semaste                    first = t;
1877263363Semaste                }
1878263363Semaste            }
1879263363Semaste        }
1880263363Semaste    }
1881263363Semaste    return first;
1882263363Semaste}
1883263363Semaste
1884263363Semaste// <type> ::= <builtin-type>
1885263363Semaste//        ::= <function-type>
1886263363Semaste//        ::= <class-enum-type>
1887263363Semaste//        ::= <array-type>
1888263363Semaste//        ::= <pointer-to-member-type>
1889263363Semaste//        ::= <template-param>
1890263363Semaste//        ::= <template-template-param> <template-args>
1891263363Semaste//        ::= <decltype>
1892263363Semaste//        ::= <substitution>
1893263363Semaste//        ::= <CV-qualifiers> <type>
1894263363Semaste//        ::= P <type>        # pointer-to
1895263363Semaste//        ::= R <type>        # reference-to
1896263363Semaste//        ::= O <type>        # rvalue reference-to (C++0x)
1897263363Semaste//        ::= C <type>        # complex pair (C 2000)
1898263363Semaste//        ::= G <type>        # imaginary (C 2000)
1899263363Semaste//        ::= Dp <type>       # pack expansion (C++0x)
1900263363Semaste//        ::= U <source-name> <type>  # vendor extended type qualifier
1901263363Semaste// extension := U <objc-name> <objc-type>  # objc-type<identifier>
1902263363Semaste// extension := <vector-type> # <vector-type> starts with Dv
1903263363Semaste
1904263363Semaste// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
1905263363Semaste// <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
1906263363Semaste
1907263363Semastetemplate <class C>
1908263363Semasteconst char*
1909263363Semasteparse_type(const char* first, const char* last, C& db)
1910263363Semaste{
1911263363Semaste    if (first != last)
1912263363Semaste    {
1913263363Semaste        switch (*first)
1914263363Semaste        {
1915263363Semaste            case 'r':
1916263363Semaste            case 'V':
1917263363Semaste            case 'K':
1918263363Semaste              {
1919263363Semaste                unsigned cv = 0;
1920263363Semaste                const char* t = parse_cv_qualifiers(first, last, cv);
1921263363Semaste                if (t != first)
1922263363Semaste                {
1923263363Semaste                    bool is_function = *t == 'F';
1924263363Semaste                    size_t k0 = db.names.size();
1925263363Semaste                    const char* t1 = parse_type(t, last, db);
1926263363Semaste                    size_t k1 = db.names.size();
1927263363Semaste                    if (t1 != t)
1928263363Semaste                    {
1929263363Semaste                        if (is_function)
1930263363Semaste                            db.subs.pop_back();
1931263363Semaste                        db.subs.emplace_back(db.names.get_allocator());
1932263363Semaste                        for (size_t k = k0; k < k1; ++k)
1933263363Semaste                        {
1934263363Semaste                            if (is_function)
1935263363Semaste                            {
1936263363Semaste                                size_t p = db.names[k].second.size();
1937263363Semaste                                if (db.names[k].second[p-2] == '&')
1938263363Semaste                                    p -= 3;
1939263363Semaste                                else if (db.names[k].second.back() == '&')
1940263363Semaste                                    p -= 2;
1941263363Semaste                                if (cv & 1)
1942263363Semaste                                {
1943263363Semaste                                    db.names[k].second.insert(p, " const");
1944263363Semaste                                    p += 6;
1945263363Semaste                                }
1946263363Semaste                                if (cv & 2)
1947263363Semaste                                {
1948263363Semaste                                    db.names[k].second.insert(p, " volatile");
1949263363Semaste                                    p += 9;
1950263363Semaste                                }
1951263363Semaste                                if (cv & 4)
1952263363Semaste                                    db.names[k].second.insert(p, " restrict");
1953263363Semaste                            }
1954263363Semaste                            else
1955263363Semaste                            {
1956263363Semaste                                if (cv & 1)
1957263363Semaste                                    db.names[k].first.append(" const");
1958263363Semaste                                if (cv & 2)
1959263363Semaste                                    db.names[k].first.append(" volatile");
1960263363Semaste                                if (cv & 4)
1961263363Semaste                                    db.names[k].first.append(" restrict");
1962263363Semaste                            }
1963263363Semaste                            db.subs.back().push_back(db.names[k]);
1964263363Semaste                        }
1965263363Semaste                        first = t1;
1966263363Semaste                    }
1967263363Semaste                }
1968263363Semaste              }
1969263363Semaste                break;
1970263363Semaste            default:
1971263363Semaste              {
1972263363Semaste                const char* t = parse_builtin_type(first, last, db);
1973263363Semaste                if (t != first)
1974263363Semaste                {
1975263363Semaste                    first = t;
1976263363Semaste                }
1977263363Semaste                else
1978263363Semaste                {
1979263363Semaste                    switch (*first)
1980263363Semaste                    {
1981263363Semaste                    case 'A':
1982263363Semaste                        t = parse_array_type(first, last, db);
1983263363Semaste                        if (t != first)
1984263363Semaste                        {
1985269024Semaste                            if (db.names.empty())
1986269024Semaste                                return first;
1987263363Semaste                            first = t;
1988263363Semaste                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1989263363Semaste                        }
1990263363Semaste                        break;
1991263363Semaste                    case 'C':
1992263363Semaste                        t = parse_type(first+1, last, db);
1993263363Semaste                        if (t != first+1)
1994263363Semaste                        {
1995269024Semaste                            if (db.names.empty())
1996269024Semaste                                return first;
1997263363Semaste                            db.names.back().first.append(" complex");
1998263363Semaste                            first = t;
1999263363Semaste                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2000263363Semaste                        }
2001263363Semaste                        break;
2002263363Semaste                    case 'F':
2003263363Semaste                        t = parse_function_type(first, last, db);
2004263363Semaste                        if (t != first)
2005263363Semaste                        {
2006269024Semaste                            if (db.names.empty())
2007269024Semaste                                return first;
2008263363Semaste                            first = t;
2009263363Semaste                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2010263363Semaste                        }
2011263363Semaste                        break;
2012263363Semaste                    case 'G':
2013263363Semaste                        t = parse_type(first+1, last, db);
2014263363Semaste                        if (t != first+1)
2015263363Semaste                        {
2016269024Semaste                            if (db.names.empty())
2017269024Semaste                                return first;
2018263363Semaste                            db.names.back().first.append(" imaginary");
2019263363Semaste                            first = t;
2020263363Semaste                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2021263363Semaste                        }
2022263363Semaste                        break;
2023263363Semaste                    case 'M':
2024263363Semaste                        t = parse_pointer_to_member_type(first, last, db);
2025263363Semaste                        if (t != first)
2026263363Semaste                        {
2027269024Semaste                            if (db.names.empty())
2028269024Semaste                                return first;
2029263363Semaste                            first = t;
2030263363Semaste                            db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2031263363Semaste                        }
2032263363Semaste                        break;
2033263363Semaste                    case 'O':
2034263363Semaste                      {
2035263363Semaste                        size_t k0 = db.names.size();
2036263363Semaste                        t = parse_type(first+1, last, db);
2037263363Semaste                        size_t k1 = db.names.size();
2038263363Semaste                        if (t != first+1)
2039263363Semaste                        {
2040263363Semaste                            db.subs.emplace_back(db.names.get_allocator());
2041263363Semaste                            for (size_t k = k0; k < k1; ++k)
2042263363Semaste                            {
2043263363Semaste                                if (db.names[k].second.substr(0, 2) == " [")
2044263363Semaste                                {
2045263363Semaste                                    db.names[k].first += " (";
2046263363Semaste                                    db.names[k].second.insert(0, ")");
2047263363Semaste                                }
2048263363Semaste                                else if (db.names[k].second.front() == '(')
2049263363Semaste                                {
2050263363Semaste                                    db.names[k].first += "(";
2051263363Semaste                                    db.names[k].second.insert(0, ")");
2052263363Semaste                                }
2053263363Semaste                                db.names[k].first.append("&&");
2054263363Semaste                                db.subs.back().push_back(db.names[k]);
2055263363Semaste                            }
2056263363Semaste                            first = t;
2057263363Semaste                        }
2058263363Semaste                        break;
2059263363Semaste                      }
2060263363Semaste                    case 'P':
2061263363Semaste                      {
2062263363Semaste                        size_t k0 = db.names.size();
2063263363Semaste                        t = parse_type(first+1, last, db);
2064263363Semaste                        size_t k1 = db.names.size();
2065263363Semaste                        if (t != first+1)
2066263363Semaste                        {
2067263363Semaste                            db.subs.emplace_back(db.names.get_allocator());
2068263363Semaste                            for (size_t k = k0; k < k1; ++k)
2069263363Semaste                            {
2070263363Semaste                                if (db.names[k].second.substr(0, 2) == " [")
2071263363Semaste                                {
2072263363Semaste                                    db.names[k].first += " (";
2073263363Semaste                                    db.names[k].second.insert(0, ")");
2074263363Semaste                                }
2075263363Semaste                                else if (db.names[k].second.front() == '(')
2076263363Semaste                                {
2077263363Semaste                                    db.names[k].first += "(";
2078263363Semaste                                    db.names[k].second.insert(0, ")");
2079263363Semaste                                }
2080263363Semaste                                if (first[1] != 'U' || db.names[k].first.substr(0, 12) != "objc_object<")
2081263363Semaste                                {
2082263363Semaste                                    db.names[k].first.append("*");
2083263363Semaste                                }
2084263363Semaste                                else
2085263363Semaste                                {
2086263363Semaste                                    db.names[k].first.replace(0, 11, "id");
2087263363Semaste                                }
2088263363Semaste                                db.subs.back().push_back(db.names[k]);
2089263363Semaste                            }
2090263363Semaste                            first = t;
2091263363Semaste                        }
2092263363Semaste                        break;
2093263363Semaste                      }
2094263363Semaste                    case 'R':
2095263363Semaste                      {
2096263363Semaste                        size_t k0 = db.names.size();
2097263363Semaste                        t = parse_type(first+1, last, db);
2098263363Semaste                        size_t k1 = db.names.size();
2099263363Semaste                        if (t != first+1)
2100263363Semaste                        {
2101263363Semaste                            db.subs.emplace_back(db.names.get_allocator());
2102263363Semaste                            for (size_t k = k0; k < k1; ++k)
2103263363Semaste                            {
2104263363Semaste                                if (db.names[k].second.substr(0, 2) == " [")
2105263363Semaste                                {
2106263363Semaste                                    db.names[k].first += " (";
2107263363Semaste                                    db.names[k].second.insert(0, ")");
2108263363Semaste                                }
2109263363Semaste                                else if (db.names[k].second.front() == '(')
2110263363Semaste                                {
2111263363Semaste                                    db.names[k].first += "(";
2112263363Semaste                                    db.names[k].second.insert(0, ")");
2113263363Semaste                                }
2114263363Semaste                                db.names[k].first.append("&");
2115263363Semaste                                db.subs.back().push_back(db.names[k]);
2116263363Semaste                            }
2117263363Semaste                            first = t;
2118263363Semaste                        }
2119263363Semaste                        break;
2120263363Semaste                      }
2121263363Semaste                    case 'T':
2122263363Semaste                      {
2123263363Semaste                        size_t k0 = db.names.size();
2124263363Semaste                        t = parse_template_param(first, last, db);
2125263363Semaste                        size_t k1 = db.names.size();
2126263363Semaste                        if (t != first)
2127263363Semaste                        {
2128263363Semaste                            db.subs.emplace_back(db.names.get_allocator());
2129263363Semaste                            for (size_t k = k0; k < k1; ++k)
2130263363Semaste                                db.subs.back().push_back(db.names[k]);
2131263363Semaste                            if (db.try_to_parse_template_args && k1 == k0+1)
2132263363Semaste                            {
2133263363Semaste                                const char* t1 = parse_template_args(t, last, db);
2134263363Semaste                                if (t1 != t)
2135263363Semaste                                {
2136263363Semaste                                    auto args = db.names.back().move_full();
2137263363Semaste                                    db.names.pop_back();
2138263363Semaste                                    db.names.back().first += std::move(args);
2139263363Semaste                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2140263363Semaste                                    t = t1;
2141263363Semaste                                }
2142263363Semaste                            }
2143263363Semaste                            first = t;
2144263363Semaste                        }
2145263363Semaste                        break;
2146263363Semaste                      }
2147263363Semaste                    case 'U':
2148263363Semaste                        if (first+1 != last)
2149263363Semaste                        {
2150263363Semaste                            t = parse_source_name(first+1, last, db);
2151263363Semaste                            if (t != first+1)
2152263363Semaste                            {
2153263363Semaste                                const char* t2 = parse_type(t, last, db);
2154263363Semaste                                if (t2 != t)
2155263363Semaste                                {
2156269024Semaste                                    if (db.names.size() < 2)
2157269024Semaste                                        return first;
2158263363Semaste                                    auto type = db.names.back().move_full();
2159263363Semaste                                    db.names.pop_back();
2160263363Semaste                                    if (db.names.back().first.substr(0, 9) != "objcproto")
2161263363Semaste                                    {
2162263363Semaste                                        db.names.back() = type + " " + db.names.back().move_full();
2163263363Semaste                                    }
2164263363Semaste                                    else
2165263363Semaste                                    {
2166263363Semaste                                        auto proto = db.names.back().move_full();
2167263363Semaste                                        db.names.pop_back();
2168263363Semaste                                        t = parse_source_name(proto.data() + 9, proto.data() + proto.size(), db);
2169263363Semaste                                        if (t != proto.data() + 9)
2170263363Semaste                                        {
2171263363Semaste                                            db.names.back() = type + "<" + db.names.back().move_full() + ">";
2172263363Semaste                                        }
2173263363Semaste                                        else
2174263363Semaste                                        {
2175263363Semaste                                            db.names.push_back(type + " " + proto);
2176263363Semaste                                        }
2177263363Semaste                                    }
2178263363Semaste                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2179263363Semaste                                    first = t2;
2180263363Semaste                                }
2181263363Semaste                            }
2182263363Semaste                        }
2183263363Semaste                        break;
2184263363Semaste                    case 'S':
2185263363Semaste                        if (first+1 != last && first[1] == 't')
2186263363Semaste                        {
2187263363Semaste                            t = parse_name(first, last, db);
2188263363Semaste                            if (t != first)
2189263363Semaste                            {
2190269024Semaste                                if (db.names.empty())
2191269024Semaste                                    return first;
2192263363Semaste                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2193263363Semaste                                first = t;
2194263363Semaste                            }
2195263363Semaste                        }
2196263363Semaste                        else
2197263363Semaste                        {
2198263363Semaste                            t = parse_substitution(first, last, db);
2199263363Semaste                            if (t != first)
2200263363Semaste                            {
2201263363Semaste                                first = t;
2202263363Semaste                                // Parsed a substitution.  If the substitution is a
2203263363Semaste                                //  <template-param> it might be followed by <template-args>.
2204263363Semaste                                t = parse_template_args(first, last, db);
2205263363Semaste                                if (t != first)
2206263363Semaste                                {
2207269024Semaste                                    if (db.names.size() < 2)
2208269024Semaste                                        return first;
2209263363Semaste                                    auto template_args = db.names.back().move_full();
2210263363Semaste                                    db.names.pop_back();
2211263363Semaste                                    db.names.back().first += template_args;
2212263363Semaste                                    // Need to create substitution for <template-template-param> <template-args>
2213263363Semaste                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2214263363Semaste                                    first = t;
2215263363Semaste                                }
2216263363Semaste                            }
2217263363Semaste                        }
2218263363Semaste                        break;
2219263363Semaste                    case 'D':
2220263363Semaste                        if (first+1 != last)
2221263363Semaste                        {
2222263363Semaste                            switch (first[1])
2223263363Semaste                            {
2224263363Semaste                            case 'p':
2225263363Semaste                              {
2226263363Semaste                                size_t k0 = db.names.size();
2227263363Semaste                                t = parse_type(first+2, last, db);
2228263363Semaste                                size_t k1 = db.names.size();
2229263363Semaste                                if (t != first+2)
2230263363Semaste                                {
2231263363Semaste                                    db.subs.emplace_back(db.names.get_allocator());
2232263363Semaste                                    for (size_t k = k0; k < k1; ++k)
2233263363Semaste                                        db.subs.back().push_back(db.names[k]);
2234263363Semaste                                    first = t;
2235263363Semaste                                    return first;
2236263363Semaste                                }
2237263363Semaste                                break;
2238263363Semaste                              }
2239263363Semaste                            case 't':
2240263363Semaste                            case 'T':
2241263363Semaste                                t = parse_decltype(first, last, db);
2242263363Semaste                                if (t != first)
2243263363Semaste                                {
2244269024Semaste                                    if (db.names.empty())
2245269024Semaste                                        return first;
2246263363Semaste                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2247263363Semaste                                    first = t;
2248263363Semaste                                    return first;
2249263363Semaste                                }
2250263363Semaste                                break;
2251263363Semaste                            case 'v':
2252263363Semaste                                t = parse_vector_type(first, last, db);
2253263363Semaste                                if (t != first)
2254263363Semaste                                {
2255269024Semaste                                    if (db.names.empty())
2256269024Semaste                                        return first;
2257263363Semaste                                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2258263363Semaste                                    first = t;
2259263363Semaste                                    return first;
2260263363Semaste                                }
2261263363Semaste                                break;
2262263363Semaste                            }
2263263363Semaste                        }
2264263363Semaste                        // drop through
2265263363Semaste                    default:
2266263363Semaste                        // must check for builtin-types before class-enum-types to avoid
2267263363Semaste                        // ambiguities with operator-names
2268263363Semaste                        t = parse_builtin_type(first, last, db);
2269263363Semaste                        if (t != first)
2270263363Semaste                        {
2271263363Semaste                            first = t;
2272263363Semaste                        }
2273263363Semaste                        else
2274263363Semaste                        {
2275263363Semaste                            t = parse_name(first, last, db);
2276263363Semaste                            if (t != first)
2277263363Semaste                            {
2278269024Semaste                                if (db.names.empty())
2279269024Semaste                                    return first;
2280263363Semaste                                db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2281263363Semaste                                first = t;
2282263363Semaste                            }
2283263363Semaste                        }
2284263363Semaste                        break;
2285263363Semaste                    }
2286263363Semaste              }
2287263363Semaste                break;
2288263363Semaste            }
2289263363Semaste        }
2290263363Semaste    }
2291263363Semaste    return first;
2292263363Semaste}
2293263363Semaste
2294263363Semaste//   <operator-name>
2295263363Semaste//                   ::= aa    # &&
2296263363Semaste//                   ::= ad    # & (unary)
2297263363Semaste//                   ::= an    # &
2298263363Semaste//                   ::= aN    # &=
2299263363Semaste//                   ::= aS    # =
2300263363Semaste//                   ::= cl    # ()
2301263363Semaste//                   ::= cm    # ,
2302263363Semaste//                   ::= co    # ~
2303263363Semaste//                   ::= cv <type>    # (cast)
2304263363Semaste//                   ::= da    # delete[]
2305263363Semaste//                   ::= de    # * (unary)
2306263363Semaste//                   ::= dl    # delete
2307263363Semaste//                   ::= dv    # /
2308263363Semaste//                   ::= dV    # /=
2309263363Semaste//                   ::= eo    # ^
2310263363Semaste//                   ::= eO    # ^=
2311263363Semaste//                   ::= eq    # ==
2312263363Semaste//                   ::= ge    # >=
2313263363Semaste//                   ::= gt    # >
2314263363Semaste//                   ::= ix    # []
2315263363Semaste//                   ::= le    # <=
2316269024Semaste//                   ::= li <source-name>  # operator ""
2317263363Semaste//                   ::= ls    # <<
2318263363Semaste//                   ::= lS    # <<=
2319263363Semaste//                   ::= lt    # <
2320263363Semaste//                   ::= mi    # -
2321263363Semaste//                   ::= mI    # -=
2322263363Semaste//                   ::= ml    # *
2323263363Semaste//                   ::= mL    # *=
2324263363Semaste//                   ::= mm    # -- (postfix in <expression> context)
2325263363Semaste//                   ::= na    # new[]
2326263363Semaste//                   ::= ne    # !=
2327263363Semaste//                   ::= ng    # - (unary)
2328263363Semaste//                   ::= nt    # !
2329263363Semaste//                   ::= nw    # new
2330263363Semaste//                   ::= oo    # ||
2331263363Semaste//                   ::= or    # |
2332263363Semaste//                   ::= oR    # |=
2333263363Semaste//                   ::= pm    # ->*
2334263363Semaste//                   ::= pl    # +
2335263363Semaste//                   ::= pL    # +=
2336263363Semaste//                   ::= pp    # ++ (postfix in <expression> context)
2337263363Semaste//                   ::= ps    # + (unary)
2338263363Semaste//                   ::= pt    # ->
2339263363Semaste//                   ::= qu    # ?
2340263363Semaste//                   ::= rm    # %
2341263363Semaste//                   ::= rM    # %=
2342263363Semaste//                   ::= rs    # >>
2343263363Semaste//                   ::= rS    # >>=
2344263363Semaste//                   ::= v <digit> <source-name>        # vendor extended operator
2345263363Semaste
2346263363Semastetemplate <class C>
2347263363Semasteconst char*
2348263363Semasteparse_operator_name(const char* first, const char* last, C& db)
2349263363Semaste{
2350263363Semaste    if (last - first >= 2)
2351263363Semaste    {
2352263363Semaste        switch (first[0])
2353263363Semaste        {
2354263363Semaste        case 'a':
2355263363Semaste            switch (first[1])
2356263363Semaste            {
2357263363Semaste            case 'a':
2358263363Semaste                db.names.push_back("operator&&");
2359263363Semaste                first += 2;
2360263363Semaste                break;
2361263363Semaste            case 'd':
2362263363Semaste            case 'n':
2363263363Semaste                db.names.push_back("operator&");
2364263363Semaste                first += 2;
2365263363Semaste                break;
2366263363Semaste            case 'N':
2367263363Semaste                db.names.push_back("operator&=");
2368263363Semaste                first += 2;
2369263363Semaste                break;
2370263363Semaste            case 'S':
2371263363Semaste                db.names.push_back("operator=");
2372263363Semaste                first += 2;
2373263363Semaste                break;
2374263363Semaste            }
2375263363Semaste            break;
2376263363Semaste        case 'c':
2377263363Semaste            switch (first[1])
2378263363Semaste            {
2379263363Semaste            case 'l':
2380263363Semaste                db.names.push_back("operator()");
2381263363Semaste                first += 2;
2382263363Semaste                break;
2383263363Semaste            case 'm':
2384263363Semaste                db.names.push_back("operator,");
2385263363Semaste                first += 2;
2386263363Semaste                break;
2387263363Semaste            case 'o':
2388263363Semaste                db.names.push_back("operator~");
2389263363Semaste                first += 2;
2390263363Semaste                break;
2391263363Semaste            case 'v':
2392263363Semaste                {
2393263363Semaste                    bool try_to_parse_template_args = db.try_to_parse_template_args;
2394263363Semaste                    db.try_to_parse_template_args = false;
2395263363Semaste                    const char* t = parse_type(first+2, last, db);
2396263363Semaste                    db.try_to_parse_template_args = try_to_parse_template_args;
2397263363Semaste                    if (t != first+2)
2398263363Semaste                    {
2399269024Semaste                        if (db.names.empty())
2400269024Semaste                            return first;
2401263363Semaste                        db.names.back().first.insert(0, "operator ");
2402263363Semaste                        db.parsed_ctor_dtor_cv = true;
2403263363Semaste                        first = t;
2404263363Semaste                    }
2405263363Semaste                }
2406263363Semaste                break;
2407263363Semaste            }
2408263363Semaste            break;
2409263363Semaste        case 'd':
2410263363Semaste            switch (first[1])
2411263363Semaste            {
2412263363Semaste            case 'a':
2413263363Semaste                db.names.push_back("operator delete[]");
2414263363Semaste                first += 2;
2415263363Semaste                break;
2416263363Semaste            case 'e':
2417263363Semaste                db.names.push_back("operator*");
2418263363Semaste                first += 2;
2419263363Semaste                break;
2420263363Semaste            case 'l':
2421263363Semaste                db.names.push_back("operator delete");
2422263363Semaste                first += 2;
2423263363Semaste                break;
2424263363Semaste            case 'v':
2425263363Semaste                db.names.push_back("operator/");
2426263363Semaste                first += 2;
2427263363Semaste                break;
2428263363Semaste            case 'V':
2429263363Semaste                db.names.push_back("operator/=");
2430263363Semaste                first += 2;
2431263363Semaste                break;
2432263363Semaste            }
2433263363Semaste            break;
2434263363Semaste        case 'e':
2435263363Semaste            switch (first[1])
2436263363Semaste            {
2437263363Semaste            case 'o':
2438263363Semaste                db.names.push_back("operator^");
2439263363Semaste                first += 2;
2440263363Semaste                break;
2441263363Semaste            case 'O':
2442263363Semaste                db.names.push_back("operator^=");
2443263363Semaste                first += 2;
2444263363Semaste                break;
2445263363Semaste            case 'q':
2446263363Semaste                db.names.push_back("operator==");
2447263363Semaste                first += 2;
2448263363Semaste                break;
2449263363Semaste            }
2450263363Semaste            break;
2451263363Semaste        case 'g':
2452263363Semaste            switch (first[1])
2453263363Semaste            {
2454263363Semaste            case 'e':
2455263363Semaste                db.names.push_back("operator>=");
2456263363Semaste                first += 2;
2457263363Semaste                break;
2458263363Semaste            case 't':
2459263363Semaste                db.names.push_back("operator>");
2460263363Semaste                first += 2;
2461263363Semaste                break;
2462263363Semaste            }
2463263363Semaste            break;
2464263363Semaste        case 'i':
2465263363Semaste            if (first[1] == 'x')
2466263363Semaste            {
2467263363Semaste                db.names.push_back("operator[]");
2468263363Semaste                first += 2;
2469263363Semaste            }
2470263363Semaste            break;
2471263363Semaste        case 'l':
2472263363Semaste            switch (first[1])
2473263363Semaste            {
2474263363Semaste            case 'e':
2475263363Semaste                db.names.push_back("operator<=");
2476263363Semaste                first += 2;
2477263363Semaste                break;
2478269024Semaste            case 'i':
2479269024Semaste                {
2480269024Semaste                    const char* t = parse_source_name(first+2, last, db);
2481269024Semaste                    if (t != first+2)
2482269024Semaste                    {
2483269024Semaste                        if (db.names.empty())
2484269024Semaste                            return first;
2485269024Semaste                        db.names.back().first.insert(0, "operator\"\" ");
2486269024Semaste                        first = t;
2487269024Semaste                    }
2488269024Semaste                }
2489269024Semaste                break;
2490263363Semaste            case 's':
2491263363Semaste                db.names.push_back("operator<<");
2492263363Semaste                first += 2;
2493263363Semaste                break;
2494263363Semaste            case 'S':
2495263363Semaste                db.names.push_back("operator<<=");
2496263363Semaste                first += 2;
2497263363Semaste                break;
2498263363Semaste            case 't':
2499263363Semaste                db.names.push_back("operator<");
2500263363Semaste                first += 2;
2501263363Semaste                break;
2502263363Semaste            }
2503263363Semaste            break;
2504263363Semaste        case 'm':
2505263363Semaste            switch (first[1])
2506263363Semaste            {
2507263363Semaste            case 'i':
2508263363Semaste                db.names.push_back("operator-");
2509263363Semaste                first += 2;
2510263363Semaste                break;
2511263363Semaste            case 'I':
2512263363Semaste                db.names.push_back("operator-=");
2513263363Semaste                first += 2;
2514263363Semaste                break;
2515263363Semaste            case 'l':
2516263363Semaste                db.names.push_back("operator*");
2517263363Semaste                first += 2;
2518263363Semaste                break;
2519263363Semaste            case 'L':
2520263363Semaste                db.names.push_back("operator*=");
2521263363Semaste                first += 2;
2522263363Semaste                break;
2523263363Semaste            case 'm':
2524263363Semaste                db.names.push_back("operator--");
2525263363Semaste                first += 2;
2526263363Semaste                break;
2527263363Semaste            }
2528263363Semaste            break;
2529263363Semaste        case 'n':
2530263363Semaste            switch (first[1])
2531263363Semaste            {
2532263363Semaste            case 'a':
2533263363Semaste                db.names.push_back("operator new[]");
2534263363Semaste                first += 2;
2535263363Semaste                break;
2536263363Semaste            case 'e':
2537263363Semaste                db.names.push_back("operator!=");
2538263363Semaste                first += 2;
2539263363Semaste                break;
2540263363Semaste            case 'g':
2541263363Semaste                db.names.push_back("operator-");
2542263363Semaste                first += 2;
2543263363Semaste                break;
2544263363Semaste            case 't':
2545263363Semaste                db.names.push_back("operator!");
2546263363Semaste                first += 2;
2547263363Semaste                break;
2548263363Semaste            case 'w':
2549263363Semaste                db.names.push_back("operator new");
2550263363Semaste                first += 2;
2551263363Semaste                break;
2552263363Semaste            }
2553263363Semaste            break;
2554263363Semaste        case 'o':
2555263363Semaste            switch (first[1])
2556263363Semaste            {
2557263363Semaste            case 'o':
2558263363Semaste                db.names.push_back("operator||");
2559263363Semaste                first += 2;
2560263363Semaste                break;
2561263363Semaste            case 'r':
2562263363Semaste                db.names.push_back("operator|");
2563263363Semaste                first += 2;
2564263363Semaste                break;
2565263363Semaste            case 'R':
2566263363Semaste                db.names.push_back("operator|=");
2567263363Semaste                first += 2;
2568263363Semaste                break;
2569263363Semaste            }
2570263363Semaste            break;
2571263363Semaste        case 'p':
2572263363Semaste            switch (first[1])
2573263363Semaste            {
2574263363Semaste            case 'm':
2575263363Semaste                db.names.push_back("operator->*");
2576263363Semaste                first += 2;
2577263363Semaste                break;
2578263363Semaste            case 'l':
2579263363Semaste                db.names.push_back("operator+");
2580263363Semaste                first += 2;
2581263363Semaste                break;
2582263363Semaste            case 'L':
2583263363Semaste                db.names.push_back("operator+=");
2584263363Semaste                first += 2;
2585263363Semaste                break;
2586263363Semaste            case 'p':
2587263363Semaste                db.names.push_back("operator++");
2588263363Semaste                first += 2;
2589263363Semaste                break;
2590263363Semaste            case 's':
2591263363Semaste                db.names.push_back("operator+");
2592263363Semaste                first += 2;
2593263363Semaste                break;
2594263363Semaste            case 't':
2595263363Semaste                db.names.push_back("operator->");
2596263363Semaste                first += 2;
2597263363Semaste                break;
2598263363Semaste            }
2599263363Semaste            break;
2600263363Semaste        case 'q':
2601263363Semaste            if (first[1] == 'u')
2602263363Semaste            {
2603263363Semaste                db.names.push_back("operator?");
2604263363Semaste                first += 2;
2605263363Semaste            }
2606263363Semaste            break;
2607263363Semaste        case 'r':
2608263363Semaste            switch (first[1])
2609263363Semaste            {
2610263363Semaste            case 'm':
2611263363Semaste                db.names.push_back("operator%");
2612263363Semaste                first += 2;
2613263363Semaste                break;
2614263363Semaste            case 'M':
2615263363Semaste                db.names.push_back("operator%=");
2616263363Semaste                first += 2;
2617263363Semaste                break;
2618263363Semaste            case 's':
2619263363Semaste                db.names.push_back("operator>>");
2620263363Semaste                first += 2;
2621263363Semaste                break;
2622263363Semaste            case 'S':
2623263363Semaste                db.names.push_back("operator>>=");
2624263363Semaste                first += 2;
2625263363Semaste                break;
2626263363Semaste            }
2627263363Semaste            break;
2628263363Semaste        case 'v':
2629263363Semaste            if (std::isdigit(first[1]))
2630263363Semaste            {
2631263363Semaste                const char* t = parse_source_name(first+2, last, db);
2632263363Semaste                if (t != first+2)
2633263363Semaste                {
2634269024Semaste                    if (db.names.empty())
2635269024Semaste                        return first;
2636263363Semaste                    db.names.back().first.insert(0, "operator ");
2637263363Semaste                    first = t;
2638263363Semaste                }
2639263363Semaste            }
2640263363Semaste            break;
2641263363Semaste        }
2642263363Semaste    }
2643263363Semaste    return first;
2644263363Semaste}
2645263363Semaste
2646263363Semastetemplate <class C>
2647263363Semasteconst char*
2648263363Semasteparse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)
2649263363Semaste{
2650263363Semaste    const char* t = parse_number(first, last);
2651263363Semaste    if (t != first && t != last && *t == 'E')
2652263363Semaste    {
2653263363Semaste        if (lit.size() > 3)
2654263363Semaste            db.names.push_back("(" + lit + ")");
2655263363Semaste        else
2656263363Semaste            db.names.emplace_back();
2657263363Semaste        if (*first == 'n')
2658263363Semaste        {
2659263363Semaste            db.names.back().first += '-';
2660263363Semaste            ++first;
2661263363Semaste        }
2662263363Semaste        db.names.back().first.append(first, t);
2663263363Semaste        if (lit.size() <= 3)
2664263363Semaste            db.names.back().first += lit;
2665263363Semaste        first = t+1;
2666263363Semaste    }
2667263363Semaste    return first;
2668263363Semaste}
2669263363Semaste
2670263363Semaste// <expr-primary> ::= L <type> <value number> E                          # integer literal
2671263363Semaste//                ::= L <type> <value float> E                           # floating literal
2672263363Semaste//                ::= L <string type> E                                  # string literal
2673263363Semaste//                ::= L <nullptr type> E                                 # nullptr literal (i.e., "LDnE")
2674263363Semaste//                ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)
2675263363Semaste//                ::= L <mangled-name> E                                 # external name
2676263363Semaste
2677263363Semastetemplate <class C>
2678263363Semasteconst char*
2679263363Semasteparse_expr_primary(const char* first, const char* last, C& db)
2680263363Semaste{
2681263363Semaste    if (last - first >= 4 && *first == 'L')
2682263363Semaste    {
2683263363Semaste        switch (first[1])
2684263363Semaste        {
2685263363Semaste        case 'w':
2686263363Semaste            {
2687263363Semaste            const char* t = parse_integer_literal(first+2, last, "wchar_t", db);
2688263363Semaste            if (t != first+2)
2689263363Semaste                first = t;
2690263363Semaste            }
2691263363Semaste            break;
2692263363Semaste        case 'b':
2693263363Semaste            if (first[3] == 'E')
2694263363Semaste            {
2695263363Semaste                switch (first[2])
2696263363Semaste                {
2697263363Semaste                case '0':
2698263363Semaste                    db.names.push_back("false");
2699263363Semaste                    first += 4;
2700263363Semaste                    break;
2701263363Semaste                case '1':
2702263363Semaste                    db.names.push_back("true");
2703263363Semaste                    first += 4;
2704263363Semaste                    break;
2705263363Semaste                }
2706263363Semaste            }
2707263363Semaste            break;
2708263363Semaste        case 'c':
2709263363Semaste            {
2710263363Semaste            const char* t = parse_integer_literal(first+2, last, "char", db);
2711263363Semaste            if (t != first+2)
2712263363Semaste                first = t;
2713263363Semaste            }
2714263363Semaste            break;
2715263363Semaste        case 'a':
2716263363Semaste            {
2717263363Semaste            const char* t = parse_integer_literal(first+2, last, "signed char", db);
2718263363Semaste            if (t != first+2)
2719263363Semaste                first = t;
2720263363Semaste            }
2721263363Semaste            break;
2722263363Semaste        case 'h':
2723263363Semaste            {
2724263363Semaste            const char* t = parse_integer_literal(first+2, last, "unsigned char", db);
2725263363Semaste            if (t != first+2)
2726263363Semaste                first = t;
2727263363Semaste            }
2728263363Semaste            break;
2729263363Semaste        case 's':
2730263363Semaste            {
2731263363Semaste            const char* t = parse_integer_literal(first+2, last, "short", db);
2732263363Semaste            if (t != first+2)
2733263363Semaste                first = t;
2734263363Semaste            }
2735263363Semaste            break;
2736263363Semaste        case 't':
2737263363Semaste            {
2738263363Semaste            const char* t = parse_integer_literal(first+2, last, "unsigned short", db);
2739263363Semaste            if (t != first+2)
2740263363Semaste                first = t;
2741263363Semaste            }
2742263363Semaste            break;
2743263363Semaste        case 'i':
2744263363Semaste            {
2745263363Semaste            const char* t = parse_integer_literal(first+2, last, "", db);
2746263363Semaste            if (t != first+2)
2747263363Semaste                first = t;
2748263363Semaste            }
2749263363Semaste            break;
2750263363Semaste        case 'j':
2751263363Semaste            {
2752263363Semaste            const char* t = parse_integer_literal(first+2, last, "u", db);
2753263363Semaste            if (t != first+2)
2754263363Semaste                first = t;
2755263363Semaste            }
2756263363Semaste            break;
2757263363Semaste        case 'l':
2758263363Semaste            {
2759263363Semaste            const char* t = parse_integer_literal(first+2, last, "l", db);
2760263363Semaste            if (t != first+2)
2761263363Semaste                first = t;
2762263363Semaste            }
2763263363Semaste            break;
2764263363Semaste        case 'm':
2765263363Semaste            {
2766263363Semaste            const char* t = parse_integer_literal(first+2, last, "ul", db);
2767263363Semaste            if (t != first+2)
2768263363Semaste                first = t;
2769263363Semaste            }
2770263363Semaste            break;
2771263363Semaste        case 'x':
2772263363Semaste            {
2773263363Semaste            const char* t = parse_integer_literal(first+2, last, "ll", db);
2774263363Semaste            if (t != first+2)
2775263363Semaste                first = t;
2776263363Semaste            }
2777263363Semaste            break;
2778263363Semaste        case 'y':
2779263363Semaste            {
2780263363Semaste            const char* t = parse_integer_literal(first+2, last, "ull", db);
2781263363Semaste            if (t != first+2)
2782263363Semaste                first = t;
2783263363Semaste            }
2784263363Semaste            break;
2785263363Semaste        case 'n':
2786263363Semaste            {
2787263363Semaste            const char* t = parse_integer_literal(first+2, last, "__int128", db);
2788263363Semaste            if (t != first+2)
2789263363Semaste                first = t;
2790263363Semaste            }
2791263363Semaste            break;
2792263363Semaste        case 'o':
2793263363Semaste            {
2794263363Semaste            const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db);
2795263363Semaste            if (t != first+2)
2796263363Semaste                first = t;
2797263363Semaste            }
2798263363Semaste            break;
2799263363Semaste        case 'f':
2800263363Semaste            {
2801263363Semaste            const char* t = parse_floating_number<float>(first+2, last, db);
2802263363Semaste            if (t != first+2)
2803263363Semaste                first = t;
2804263363Semaste            }
2805263363Semaste            break;
2806263363Semaste        case 'd':
2807263363Semaste            {
2808263363Semaste            const char* t = parse_floating_number<double>(first+2, last, db);
2809263363Semaste            if (t != first+2)
2810263363Semaste                first = t;
2811263363Semaste            }
2812263363Semaste            break;
2813263363Semaste         case 'e':
2814263363Semaste            {
2815263363Semaste            const char* t = parse_floating_number<long double>(first+2, last, db);
2816263363Semaste            if (t != first+2)
2817263363Semaste                first = t;
2818263363Semaste            }
2819263363Semaste            break;
2820263363Semaste        case '_':
2821263363Semaste            if (first[2] == 'Z')
2822263363Semaste            {
2823263363Semaste                const char* t = parse_encoding(first+3, last, db);
2824263363Semaste                if (t != first+3 && t != last && *t == 'E')
2825263363Semaste                    first = t+1;
2826263363Semaste            }
2827263363Semaste            break;
2828263363Semaste        case 'T':
2829263363Semaste            // Invalid mangled name per
2830263363Semaste            //   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2831263363Semaste            break;
2832263363Semaste        default:
2833263363Semaste            {
2834263363Semaste                // might be named type
2835263363Semaste                const char* t = parse_type(first+1, last, db);
2836263363Semaste                if (t != first+1 && t != last)
2837263363Semaste                {
2838263363Semaste                    if (*t != 'E')
2839263363Semaste                    {
2840263363Semaste                        const char* n = t;
2841263363Semaste                        for (; n != last && isdigit(*n); ++n)
2842263363Semaste                            ;
2843263363Semaste                        if (n != t && n != last && *n == 'E')
2844263363Semaste                        {
2845269024Semaste                            if (db.names.empty())
2846269024Semaste                                return first;
2847263363Semaste                            db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n);
2848263363Semaste                            first = n+1;
2849263363Semaste                            break;
2850263363Semaste                        }
2851263363Semaste                    }
2852263363Semaste                    else
2853263363Semaste                    {
2854263363Semaste                        first = t+1;
2855263363Semaste                        break;
2856263363Semaste                    }
2857263363Semaste                }
2858263363Semaste            }
2859263363Semaste        }
2860263363Semaste    }
2861263363Semaste    return first;
2862263363Semaste}
2863263363Semaste
2864263363Semastetemplate <class String>
2865263363SemasteString
2866263363Semastebase_name(String& s)
2867263363Semaste{
2868263363Semaste    if (s.empty())
2869263363Semaste        return s;
2870263363Semaste    if (s == "std::string")
2871263363Semaste    {
2872263363Semaste        s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >";
2873263363Semaste        return "basic_string";
2874263363Semaste    }
2875263363Semaste    if (s == "std::istream")
2876263363Semaste    {
2877263363Semaste        s = "std::basic_istream<char, std::char_traits<char> >";
2878263363Semaste        return "basic_istream";
2879263363Semaste    }
2880263363Semaste    if (s == "std::ostream")
2881263363Semaste    {
2882263363Semaste        s = "std::basic_ostream<char, std::char_traits<char> >";
2883263363Semaste        return "basic_ostream";
2884263363Semaste    }
2885263363Semaste    if (s == "std::iostream")
2886263363Semaste    {
2887263363Semaste        s = "std::basic_iostream<char, std::char_traits<char> >";
2888263363Semaste        return "basic_iostream";
2889263363Semaste    }
2890263363Semaste    const char* const pf = s.data();
2891263363Semaste    const char* pe = pf + s.size();
2892263363Semaste    if (pe[-1] == '>')
2893263363Semaste    {
2894263363Semaste        unsigned c = 1;
2895263363Semaste        while (true)
2896263363Semaste        {
2897263363Semaste            if (--pe == pf)
2898263363Semaste                return String();
2899263363Semaste            if (pe[-1] == '<')
2900263363Semaste            {
2901263363Semaste                if (--c == 0)
2902263363Semaste                {
2903263363Semaste                    --pe;
2904263363Semaste                    break;
2905263363Semaste                }
2906263363Semaste            }
2907263363Semaste            else if (pe[-1] == '>')
2908263363Semaste                ++c;
2909263363Semaste        }
2910263363Semaste    }
2911263363Semaste    const char* p0 = pe - 1;
2912263363Semaste    for (; p0 != pf; --p0)
2913263363Semaste    {
2914263363Semaste        if (*p0 == ':')
2915263363Semaste        {
2916263363Semaste            ++p0;
2917263363Semaste            break;
2918263363Semaste        }
2919263363Semaste    }
2920263363Semaste    return String(p0, pe);
2921263363Semaste}
2922263363Semaste
2923263363Semaste// <ctor-dtor-name> ::= C1    # complete object constructor
2924263363Semaste//                  ::= C2    # base object constructor
2925263363Semaste//                  ::= C3    # complete object allocating constructor
2926263363Semaste//   extension      ::= C5    # ?
2927263363Semaste//                  ::= D0    # deleting destructor
2928263363Semaste//                  ::= D1    # complete object destructor
2929263363Semaste//                  ::= D2    # base object destructor
2930263363Semaste//   extension      ::= D5    # ?
2931263363Semaste
2932263363Semastetemplate <class C>
2933263363Semasteconst char*
2934263363Semasteparse_ctor_dtor_name(const char* first, const char* last, C& db)
2935263363Semaste{
2936263363Semaste    if (last-first >= 2 && !db.names.empty())
2937263363Semaste    {
2938263363Semaste        switch (first[0])
2939263363Semaste        {
2940263363Semaste        case 'C':
2941263363Semaste            switch (first[1])
2942263363Semaste            {
2943263363Semaste            case '1':
2944263363Semaste            case '2':
2945263363Semaste            case '3':
2946263363Semaste            case '5':
2947269024Semaste                if (db.names.empty())
2948269024Semaste                    return first;
2949263363Semaste                db.names.push_back(base_name(db.names.back().first));
2950263363Semaste                first += 2;
2951263363Semaste                db.parsed_ctor_dtor_cv = true;
2952263363Semaste                break;
2953263363Semaste            }
2954263363Semaste            break;
2955263363Semaste        case 'D':
2956263363Semaste            switch (first[1])
2957263363Semaste            {
2958263363Semaste            case '0':
2959263363Semaste            case '1':
2960263363Semaste            case '2':
2961263363Semaste            case '5':
2962269024Semaste                if (db.names.empty())
2963269024Semaste                    return first;
2964263363Semaste                db.names.push_back("~" + base_name(db.names.back().first));
2965263363Semaste                first += 2;
2966263363Semaste                db.parsed_ctor_dtor_cv = true;
2967263363Semaste                break;
2968263363Semaste            }
2969263363Semaste            break;
2970263363Semaste        }
2971263363Semaste    }
2972263363Semaste    return first;
2973263363Semaste}
2974263363Semaste
2975263363Semaste// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
2976263363Semaste//                     ::= <closure-type-name>
2977263363Semaste//
2978263363Semaste// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2979263363Semaste//
2980263363Semaste// <lambda-sig> ::= <parameter type>+  # Parameter types or "v" if the lambda has no parameters
2981263363Semaste
2982263363Semastetemplate <class C>
2983263363Semasteconst char*
2984263363Semasteparse_unnamed_type_name(const char* first, const char* last, C& db)
2985263363Semaste{
2986263363Semaste    if (last - first > 2 && first[0] == 'U')
2987263363Semaste    {
2988263363Semaste        char type = first[1];
2989263363Semaste        switch (type)
2990263363Semaste        {
2991263363Semaste        case 't':
2992263363Semaste          {
2993263363Semaste            db.names.push_back(typename C::String("'unnamed"));
2994263363Semaste            const char* t0 = first+2;
2995263363Semaste            if (t0 == last)
2996263363Semaste            {
2997263363Semaste                db.names.pop_back();
2998263363Semaste                return first;
2999263363Semaste            }
3000263363Semaste            if (std::isdigit(*t0))
3001263363Semaste            {
3002263363Semaste                const char* t1 = t0 + 1;
3003263363Semaste                while (t1 != last && std::isdigit(*t1))
3004263363Semaste                    ++t1;
3005263363Semaste                db.names.back().first.append(t0, t1);
3006263363Semaste                t0 = t1;
3007263363Semaste            }
3008263363Semaste            db.names.back().first.push_back('\'');
3009263363Semaste            if (t0 == last || *t0 != '_')
3010263363Semaste            {
3011263363Semaste                db.names.pop_back();
3012263363Semaste                return first;
3013263363Semaste            }
3014263363Semaste            first = t0 + 1;
3015263363Semaste          }
3016263363Semaste            break;
3017263363Semaste        case 'l':
3018263363Semaste          {
3019263363Semaste            db.names.push_back(typename C::String("'lambda'("));
3020263363Semaste            const char* t0 = first+2;
3021263363Semaste            if (first[2] == 'v')
3022263363Semaste            {
3023263363Semaste                db.names.back().first += ')';
3024263363Semaste                ++t0;
3025263363Semaste            }
3026263363Semaste            else
3027263363Semaste            {
3028263363Semaste                const char* t1 = parse_type(t0, last, db);
3029263363Semaste                if (t1 == t0)
3030263363Semaste                {
3031263363Semaste                    db.names.pop_back();
3032263363Semaste                    return first;
3033263363Semaste                }
3034269024Semaste                if (db.names.size() < 2)
3035269024Semaste                    return first;
3036263363Semaste                auto tmp = db.names.back().move_full();
3037263363Semaste                db.names.pop_back();
3038263363Semaste                db.names.back().first.append(tmp);
3039263363Semaste                t0 = t1;
3040263363Semaste                while (true)
3041263363Semaste                {
3042263363Semaste                    t1 = parse_type(t0, last, db);
3043263363Semaste                    if (t1 == t0)
3044263363Semaste                        break;
3045269024Semaste                    if (db.names.size() < 2)
3046269024Semaste                        return first;
3047263363Semaste                    tmp = db.names.back().move_full();
3048263363Semaste                    db.names.pop_back();
3049263363Semaste                    if (!tmp.empty())
3050263363Semaste                    {
3051263363Semaste                        db.names.back().first.append(", ");
3052263363Semaste                        db.names.back().first.append(tmp);
3053263363Semaste                    }
3054263363Semaste                    t0 = t1;
3055263363Semaste                }
3056263363Semaste                db.names.back().first.append(")");
3057263363Semaste            }
3058263363Semaste            if (t0 == last || *t0 != 'E')
3059263363Semaste            {
3060263363Semaste                db.names.pop_back();
3061263363Semaste                return first;
3062263363Semaste            }
3063263363Semaste            ++t0;
3064263363Semaste            if (t0 == last)
3065263363Semaste            {
3066263363Semaste                db.names.pop_back();
3067263363Semaste                return first;
3068263363Semaste            }
3069263363Semaste            if (std::isdigit(*t0))
3070263363Semaste            {
3071263363Semaste                const char* t1 = t0 + 1;
3072263363Semaste                while (t1 != last && std::isdigit(*t1))
3073263363Semaste                    ++t1;
3074263363Semaste                db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
3075263363Semaste                t0 = t1;
3076263363Semaste            }
3077263363Semaste            if (t0 == last || *t0 != '_')
3078263363Semaste            {
3079263363Semaste                db.names.pop_back();
3080263363Semaste                return first;
3081263363Semaste            }
3082263363Semaste            first = t0 + 1;
3083263363Semaste          }
3084263363Semaste            break;
3085263363Semaste        }
3086263363Semaste    }
3087263363Semaste    return first;
3088263363Semaste}
3089263363Semaste
3090263363Semaste// <unqualified-name> ::= <operator-name>
3091263363Semaste//                    ::= <ctor-dtor-name>
3092263363Semaste//                    ::= <source-name>
3093263363Semaste//                    ::= <unnamed-type-name>
3094263363Semaste
3095263363Semastetemplate <class C>
3096263363Semasteconst char*
3097263363Semasteparse_unqualified_name(const char* first, const char* last, C& db)
3098263363Semaste{
3099263363Semaste    if (first != last)
3100263363Semaste    {
3101263363Semaste        const char* t;
3102263363Semaste        switch (*first)
3103263363Semaste        {
3104263363Semaste        case 'C':
3105263363Semaste        case 'D':
3106263363Semaste            t = parse_ctor_dtor_name(first, last, db);
3107263363Semaste            if (t != first)
3108263363Semaste                first = t;
3109263363Semaste            break;
3110263363Semaste        case 'U':
3111263363Semaste            t = parse_unnamed_type_name(first, last, db);
3112263363Semaste            if (t != first)
3113263363Semaste                first = t;
3114263363Semaste            break;
3115263363Semaste        case '1':
3116263363Semaste        case '2':
3117263363Semaste        case '3':
3118263363Semaste        case '4':
3119263363Semaste        case '5':
3120263363Semaste        case '6':
3121263363Semaste        case '7':
3122263363Semaste        case '8':
3123263363Semaste        case '9':
3124263363Semaste            t = parse_source_name(first, last, db);
3125263363Semaste            if (t != first)
3126263363Semaste                first = t;
3127263363Semaste            break;
3128263363Semaste        default:
3129263363Semaste            t = parse_operator_name(first, last, db);
3130263363Semaste            if (t != first)
3131263363Semaste                first = t;
3132263363Semaste            break;
3133263363Semaste        };
3134263363Semaste    }
3135263363Semaste    return first;
3136263363Semaste}
3137263363Semaste
3138263363Semaste// <unscoped-name> ::= <unqualified-name>
3139263363Semaste//                 ::= St <unqualified-name>   # ::std::
3140263363Semaste// extension       ::= StL<unqualified-name>
3141263363Semaste
3142263363Semastetemplate <class C>
3143263363Semasteconst char*
3144263363Semasteparse_unscoped_name(const char* first, const char* last, C& db)
3145263363Semaste{
3146263363Semaste    if (last - first >= 2)
3147263363Semaste    {
3148263363Semaste        const char* t0 = first;
3149263363Semaste        bool St = false;
3150263363Semaste        if (first[0] == 'S' && first[1] == 't')
3151263363Semaste        {
3152263363Semaste            t0 += 2;
3153263363Semaste            St = true;
3154263363Semaste            if (t0 != last && *t0 == 'L')
3155263363Semaste                ++t0;
3156263363Semaste        }
3157263363Semaste        const char* t1 = parse_unqualified_name(t0, last, db);
3158263363Semaste        if (t1 != t0)
3159263363Semaste        {
3160263363Semaste            if (St)
3161269024Semaste            {
3162269024Semaste                if (db.names.empty())
3163269024Semaste                    return first;
3164263363Semaste                db.names.back().first.insert(0, "std::");
3165269024Semaste            }
3166263363Semaste            first = t1;
3167263363Semaste        }
3168263363Semaste    }
3169263363Semaste    return first;
3170263363Semaste}
3171263363Semaste
3172263363Semaste// at <type>                                            # alignof (a type)
3173263363Semaste
3174263363Semastetemplate <class C>
3175263363Semasteconst char*
3176263363Semasteparse_alignof_type(const char* first, const char* last, C& db)
3177263363Semaste{
3178263363Semaste    if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
3179263363Semaste    {
3180263363Semaste        const char* t = parse_type(first+2, last, db);
3181263363Semaste        if (t != first+2)
3182263363Semaste        {
3183269024Semaste            if (db.names.empty())
3184269024Semaste                return first;
3185263363Semaste            db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
3186263363Semaste            first = t;
3187263363Semaste        }
3188263363Semaste    }
3189263363Semaste    return first;
3190263363Semaste}
3191263363Semaste
3192263363Semaste// az <expression>                                            # alignof (a expression)
3193263363Semaste
3194263363Semastetemplate <class C>
3195263363Semasteconst char*
3196263363Semasteparse_alignof_expr(const char* first, const char* last, C& db)
3197263363Semaste{
3198263363Semaste    if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
3199263363Semaste    {
3200263363Semaste        const char* t = parse_expression(first+2, last, db);
3201263363Semaste        if (t != first+2)
3202263363Semaste        {
3203269024Semaste            if (db.names.empty())
3204269024Semaste                return first;
3205263363Semaste            db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
3206263363Semaste            first = t;
3207263363Semaste        }
3208263363Semaste    }
3209263363Semaste    return first;
3210263363Semaste}
3211263363Semaste
3212263363Semastetemplate <class C>
3213263363Semasteconst char*
3214263363Semasteparse_noexcept_expression(const char* first, const char* last, C& db)
3215263363Semaste{
3216263363Semaste    const char* t1 = parse_expression(first, last, db);
3217263363Semaste    if (t1 != first)
3218263363Semaste    {
3219269024Semaste        if (db.names.empty())
3220269024Semaste            return first;
3221263363Semaste        db.names.back().first =  "noexcept (" + db.names.back().move_full() + ")";
3222263363Semaste        first = t1;
3223263363Semaste    }
3224263363Semaste    return first;
3225263363Semaste}
3226263363Semaste
3227263363Semastetemplate <class C>
3228263363Semasteconst char*
3229263363Semasteparse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db)
3230263363Semaste{
3231263363Semaste    const char* t1 = parse_expression(first, last, db);
3232263363Semaste    if (t1 != first)
3233263363Semaste    {
3234269024Semaste        if (db.names.empty())
3235269024Semaste            return first;
3236263363Semaste        db.names.back().first =  op + "(" + db.names.back().move_full() + ")";
3237263363Semaste        first = t1;
3238263363Semaste    }
3239263363Semaste    return first;
3240263363Semaste}
3241263363Semaste
3242263363Semastetemplate <class C>
3243263363Semasteconst char*
3244263363Semasteparse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db)
3245263363Semaste{
3246263363Semaste    const char* t1 = parse_expression(first, last, db);
3247263363Semaste    if (t1 != first)
3248263363Semaste    {
3249263363Semaste        const char* t2 = parse_expression(t1, last, db);
3250263363Semaste        if (t2 != t1)
3251263363Semaste        {
3252269024Semaste            if (db.names.size() < 2)
3253269024Semaste                return first;
3254263363Semaste            auto op2 = db.names.back().move_full();
3255263363Semaste            db.names.pop_back();
3256263363Semaste            auto op1 = db.names.back().move_full();
3257263363Semaste            auto& nm = db.names.back().first;
3258263363Semaste            nm.clear();
3259263363Semaste            if (op == ">")
3260263363Semaste                nm += '(';
3261263363Semaste            nm += "(" + op1 + ") " + op + " (" + op2 + ")";
3262263363Semaste            if (op == ">")
3263263363Semaste                nm += ')';
3264263363Semaste            first = t2;
3265263363Semaste        }
3266263363Semaste        else
3267263363Semaste            db.names.pop_back();
3268263363Semaste    }
3269263363Semaste    return first;
3270263363Semaste}
3271263363Semaste
3272263363Semaste// <expression> ::= <unary operator-name> <expression>
3273263363Semaste//              ::= <binary operator-name> <expression> <expression>
3274263363Semaste//              ::= <ternary operator-name> <expression> <expression> <expression>
3275263363Semaste//              ::= cl <expression>+ E                                   # call
3276263363Semaste//              ::= cv <type> <expression>                               # conversion with one argument
3277263363Semaste//              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments
3278263363Semaste//              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type
3279263363Semaste//              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
3280263363Semaste//              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
3281263363Semaste//              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
3282263363Semaste//              ::= [gs] dl <expression>                                 # delete expression
3283263363Semaste//              ::= [gs] da <expression>                                 # delete[] expression
3284263363Semaste//              ::= pp_ <expression>                                     # prefix ++
3285263363Semaste//              ::= mm_ <expression>                                     # prefix --
3286263363Semaste//              ::= ti <type>                                            # typeid (type)
3287263363Semaste//              ::= te <expression>                                      # typeid (expression)
3288263363Semaste//              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)
3289263363Semaste//              ::= sc <type> <expression>                               # static_cast<type> (expression)
3290263363Semaste//              ::= cc <type> <expression>                               # const_cast<type> (expression)
3291263363Semaste//              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)
3292263363Semaste//              ::= st <type>                                            # sizeof (a type)
3293263363Semaste//              ::= sz <expression>                                      # sizeof (an expression)
3294263363Semaste//              ::= at <type>                                            # alignof (a type)
3295263363Semaste//              ::= az <expression>                                      # alignof (an expression)
3296263363Semaste//              ::= nx <expression>                                      # noexcept (expression)
3297263363Semaste//              ::= <template-param>
3298263363Semaste//              ::= <function-param>
3299263363Semaste//              ::= dt <expression> <unresolved-name>                    # expr.name
3300263363Semaste//              ::= pt <expression> <unresolved-name>                    # expr->name
3301263363Semaste//              ::= ds <expression> <expression>                         # expr.*expr
3302263363Semaste//              ::= sZ <template-param>                                  # size of a parameter pack
3303263363Semaste//              ::= sZ <function-param>                                  # size of a function parameter pack
3304263363Semaste//              ::= sp <expression>                                      # pack expansion
3305263363Semaste//              ::= tw <expression>                                      # throw expression
3306263363Semaste//              ::= tr                                                   # throw with no operand (rethrow)
3307263363Semaste//              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),
3308263363Semaste//                                                                       # freestanding dependent name (e.g., T::x),
3309263363Semaste//                                                                       # objectless nonstatic member reference
3310263363Semaste//              ::= <expr-primary>
3311263363Semaste
3312263363Semastetemplate <class C>
3313263363Semasteconst char*
3314263363Semasteparse_expression(const char* first, const char* last, C& db)
3315263363Semaste{
3316263363Semaste    if (last - first >= 2)
3317263363Semaste    {
3318263363Semaste        const char* t = first;
3319263363Semaste        bool parsed_gs = false;
3320263363Semaste        if (last - first >= 4 && t[0] == 'g' && t[1] == 's')
3321263363Semaste        {
3322263363Semaste            t += 2;
3323263363Semaste            parsed_gs = true;
3324263363Semaste        }
3325263363Semaste        switch (*t)
3326263363Semaste        {
3327263363Semaste        case 'L':
3328263363Semaste            first = parse_expr_primary(first, last, db);
3329263363Semaste            break;
3330263363Semaste        case 'T':
3331263363Semaste            first = parse_template_param(first, last, db);
3332263363Semaste            break;
3333263363Semaste        case 'f':
3334263363Semaste            first = parse_function_param(first, last, db);
3335263363Semaste            break;
3336263363Semaste        case 'a':
3337263363Semaste            switch (t[1])
3338263363Semaste            {
3339263363Semaste            case 'a':
3340263363Semaste                t = parse_binary_expression(first+2, last, "&&", db);
3341263363Semaste                if (t != first+2)
3342263363Semaste                    first = t;
3343263363Semaste                break;
3344263363Semaste            case 'd':
3345263363Semaste                t = parse_prefix_expression(first+2, last, "&", db);
3346263363Semaste                if (t != first+2)
3347263363Semaste                    first = t;
3348263363Semaste                break;
3349263363Semaste            case 'n':
3350263363Semaste                t = parse_binary_expression(first+2, last, "&", db);
3351263363Semaste                if (t != first+2)
3352263363Semaste                    first = t;
3353263363Semaste                break;
3354263363Semaste            case 'N':
3355263363Semaste                t = parse_binary_expression(first+2, last, "&=", db);
3356263363Semaste                if (t != first+2)
3357263363Semaste                    first = t;
3358263363Semaste                break;
3359263363Semaste            case 'S':
3360263363Semaste                t = parse_binary_expression(first+2, last, "=", db);
3361263363Semaste                if (t != first+2)
3362263363Semaste                    first = t;
3363263363Semaste                break;
3364263363Semaste            case 't':
3365263363Semaste                first = parse_alignof_type(first, last, db);
3366263363Semaste                break;
3367263363Semaste            case 'z':
3368263363Semaste                first = parse_alignof_expr(first, last, db);
3369263363Semaste                break;
3370263363Semaste            }
3371263363Semaste            break;
3372263363Semaste        case 'c':
3373263363Semaste            switch (t[1])
3374263363Semaste            {
3375263363Semaste            case 'c':
3376263363Semaste                first = parse_const_cast_expr(first, last, db);
3377263363Semaste                break;
3378263363Semaste            case 'l':
3379263363Semaste                first = parse_call_expr(first, last, db);
3380263363Semaste                break;
3381263363Semaste            case 'm':
3382263363Semaste                t = parse_binary_expression(first+2, last, ",", db);
3383263363Semaste                if (t != first+2)
3384263363Semaste                    first = t;
3385263363Semaste                break;
3386263363Semaste            case 'o':
3387263363Semaste                t = parse_prefix_expression(first+2, last, "~", db);
3388263363Semaste                if (t != first+2)
3389263363Semaste                    first = t;
3390263363Semaste                break;
3391263363Semaste            case 'v':
3392263363Semaste                first = parse_conversion_expr(first, last, db);
3393263363Semaste                break;
3394263363Semaste            }
3395263363Semaste            break;
3396263363Semaste        case 'd':
3397263363Semaste            switch (t[1])
3398263363Semaste            {
3399263363Semaste            case 'a':
3400263363Semaste                {
3401263363Semaste                    const char* t1 = parse_expression(t+2, last, db);
3402263363Semaste                    if (t1 != t+2)
3403263363Semaste                    {
3404269024Semaste                        if (db.names.empty())
3405269024Semaste                            return first;
3406263363Semaste                        db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
3407263363Semaste                                          "delete[] " + db.names.back().move_full();
3408263363Semaste                        first = t1;
3409263363Semaste                    }
3410263363Semaste                }
3411263363Semaste                break;
3412263363Semaste            case 'c':
3413263363Semaste                first = parse_dynamic_cast_expr(first, last, db);
3414263363Semaste                break;
3415263363Semaste            case 'e':
3416263363Semaste                t = parse_prefix_expression(first+2, last, "*", db);
3417263363Semaste                if (t != first+2)
3418263363Semaste                    first = t;
3419263363Semaste                break;
3420263363Semaste            case 'l':
3421263363Semaste                {
3422263363Semaste                    const char* t1 = parse_expression(t+2, last, db);
3423263363Semaste                    if (t1 != t+2)
3424263363Semaste                    {
3425269024Semaste                        if (db.names.empty())
3426269024Semaste                            return first;
3427263363Semaste                        db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
3428263363Semaste                                          "delete " + db.names.back().move_full();
3429263363Semaste                        first = t1;
3430263363Semaste                    }
3431263363Semaste                }
3432263363Semaste                break;
3433263363Semaste            case 'n':
3434263363Semaste                return parse_unresolved_name(first, last, db);
3435263363Semaste            case 's':
3436263363Semaste                first = parse_dot_star_expr(first, last, db);
3437263363Semaste                break;
3438263363Semaste            case 't':
3439263363Semaste                first = parse_dot_expr(first, last, db);
3440263363Semaste                break;
3441263363Semaste            case 'v':
3442263363Semaste                t = parse_binary_expression(first+2, last, "/", db);
3443263363Semaste                if (t != first+2)
3444263363Semaste                    first = t;
3445263363Semaste                break;
3446263363Semaste            case 'V':
3447263363Semaste                t = parse_binary_expression(first+2, last, "/=", db);
3448263363Semaste                if (t != first+2)
3449263363Semaste                    first = t;
3450263363Semaste                break;
3451263363Semaste            }
3452263363Semaste            break;
3453263363Semaste        case 'e':
3454263363Semaste            switch (t[1])
3455263363Semaste            {
3456263363Semaste            case 'o':
3457263363Semaste                t = parse_binary_expression(first+2, last, "^", db);
3458263363Semaste                if (t != first+2)
3459263363Semaste                    first = t;
3460263363Semaste                break;
3461263363Semaste            case 'O':
3462263363Semaste                t = parse_binary_expression(first+2, last, "^=", db);
3463263363Semaste                if (t != first+2)
3464263363Semaste                    first = t;
3465263363Semaste                break;
3466263363Semaste            case 'q':
3467263363Semaste                t = parse_binary_expression(first+2, last, "==", db);
3468263363Semaste                if (t != first+2)
3469263363Semaste                    first = t;
3470263363Semaste                break;
3471263363Semaste            }
3472263363Semaste            break;
3473263363Semaste        case 'g':
3474263363Semaste            switch (t[1])
3475263363Semaste            {
3476263363Semaste            case 'e':
3477263363Semaste                t = parse_binary_expression(first+2, last, ">=", db);
3478263363Semaste                if (t != first+2)
3479263363Semaste                    first = t;
3480263363Semaste                break;
3481263363Semaste            case 't':
3482263363Semaste                t = parse_binary_expression(first+2, last, ">", db);
3483263363Semaste                if (t != first+2)
3484263363Semaste                    first = t;
3485263363Semaste                break;
3486263363Semaste            }
3487263363Semaste            break;
3488263363Semaste        case 'i':
3489263363Semaste            if (t[1] == 'x')
3490263363Semaste            {
3491263363Semaste                const char* t1 = parse_expression(first+2, last, db);
3492263363Semaste                if (t1 != first+2)
3493263363Semaste                {
3494263363Semaste                    const char* t2 = parse_expression(t1, last, db);
3495263363Semaste                    if (t2 != t1)
3496263363Semaste                    {
3497269024Semaste                        if (db.names.size() < 2)
3498269024Semaste                            return first;
3499263363Semaste                        auto op2 = db.names.back().move_full();
3500263363Semaste                        db.names.pop_back();
3501263363Semaste                        auto op1 = db.names.back().move_full();
3502263363Semaste                        db.names.back() = "(" + op1 + ")[" + op2 + "]";
3503263363Semaste                        first = t2;
3504263363Semaste                    }
3505263363Semaste                    else
3506263363Semaste                        db.names.pop_back();
3507263363Semaste                }
3508263363Semaste            }
3509263363Semaste            break;
3510263363Semaste        case 'l':
3511263363Semaste            switch (t[1])
3512263363Semaste            {
3513263363Semaste            case 'e':
3514263363Semaste                t = parse_binary_expression(first+2, last, "<=", db);
3515263363Semaste                if (t != first+2)
3516263363Semaste                    first = t;
3517263363Semaste                break;
3518263363Semaste            case 's':
3519263363Semaste                t = parse_binary_expression(first+2, last, "<<", db);
3520263363Semaste                if (t != first+2)
3521263363Semaste                    first = t;
3522263363Semaste                break;
3523263363Semaste            case 'S':
3524263363Semaste                t = parse_binary_expression(first+2, last, "<<=", db);
3525263363Semaste                if (t != first+2)
3526263363Semaste                    first = t;
3527263363Semaste                break;
3528263363Semaste            case 't':
3529263363Semaste                t = parse_binary_expression(first+2, last, "<", db);
3530263363Semaste                if (t != first+2)
3531263363Semaste                    first = t;
3532263363Semaste                break;
3533263363Semaste            }
3534263363Semaste            break;
3535263363Semaste        case 'm':
3536263363Semaste            switch (t[1])
3537263363Semaste            {
3538263363Semaste            case 'i':
3539263363Semaste                t = parse_binary_expression(first+2, last, "-", db);
3540263363Semaste                if (t != first+2)
3541263363Semaste                    first = t;
3542263363Semaste                break;
3543263363Semaste            case 'I':
3544263363Semaste                t = parse_binary_expression(first+2, last, "-=", db);
3545263363Semaste                if (t != first+2)
3546263363Semaste                    first = t;
3547263363Semaste                break;
3548263363Semaste            case 'l':
3549263363Semaste                t = parse_binary_expression(first+2, last, "*", db);
3550263363Semaste                if (t != first+2)
3551263363Semaste                    first = t;
3552263363Semaste                break;
3553263363Semaste            case 'L':
3554263363Semaste                t = parse_binary_expression(first+2, last, "*=", db);
3555263363Semaste                if (t != first+2)
3556263363Semaste                    first = t;
3557263363Semaste                break;
3558263363Semaste            case 'm':
3559263363Semaste                if (first+2 != last && first[2] == '_')
3560263363Semaste                {
3561263363Semaste                    t = parse_prefix_expression(first+3, last, "--", db);
3562263363Semaste                    if (t != first+3)
3563263363Semaste                        first = t;
3564263363Semaste                }
3565263363Semaste                else
3566263363Semaste                {
3567263363Semaste                    const char* t1 = parse_expression(first+2, last, db);
3568263363Semaste                    if (t1 != first+2)
3569263363Semaste                    {
3570269024Semaste                        if (db.names.empty())
3571269024Semaste                            return first;
3572263363Semaste                        db.names.back() = "(" + db.names.back().move_full() + ")--";
3573263363Semaste                        first = t1;
3574263363Semaste                    }
3575263363Semaste                }
3576263363Semaste                break;
3577263363Semaste            }
3578263363Semaste            break;
3579263363Semaste        case 'n':
3580263363Semaste            switch (t[1])
3581263363Semaste            {
3582263363Semaste            case 'a':
3583263363Semaste            case 'w':
3584263363Semaste                first = parse_new_expr(first, last, db);
3585263363Semaste                break;
3586263363Semaste            case 'e':
3587263363Semaste                t = parse_binary_expression(first+2, last, "!=", db);
3588263363Semaste                if (t != first+2)
3589263363Semaste                    first = t;
3590263363Semaste                break;
3591263363Semaste            case 'g':
3592263363Semaste                t = parse_prefix_expression(first+2, last, "-", db);
3593263363Semaste                if (t != first+2)
3594263363Semaste                    first = t;
3595263363Semaste                break;
3596263363Semaste            case 't':
3597263363Semaste                t = parse_prefix_expression(first+2, last, "!", db);
3598263363Semaste                if (t != first+2)
3599263363Semaste                    first = t;
3600263363Semaste                break;
3601263363Semaste            case 'x':
3602263363Semaste                t = parse_noexcept_expression(first+2, last, db);
3603263363Semaste                if (t != first+2)
3604263363Semaste                    first = t;
3605263363Semaste                break;
3606263363Semaste            }
3607263363Semaste            break;
3608263363Semaste        case 'o':
3609263363Semaste            switch (t[1])
3610263363Semaste            {
3611263363Semaste            case 'n':
3612263363Semaste                return parse_unresolved_name(first, last, db);
3613263363Semaste            case 'o':
3614263363Semaste                t = parse_binary_expression(first+2, last, "||", db);
3615263363Semaste                if (t != first+2)
3616263363Semaste                    first = t;
3617263363Semaste                break;
3618263363Semaste            case 'r':
3619263363Semaste                t = parse_binary_expression(first+2, last, "|", db);
3620263363Semaste                if (t != first+2)
3621263363Semaste                    first = t;
3622263363Semaste                break;
3623263363Semaste            case 'R':
3624263363Semaste                t = parse_binary_expression(first+2, last, "|=", db);
3625263363Semaste                if (t != first+2)
3626263363Semaste                    first = t;
3627263363Semaste                break;
3628263363Semaste            }
3629263363Semaste            break;
3630263363Semaste        case 'p':
3631263363Semaste            switch (t[1])
3632263363Semaste            {
3633263363Semaste            case 'm':
3634263363Semaste                t = parse_binary_expression(first+2, last, "->*", db);
3635263363Semaste                if (t != first+2)
3636263363Semaste                    first = t;
3637263363Semaste                break;
3638263363Semaste            case 'l':
3639263363Semaste                t = parse_binary_expression(first+2, last, "+", db);
3640263363Semaste                if (t != first+2)
3641263363Semaste                    first = t;
3642263363Semaste                break;
3643263363Semaste            case 'L':
3644263363Semaste                t = parse_binary_expression(first+2, last, "+=", db);
3645263363Semaste                if (t != first+2)
3646263363Semaste                    first = t;
3647263363Semaste                break;
3648263363Semaste            case 'p':
3649263363Semaste                if (first+2 != last && first[2] == '_')
3650263363Semaste                {
3651263363Semaste                    t = parse_prefix_expression(first+3, last, "++", db);
3652263363Semaste                    if (t != first+3)
3653263363Semaste                        first = t;
3654263363Semaste                }
3655263363Semaste                else
3656263363Semaste                {
3657263363Semaste                    const char* t1 = parse_expression(first+2, last, db);
3658263363Semaste                    if (t1 != first+2)
3659263363Semaste                    {
3660269024Semaste                        if (db.names.empty())
3661269024Semaste                            return first;
3662263363Semaste                        db.names.back() = "(" + db.names.back().move_full() + ")++";
3663263363Semaste                        first = t1;
3664263363Semaste                    }
3665263363Semaste                }
3666263363Semaste                break;
3667263363Semaste            case 's':
3668263363Semaste                t = parse_prefix_expression(first+2, last, "+", db);
3669263363Semaste                if (t != first+2)
3670263363Semaste                    first = t;
3671263363Semaste                break;
3672263363Semaste            case 't':
3673263363Semaste                first = parse_arrow_expr(first, last, db);
3674263363Semaste                break;
3675263363Semaste            }
3676263363Semaste            break;
3677263363Semaste        case 'q':
3678263363Semaste            if (t[1] == 'u')
3679263363Semaste            {
3680263363Semaste                const char* t1 = parse_expression(first+2, last, db);
3681263363Semaste                if (t1 != first+2)
3682263363Semaste                {
3683263363Semaste                    const char* t2 = parse_expression(t1, last, db);
3684263363Semaste                    if (t2 != t1)
3685263363Semaste                    {
3686263363Semaste                        const char* t3 = parse_expression(t2, last, db);
3687263363Semaste                        if (t3 != t2)
3688263363Semaste                        {
3689269024Semaste                            if (db.names.size() < 3)
3690269024Semaste                                return first;
3691263363Semaste                            auto op3 = db.names.back().move_full();
3692263363Semaste                            db.names.pop_back();
3693263363Semaste                            auto op2 = db.names.back().move_full();
3694263363Semaste                            db.names.pop_back();
3695263363Semaste                            auto op1 = db.names.back().move_full();
3696263363Semaste                            db.names.back() = "(" + op1 + ") ? (" + op2 + ") : (" + op3 + ")";
3697263363Semaste                            first = t3;
3698263363Semaste                        }
3699263363Semaste                        else
3700263363Semaste                        {
3701263363Semaste                            db.names.pop_back();
3702263363Semaste                            db.names.pop_back();
3703263363Semaste                        }
3704263363Semaste                    }
3705263363Semaste                    else
3706263363Semaste                        db.names.pop_back();
3707263363Semaste                }
3708263363Semaste            }
3709263363Semaste            break;
3710263363Semaste        case 'r':
3711263363Semaste            switch (t[1])
3712263363Semaste            {
3713263363Semaste            case 'c':
3714263363Semaste                first = parse_reinterpret_cast_expr(first, last, db);
3715263363Semaste                break;
3716263363Semaste            case 'm':
3717263363Semaste                t = parse_binary_expression(first+2, last, "%", db);
3718263363Semaste                if (t != first+2)
3719263363Semaste                    first = t;
3720263363Semaste                break;
3721263363Semaste            case 'M':
3722263363Semaste                t = parse_binary_expression(first+2, last, "%=", db);
3723263363Semaste                if (t != first+2)
3724263363Semaste                    first = t;
3725263363Semaste                break;
3726263363Semaste            case 's':
3727263363Semaste                t = parse_binary_expression(first+2, last, ">>", db);
3728263363Semaste                if (t != first+2)
3729263363Semaste                    first = t;
3730263363Semaste                break;
3731263363Semaste            case 'S':
3732263363Semaste                t = parse_binary_expression(first+2, last, ">>=", db);
3733263363Semaste                if (t != first+2)
3734263363Semaste                    first = t;
3735263363Semaste                break;
3736263363Semaste            }
3737263363Semaste            break;
3738263363Semaste        case 's':
3739263363Semaste            switch (t[1])
3740263363Semaste            {
3741263363Semaste            case 'c':
3742263363Semaste                first = parse_static_cast_expr(first, last, db);
3743263363Semaste                break;
3744263363Semaste            case 'p':
3745263363Semaste                first = parse_pack_expansion(first, last, db);
3746263363Semaste                break;
3747263363Semaste            case 'r':
3748263363Semaste                return parse_unresolved_name(first, last, db);
3749263363Semaste            case 't':
3750263363Semaste                first = parse_sizeof_type_expr(first, last, db);
3751263363Semaste                break;
3752263363Semaste            case 'z':
3753263363Semaste                first = parse_sizeof_expr_expr(first, last, db);
3754263363Semaste                break;
3755263363Semaste            case 'Z':
3756263363Semaste                if (last - t >= 3)
3757263363Semaste                {
3758263363Semaste                    switch (t[2])
3759263363Semaste                    {
3760263363Semaste                    case 'T':
3761263363Semaste                        first = parse_sizeof_param_pack_expr(first, last, db);
3762263363Semaste                        break;
3763263363Semaste                    case 'f':
3764263363Semaste                        first = parse_sizeof_function_param_pack_expr(first, last, db);
3765263363Semaste                        break;
3766263363Semaste                    }
3767263363Semaste                }
3768263363Semaste                break;
3769263363Semaste            }
3770263363Semaste            break;
3771263363Semaste        case 't':
3772263363Semaste            switch (t[1])
3773263363Semaste            {
3774263363Semaste            case 'e':
3775263363Semaste            case 'i':
3776263363Semaste                first = parse_typeid_expr(first, last, db);
3777263363Semaste                break;
3778263363Semaste            case 'r':
3779263363Semaste                db.names.push_back("throw");
3780263363Semaste                first += 2;
3781263363Semaste                break;
3782263363Semaste            case 'w':
3783263363Semaste                first = parse_throw_expr(first, last, db);
3784263363Semaste                break;
3785263363Semaste            }
3786263363Semaste            break;
3787263363Semaste        case '1':
3788263363Semaste        case '2':
3789263363Semaste        case '3':
3790263363Semaste        case '4':
3791263363Semaste        case '5':
3792263363Semaste        case '6':
3793263363Semaste        case '7':
3794263363Semaste        case '8':
3795263363Semaste        case '9':
3796263363Semaste            return parse_unresolved_name(first, last, db);
3797263363Semaste        }
3798263363Semaste    }
3799263363Semaste    return first;
3800263363Semaste}
3801263363Semaste
3802263363Semaste// <template-arg> ::= <type>                                             # type or template
3803263363Semaste//                ::= X <expression> E                                   # expression
3804263363Semaste//                ::= <expr-primary>                                     # simple expressions
3805263363Semaste//                ::= J <template-arg>* E                                # argument pack
3806263363Semaste//                ::= LZ <encoding> E                                    # extension
3807263363Semaste
3808263363Semastetemplate <class C>
3809263363Semasteconst char*
3810263363Semasteparse_template_arg(const char* first, const char* last, C& db)
3811263363Semaste{
3812263363Semaste    if (first != last)
3813263363Semaste    {
3814263363Semaste        const char* t;
3815263363Semaste        switch (*first)
3816263363Semaste        {
3817263363Semaste        case 'X':
3818263363Semaste            t = parse_expression(first+1, last, db);
3819263363Semaste            if (t != first+1)
3820263363Semaste            {
3821263363Semaste                if (t != last && *t == 'E')
3822263363Semaste                    first = t+1;
3823263363Semaste            }
3824263363Semaste            break;
3825263363Semaste        case 'J':
3826263363Semaste            t = first+1;
3827263363Semaste            if (t == last)
3828263363Semaste                return first;
3829263363Semaste            while (*t != 'E')
3830263363Semaste            {
3831263363Semaste                const char* t1 = parse_template_arg(t, last, db);
3832263363Semaste                if (t1 == t)
3833263363Semaste                    return first;
3834263363Semaste                t = t1;
3835263363Semaste            }
3836263363Semaste            first = t+1;
3837263363Semaste            break;
3838263363Semaste        case 'L':
3839263363Semaste            // <expr-primary> or LZ <encoding> E
3840263363Semaste            if (first+1 != last && first[1] == 'Z')
3841263363Semaste            {
3842263363Semaste                t = parse_encoding(first+2, last, db);
3843263363Semaste                if (t != first+2 && t != last && *t == 'E')
3844263363Semaste                    first = t+1;
3845263363Semaste            }
3846263363Semaste            else
3847263363Semaste                first = parse_expr_primary(first, last, db);
3848263363Semaste            break;
3849263363Semaste        default:
3850263363Semaste            // <type>
3851263363Semaste            first = parse_type(first, last, db);
3852263363Semaste            break;
3853263363Semaste        }
3854263363Semaste    }
3855263363Semaste    return first;
3856263363Semaste}
3857263363Semaste
3858263363Semaste// <template-args> ::= I <template-arg>* E
3859263363Semaste//     extension, the abi says <template-arg>+
3860263363Semaste
3861263363Semastetemplate <class C>
3862263363Semasteconst char*
3863263363Semasteparse_template_args(const char* first, const char* last, C& db)
3864263363Semaste{
3865263363Semaste    if (last - first >= 2 && *first == 'I')
3866263363Semaste    {
3867263363Semaste        if (db.tag_templates)
3868263363Semaste            db.template_param.back().clear();
3869263363Semaste        const char* t = first+1;
3870263363Semaste        typename C::String args("<");
3871263363Semaste        while (*t != 'E')
3872263363Semaste        {
3873263363Semaste            if (db.tag_templates)
3874263363Semaste                db.template_param.emplace_back(db.names.get_allocator());
3875263363Semaste            size_t k0 = db.names.size();
3876263363Semaste            const char* t1 = parse_template_arg(t, last, db);
3877263363Semaste            size_t k1 = db.names.size();
3878263363Semaste            if (db.tag_templates)
3879263363Semaste                db.template_param.pop_back();
3880263363Semaste            if (t1 == t || t1 == last)
3881263363Semaste                return first;
3882263363Semaste            if (db.tag_templates)
3883263363Semaste            {
3884263363Semaste                db.template_param.back().emplace_back(db.names.get_allocator());
3885263363Semaste                for (size_t k = k0; k < k1; ++k)
3886263363Semaste                    db.template_param.back().back().push_back(db.names[k]);
3887263363Semaste            }
3888263363Semaste            for (size_t k = k0; k < k1; ++k)
3889263363Semaste            {
3890263363Semaste                if (args.size() > 1)
3891263363Semaste                    args += ", ";
3892263363Semaste                args += db.names[k].move_full();
3893263363Semaste            }
3894263363Semaste            for (; k1 != k0; --k1)
3895263363Semaste                db.names.pop_back();
3896263363Semaste            t = t1;
3897263363Semaste        }
3898263363Semaste        first = t + 1;
3899263363Semaste        if (args.back() != '>')
3900263363Semaste            args += ">";
3901263363Semaste        else
3902263363Semaste            args += " >";
3903263363Semaste        db.names.push_back(std::move(args));
3904263363Semaste
3905263363Semaste    }
3906263363Semaste    return first;
3907263363Semaste}
3908263363Semaste
3909263363Semaste// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
3910263363Semaste//               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
3911263363Semaste//
3912263363Semaste// <prefix> ::= <prefix> <unqualified-name>
3913263363Semaste//          ::= <template-prefix> <template-args>
3914263363Semaste//          ::= <template-param>
3915263363Semaste//          ::= <decltype>
3916263363Semaste//          ::= # empty
3917263363Semaste//          ::= <substitution>
3918263363Semaste//          ::= <prefix> <data-member-prefix>
3919263363Semaste//  extension ::= L
3920263363Semaste//
3921263363Semaste// <template-prefix> ::= <prefix> <template unqualified-name>
3922263363Semaste//                   ::= <template-param>
3923263363Semaste//                   ::= <substitution>
3924263363Semaste
3925263363Semastetemplate <class C>
3926263363Semasteconst char*
3927263363Semasteparse_nested_name(const char* first, const char* last, C& db)
3928263363Semaste{
3929263363Semaste    if (first != last && *first == 'N')
3930263363Semaste    {
3931263363Semaste        unsigned cv;
3932263363Semaste        const char* t0 = parse_cv_qualifiers(first+1, last, cv);
3933263363Semaste        if (t0 == last)
3934263363Semaste            return first;
3935263363Semaste        db.ref = 0;
3936263363Semaste        if (*t0 == 'R')
3937263363Semaste        {
3938263363Semaste            db.ref = 1;
3939263363Semaste            ++t0;
3940263363Semaste        }
3941263363Semaste        else if (*t0 == 'O')
3942263363Semaste        {
3943263363Semaste            db.ref = 2;
3944263363Semaste            ++t0;
3945263363Semaste        }
3946263363Semaste        db.names.emplace_back();
3947263363Semaste        if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
3948263363Semaste        {
3949263363Semaste            t0 += 2;
3950263363Semaste            db.names.back().first = "std";
3951263363Semaste        }
3952263363Semaste        if (t0 == last)
3953263363Semaste        {
3954263363Semaste            db.names.pop_back();
3955263363Semaste            return first;
3956263363Semaste        }
3957263363Semaste        bool pop_subs = false;
3958263363Semaste        while (*t0 != 'E')
3959263363Semaste        {
3960263363Semaste            const char* t1;
3961263363Semaste            switch (*t0)
3962263363Semaste            {
3963263363Semaste            case 'S':
3964263363Semaste                if (t0 + 1 != last && t0[1] == 't')
3965263363Semaste                    goto do_parse_unqualified_name;
3966263363Semaste                t1 = parse_substitution(t0, last, db);
3967263363Semaste                if (t1 != t0 && t1 != last)
3968263363Semaste                {
3969263363Semaste                    auto name = db.names.back().move_full();
3970263363Semaste                    db.names.pop_back();
3971263363Semaste                    if (!db.names.back().first.empty())
3972263363Semaste                    {
3973263363Semaste                        db.names.back().first += "::" + name;
3974263363Semaste                        db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
3975263363Semaste                    }
3976263363Semaste                    else
3977263363Semaste                        db.names.back().first = name;
3978263363Semaste                    pop_subs = true;
3979263363Semaste                    t0 = t1;
3980263363Semaste                }
3981263363Semaste                else
3982263363Semaste                    return first;
3983263363Semaste                break;
3984263363Semaste            case 'T':
3985263363Semaste                t1 = parse_template_param(t0, last, db);
3986263363Semaste                if (t1 != t0 && t1 != last)
3987263363Semaste                {
3988263363Semaste                    auto name = db.names.back().move_full();
3989263363Semaste                    db.names.pop_back();
3990263363Semaste                    if (!db.names.back().first.empty())
3991263363Semaste                        db.names.back().first += "::" + name;
3992263363Semaste                    else
3993263363Semaste                        db.names.back().first = name;
3994263363Semaste                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
3995263363Semaste                    pop_subs = true;
3996263363Semaste                    t0 = t1;
3997263363Semaste                }
3998263363Semaste                else
3999263363Semaste                    return first;
4000263363Semaste                break;
4001263363Semaste            case 'D':
4002263363Semaste                if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
4003263363Semaste                    goto do_parse_unqualified_name;
4004263363Semaste                t1 = parse_decltype(t0, last, db);
4005263363Semaste                if (t1 != t0 && t1 != last)
4006263363Semaste                {
4007263363Semaste                    auto name = db.names.back().move_full();
4008263363Semaste                    db.names.pop_back();
4009263363Semaste                    if (!db.names.back().first.empty())
4010263363Semaste                        db.names.back().first += "::" + name;
4011263363Semaste                    else
4012263363Semaste                        db.names.back().first = name;
4013263363Semaste                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4014263363Semaste                    pop_subs = true;
4015263363Semaste                    t0 = t1;
4016263363Semaste                }
4017263363Semaste                else
4018263363Semaste                    return first;
4019263363Semaste                break;
4020263363Semaste            case 'I':
4021263363Semaste                t1 = parse_template_args(t0, last, db);
4022263363Semaste                if (t1 != t0 && t1 != last)
4023263363Semaste                {
4024263363Semaste                    auto name = db.names.back().move_full();
4025263363Semaste                    db.names.pop_back();
4026263363Semaste                    db.names.back().first += name;
4027263363Semaste                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4028263363Semaste                    t0 = t1;
4029263363Semaste                }
4030263363Semaste                else
4031263363Semaste                    return first;
4032263363Semaste                break;
4033263363Semaste            case 'L':
4034263363Semaste                if (++t0 == last)
4035263363Semaste                    return first;
4036263363Semaste                break;
4037263363Semaste            default:
4038263363Semaste            do_parse_unqualified_name:
4039263363Semaste                t1 = parse_unqualified_name(t0, last, db);
4040263363Semaste                if (t1 != t0 && t1 != last)
4041263363Semaste                {
4042263363Semaste                    auto name = db.names.back().move_full();
4043263363Semaste                    db.names.pop_back();
4044263363Semaste                    if (!db.names.back().first.empty())
4045263363Semaste                        db.names.back().first += "::" + name;
4046263363Semaste                    else
4047263363Semaste                        db.names.back().first = name;
4048263363Semaste                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4049263363Semaste                    pop_subs = true;
4050263363Semaste                    t0 = t1;
4051263363Semaste                }
4052263363Semaste                else
4053263363Semaste                    return first;
4054263363Semaste            }
4055263363Semaste        }
4056263363Semaste        first = t0 + 1;
4057263363Semaste        db.cv = cv;
4058263363Semaste        if (pop_subs && !db.subs.empty())
4059263363Semaste            db.subs.pop_back();
4060263363Semaste    }
4061263363Semaste    return first;
4062263363Semaste}
4063263363Semaste
4064263363Semaste// <discriminator> := _ <non-negative number>      # when number < 10
4065263363Semaste//                 := __ <non-negative number> _   # when number >= 10
4066263363Semaste//  extension      := decimal-digit+
4067263363Semaste
4068263363Semasteconst char*
4069263363Semasteparse_discriminator(const char* first, const char* last)
4070263363Semaste{
4071263363Semaste    // parse but ignore discriminator
4072263363Semaste    if (first != last)
4073263363Semaste    {
4074263363Semaste        if (*first == '_')
4075263363Semaste        {
4076263363Semaste            const char* t1 = first+1;
4077263363Semaste            if (t1 != last)
4078263363Semaste            {
4079263363Semaste                if (std::isdigit(*t1))
4080263363Semaste                    first = t1+1;
4081263363Semaste                else if (*t1 == '_')
4082263363Semaste                {
4083263363Semaste                    for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4084263363Semaste                        ;
4085263363Semaste                    if (t1 != last && *t1 == '_')
4086263363Semaste                        first = t1 + 1;
4087263363Semaste                }
4088263363Semaste            }
4089263363Semaste        }
4090263363Semaste        else if (std::isdigit(*first))
4091263363Semaste        {
4092263363Semaste            const char* t1 = first+1;
4093263363Semaste            for (; t1 != last && std::isdigit(*t1); ++t1)
4094263363Semaste                ;
4095263363Semaste            first = t1;
4096263363Semaste        }
4097263363Semaste    }
4098263363Semaste    return first;
4099263363Semaste}
4100263363Semaste
4101263363Semaste// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
4102263363Semaste//              := Z <function encoding> E s [<discriminator>]
4103263363Semaste//              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
4104263363Semaste
4105263363Semastetemplate <class C>
4106263363Semasteconst char*
4107263363Semasteparse_local_name(const char* first, const char* last, C& db)
4108263363Semaste{
4109263363Semaste    if (first != last && *first == 'Z')
4110263363Semaste    {
4111263363Semaste        const char* t = parse_encoding(first+1, last, db);
4112263363Semaste        if (t != first+1 && t != last && *t == 'E' && ++t != last)
4113263363Semaste        {
4114263363Semaste            switch (*t)
4115263363Semaste            {
4116263363Semaste            case 's':
4117263363Semaste                first = parse_discriminator(t+1, last);
4118269024Semaste                if (db.names.empty())
4119269024Semaste                    return first;
4120263363Semaste                db.names.back().first.append("::string literal");
4121263363Semaste                break;
4122263363Semaste            case 'd':
4123263363Semaste                if (++t != last)
4124263363Semaste                {
4125263363Semaste                    const char* t1 = parse_number(t, last);
4126263363Semaste                    if (t1 != last && *t1 == '_')
4127263363Semaste                    {
4128263363Semaste                        t = t1 + 1;
4129263363Semaste                        t1 = parse_name(t, last, db);
4130263363Semaste                        if (t1 != t)
4131263363Semaste                        {
4132269024Semaste                            if (db.names.size() < 2)
4133269024Semaste                                return first;
4134263363Semaste                            auto name = db.names.back().move_full();
4135263363Semaste                            db.names.pop_back();
4136263363Semaste                            db.names.back().first.append("::");
4137263363Semaste                            db.names.back().first.append(name);
4138263363Semaste                            first = t1;
4139263363Semaste                        }
4140263363Semaste                        else
4141263363Semaste                            db.names.pop_back();
4142263363Semaste                    }
4143263363Semaste                }
4144263363Semaste                break;
4145263363Semaste            default:
4146263363Semaste                {
4147263363Semaste                    const char* t1 = parse_name(t, last, db);
4148263363Semaste                    if (t1 != t)
4149263363Semaste                    {
4150263363Semaste                        // parse but ignore discriminator
4151263363Semaste                        first = parse_discriminator(t1, last);
4152269024Semaste                        if (db.names.size() < 2)
4153269024Semaste                            return first;
4154263363Semaste                        auto name = db.names.back().move_full();
4155263363Semaste                        db.names.pop_back();
4156263363Semaste                        db.names.back().first.append("::");
4157263363Semaste                        db.names.back().first.append(name);
4158263363Semaste                    }
4159263363Semaste                    else
4160263363Semaste                        db.names.pop_back();
4161263363Semaste                }
4162263363Semaste                break;
4163263363Semaste            }
4164263363Semaste        }
4165263363Semaste    }
4166263363Semaste    return first;
4167263363Semaste}
4168263363Semaste
4169263363Semaste// <name> ::= <nested-name> // N
4170263363Semaste//        ::= <local-name> # See Scope Encoding below  // Z
4171263363Semaste//        ::= <unscoped-template-name> <template-args>
4172263363Semaste//        ::= <unscoped-name>
4173263363Semaste
4174263363Semaste// <unscoped-template-name> ::= <unscoped-name>
4175263363Semaste//                          ::= <substitution>
4176263363Semaste
4177263363Semastetemplate <class C>
4178263363Semasteconst char*
4179263363Semasteparse_name(const char* first, const char* last, C& db)
4180263363Semaste{
4181263363Semaste    if (last - first >= 2)
4182263363Semaste    {
4183263363Semaste        const char* t0 = first;
4184263363Semaste        // extension: ignore L here
4185263363Semaste        if (*t0 == 'L')
4186263363Semaste            ++t0;
4187263363Semaste        switch (*t0)
4188263363Semaste        {
4189263363Semaste        case 'N':
4190263363Semaste          {
4191263363Semaste            const char* t1 = parse_nested_name(t0, last, db);
4192263363Semaste            if (t1 != t0)
4193263363Semaste                first = t1;
4194263363Semaste            break;
4195263363Semaste          }
4196263363Semaste        case 'Z':
4197263363Semaste          {
4198263363Semaste            const char* t1 = parse_local_name(t0, last, db);
4199263363Semaste            if (t1 != t0)
4200263363Semaste                first = t1;
4201263363Semaste            break;
4202263363Semaste          }
4203263363Semaste        default:
4204263363Semaste          {
4205263363Semaste            const char* t1 = parse_unscoped_name(t0, last, db);
4206263363Semaste            if (t1 != t0)
4207263363Semaste            {
4208263363Semaste                if (t1 != last && *t1 == 'I')  // <unscoped-template-name> <template-args>
4209263363Semaste                {
4210269024Semaste                    if (db.names.empty())
4211269024Semaste                        return first;
4212263363Semaste                    db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4213263363Semaste                    t0 = t1;
4214263363Semaste                    t1 = parse_template_args(t0, last, db);
4215263363Semaste                    if (t1 != t0)
4216263363Semaste                    {
4217269024Semaste                        if (db.names.size() < 2)
4218269024Semaste                            return first;
4219263363Semaste                        auto tmp = db.names.back().move_full();
4220263363Semaste                        db.names.pop_back();
4221263363Semaste                        db.names.back().first += tmp;
4222263363Semaste                        first = t1;
4223263363Semaste                    }
4224263363Semaste                }
4225263363Semaste                else   // <unscoped-name>
4226263363Semaste                    first = t1;
4227263363Semaste            }
4228263363Semaste            else
4229263363Semaste            {   // try <substitution> <template-args>
4230263363Semaste                t1 = parse_substitution(t0, last, db);
4231263363Semaste                if (t1 != t0 && t1 != last && *t1 == 'I')
4232263363Semaste                {
4233263363Semaste                    t0 = t1;
4234263363Semaste                    t1 = parse_template_args(t0, last, db);
4235263363Semaste                    if (t1 != t0)
4236263363Semaste                    {
4237269024Semaste                        if (db.names.size() < 2)
4238269024Semaste                            return first;
4239263363Semaste                        auto tmp = db.names.back().move_full();
4240263363Semaste                        db.names.pop_back();
4241263363Semaste                        db.names.back().first += tmp;
4242263363Semaste                        first = t1;
4243263363Semaste                    }
4244263363Semaste                }
4245263363Semaste            }
4246263363Semaste            break;
4247263363Semaste          }
4248263363Semaste        }
4249263363Semaste    }
4250263363Semaste    return first;
4251263363Semaste}
4252263363Semaste
4253263363Semaste// <call-offset> ::= h <nv-offset> _
4254263363Semaste//               ::= v <v-offset> _
4255263363Semaste//
4256263363Semaste// <nv-offset> ::= <offset number>
4257263363Semaste//               # non-virtual base override
4258263363Semaste//
4259263363Semaste// <v-offset>  ::= <offset number> _ <virtual offset number>
4260263363Semaste//               # virtual base override, with vcall offset
4261263363Semaste
4262263363Semasteconst char*
4263263363Semasteparse_call_offset(const char* first, const char* last)
4264263363Semaste{
4265263363Semaste    if (first != last)
4266263363Semaste    {
4267263363Semaste        switch (*first)
4268263363Semaste        {
4269263363Semaste        case 'h':
4270263363Semaste            {
4271263363Semaste            const char* t = parse_number(first + 1, last);
4272263363Semaste            if (t != first + 1 && t != last && *t == '_')
4273263363Semaste                first = t + 1;
4274263363Semaste            }
4275263363Semaste            break;
4276263363Semaste        case 'v':
4277263363Semaste            {
4278263363Semaste            const char* t = parse_number(first + 1, last);
4279263363Semaste            if (t != first + 1 && t != last && *t == '_')
4280263363Semaste            {
4281263363Semaste                const char* t2 = parse_number(++t, last);
4282263363Semaste                if (t2 != t && t2 != last && *t2 == '_')
4283263363Semaste                    first = t2 + 1;
4284263363Semaste            }
4285263363Semaste            }
4286263363Semaste            break;
4287263363Semaste        }
4288263363Semaste    }
4289263363Semaste    return first;
4290263363Semaste}
4291263363Semaste
4292263363Semaste// <special-name> ::= TV <type>    # virtual table
4293263363Semaste//                ::= TT <type>    # VTT structure (construction vtable index)
4294263363Semaste//                ::= TI <type>    # typeinfo structure
4295263363Semaste//                ::= TS <type>    # typeinfo name (null-terminated byte string)
4296263363Semaste//                ::= Tc <call-offset> <call-offset> <base encoding>
4297263363Semaste//                    # base is the nominal target function of thunk
4298263363Semaste//                    # first call-offset is 'this' adjustment
4299263363Semaste//                    # second call-offset is result adjustment
4300263363Semaste//                ::= T <call-offset> <base encoding>
4301263363Semaste//                    # base is the nominal target function of thunk
4302263363Semaste//                ::= GV <object name> # Guard variable for one-time initialization
4303263363Semaste//                                     # No <type>
4304263363Semaste//      extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4305263363Semaste//      extension ::= GR <object name> # reference temporary for object
4306263363Semaste
4307263363Semastetemplate <class C>
4308263363Semasteconst char*
4309263363Semasteparse_special_name(const char* first, const char* last, C& db)
4310263363Semaste{
4311263363Semaste    if (last - first > 2)
4312263363Semaste    {
4313263363Semaste        const char* t;
4314263363Semaste        switch (*first)
4315263363Semaste        {
4316263363Semaste        case 'T':
4317263363Semaste            switch (first[1])
4318263363Semaste            {
4319263363Semaste            case 'V':
4320263363Semaste                // TV <type>    # virtual table
4321263363Semaste                t = parse_type(first+2, last, db);
4322263363Semaste                if (t != first+2)
4323263363Semaste                {
4324269024Semaste                    if (db.names.empty())
4325269024Semaste                        return first;
4326263363Semaste                    db.names.back().first.insert(0, "vtable for ");
4327263363Semaste                    first = t;
4328263363Semaste                }
4329263363Semaste                break;
4330263363Semaste            case 'T':
4331263363Semaste                // TT <type>    # VTT structure (construction vtable index)
4332263363Semaste                t = parse_type(first+2, last, db);
4333263363Semaste                if (t != first+2)
4334263363Semaste                {
4335269024Semaste                    if (db.names.empty())
4336269024Semaste                        return first;
4337263363Semaste                    db.names.back().first.insert(0, "VTT for ");
4338263363Semaste                    first = t;
4339263363Semaste                }
4340263363Semaste                break;
4341263363Semaste            case 'I':
4342263363Semaste                // TI <type>    # typeinfo structure
4343263363Semaste                t = parse_type(first+2, last, db);
4344263363Semaste                if (t != first+2)
4345263363Semaste                {
4346269024Semaste                    if (db.names.empty())
4347269024Semaste                        return first;
4348263363Semaste                    db.names.back().first.insert(0, "typeinfo for ");
4349263363Semaste                    first = t;
4350263363Semaste                }
4351263363Semaste                break;
4352263363Semaste            case 'S':
4353263363Semaste                // TS <type>    # typeinfo name (null-terminated byte string)
4354263363Semaste                t = parse_type(first+2, last, db);
4355263363Semaste                if (t != first+2)
4356263363Semaste                {
4357269024Semaste                    if (db.names.empty())
4358269024Semaste                        return first;
4359263363Semaste                    db.names.back().first.insert(0, "typeinfo name for ");
4360263363Semaste                    first = t;
4361263363Semaste                }
4362263363Semaste                break;
4363263363Semaste            case 'c':
4364263363Semaste                // Tc <call-offset> <call-offset> <base encoding>
4365263363Semaste              {
4366263363Semaste                const char* t0 = parse_call_offset(first+2, last);
4367263363Semaste                if (t0 == first+2)
4368263363Semaste                    break;
4369263363Semaste                const char* t1 = parse_call_offset(t0, last);
4370263363Semaste                if (t1 == t0)
4371263363Semaste                    break;
4372263363Semaste                t = parse_encoding(t1, last, db);
4373263363Semaste                if (t != t1)
4374263363Semaste                {
4375269024Semaste                    if (db.names.empty())
4376269024Semaste                        return first;
4377263363Semaste                    db.names.back().first.insert(0, "covariant return thunk to ");
4378263363Semaste                    first = t;
4379263363Semaste                }
4380263363Semaste              }
4381263363Semaste                break;
4382263363Semaste            case 'C':
4383263363Semaste                // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4384263363Semaste                t = parse_type(first+2, last, db);
4385263363Semaste                if (t != first+2)
4386263363Semaste                {
4387263363Semaste                    const char* t0 = parse_number(t, last);
4388263363Semaste                    if (t0 != t && t0 != last && *t0 == '_')
4389263363Semaste                    {
4390263363Semaste                        const char* t1 = parse_type(++t0, last, db);
4391263363Semaste                        if (t1 != t0)
4392263363Semaste                        {
4393269024Semaste                            if (db.names.size() < 2)
4394269024Semaste                                return first;
4395263363Semaste                            auto left = db.names.back().move_full();
4396263363Semaste                            db.names.pop_back();
4397263363Semaste                            db.names.back().first = "construction vtable for " +
4398263363Semaste                                                    std::move(left) + "-in-" +
4399263363Semaste                                                    db.names.back().move_full();
4400263363Semaste                            first = t1;
4401263363Semaste                        }
4402263363Semaste                    }
4403263363Semaste                }
4404263363Semaste                break;
4405263363Semaste            default:
4406263363Semaste                // T <call-offset> <base encoding>
4407263363Semaste                {
4408263363Semaste                const char* t0 = parse_call_offset(first+1, last);
4409263363Semaste                if (t0 == first+1)
4410263363Semaste                    break;
4411263363Semaste                t = parse_encoding(t0, last, db);
4412263363Semaste                if (t != t0)
4413263363Semaste                {
4414269024Semaste                    if (db.names.empty())
4415269024Semaste                        return first;
4416263363Semaste                    if (first[2] == 'v')
4417263363Semaste                    {
4418263363Semaste                        db.names.back().first.insert(0, "virtual thunk to ");
4419263363Semaste                        first = t;
4420263363Semaste                    }
4421263363Semaste                    else
4422263363Semaste                    {
4423263363Semaste                        db.names.back().first.insert(0, "non-virtual thunk to ");
4424263363Semaste                        first = t;
4425263363Semaste                    }
4426263363Semaste                }
4427263363Semaste                }
4428263363Semaste                break;
4429263363Semaste            }
4430263363Semaste            break;
4431263363Semaste        case 'G':
4432263363Semaste            switch (first[1])
4433263363Semaste            {
4434263363Semaste            case 'V':
4435263363Semaste                // GV <object name> # Guard variable for one-time initialization
4436263363Semaste                t = parse_name(first+2, last, db);
4437263363Semaste                if (t != first+2)
4438263363Semaste                {
4439269024Semaste                    if (db.names.empty())
4440269024Semaste                        return first;
4441263363Semaste                    db.names.back().first.insert(0, "guard variable for ");
4442263363Semaste                    first = t;
4443263363Semaste                }
4444263363Semaste                break;
4445263363Semaste            case 'R':
4446263363Semaste                // extension ::= GR <object name> # reference temporary for object
4447263363Semaste                t = parse_name(first+2, last, db);
4448263363Semaste                if (t != first+2)
4449263363Semaste                {
4450269024Semaste                    if (db.names.empty())
4451269024Semaste                        return first;
4452263363Semaste                    db.names.back().first.insert(0, "reference temporary for ");
4453263363Semaste                    first = t;
4454263363Semaste                }
4455263363Semaste                break;
4456263363Semaste            }
4457263363Semaste            break;
4458263363Semaste        }
4459263363Semaste    }
4460263363Semaste    return first;
4461263363Semaste}
4462263363Semaste
4463269024Semastetemplate <class T>
4464269024Semasteclass save_value
4465269024Semaste{
4466269024Semaste    T& restore_;
4467269024Semaste    T original_value_;
4468269024Semastepublic:
4469269024Semaste    save_value(T& restore)
4470269024Semaste        : restore_(restore),
4471269024Semaste          original_value_(restore)
4472269024Semaste        {}
4473269024Semaste
4474269024Semaste    ~save_value()
4475269024Semaste    {
4476269024Semaste        restore_ = std::move(original_value_);
4477269024Semaste    }
4478269024Semaste
4479269024Semaste    save_value(const save_value&) = delete;
4480269024Semaste    save_value& operator=(const save_value&) = delete;
4481269024Semaste};
4482269024Semaste
4483263363Semaste// <encoding> ::= <function name> <bare-function-type>
4484263363Semaste//            ::= <data name>
4485263363Semaste//            ::= <special-name>
4486263363Semaste
4487263363Semastetemplate <class C>
4488263363Semasteconst char*
4489263363Semasteparse_encoding(const char* first, const char* last, C& db)
4490263363Semaste{
4491263363Semaste    if (first != last)
4492263363Semaste    {
4493269024Semaste        save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
4494269024Semaste        ++db.encoding_depth;
4495269024Semaste        save_value<decltype(db.tag_templates)> sb(db.tag_templates);
4496269024Semaste        if (db.encoding_depth > 1)
4497269024Semaste            db.tag_templates = true;
4498263363Semaste        switch (*first)
4499263363Semaste        {
4500263363Semaste        case 'G':
4501263363Semaste        case 'T':
4502263363Semaste            first = parse_special_name(first, last, db);
4503263363Semaste            break;
4504263363Semaste        default:
4505263363Semaste          {
4506263363Semaste            const char* t = parse_name(first, last, db);
4507263363Semaste            unsigned cv = db.cv;
4508263363Semaste            unsigned ref = db.ref;
4509263363Semaste            if (t != first)
4510263363Semaste            {
4511263363Semaste                if (t != last && *t != 'E' && *t != '.')
4512263363Semaste                {
4513269024Semaste                    save_value<bool> sb2(db.tag_templates);
4514263363Semaste                    db.tag_templates = false;
4515263363Semaste                    const char* t2;
4516263363Semaste                    typename C::String ret2;
4517269024Semaste                    if (db.names.empty())
4518269024Semaste                        return first;
4519263363Semaste                    const typename C::String& nm = db.names.back().first;
4520269024Semaste                    if (nm.empty())
4521269024Semaste                        return first;
4522263363Semaste                    if (!db.parsed_ctor_dtor_cv && nm.back() == '>' && nm[nm.size()-2] != '-'
4523263363Semaste                                                                    && nm[nm.size()-2] != '>')
4524263363Semaste                    {
4525263363Semaste                        t2 = parse_type(t, last, db);
4526263363Semaste                        if (t2 == t)
4527263363Semaste                            return first;
4528269024Semaste                        if (db.names.size() < 2)
4529269024Semaste                            return first;
4530263363Semaste                        auto ret1 = std::move(db.names.back().first);
4531263363Semaste                        ret2 = std::move(db.names.back().second);
4532263363Semaste                        if (ret2.empty())
4533263363Semaste                            ret1 += ' ';
4534263363Semaste                        db.names.pop_back();
4535263363Semaste                        db.names.back().first.insert(0, ret1);
4536263363Semaste                        t = t2;
4537263363Semaste                    }
4538263363Semaste                    db.names.back().first += '(';
4539263363Semaste                    if (t != last && *t == 'v')
4540263363Semaste                    {
4541263363Semaste                        ++t;
4542263363Semaste                    }
4543263363Semaste                    else
4544263363Semaste                    {
4545263363Semaste                        bool first_arg = true;
4546263363Semaste                        while (true)
4547263363Semaste                        {
4548263363Semaste                            size_t k0 = db.names.size();
4549263363Semaste                            t2 = parse_type(t, last, db);
4550263363Semaste                            size_t k1 = db.names.size();
4551263363Semaste                            if (t2 == t)
4552263363Semaste                                break;
4553263363Semaste                            if (k1 > k0)
4554263363Semaste                            {
4555263363Semaste                                typename C::String tmp;
4556263363Semaste                                for (size_t k = k0; k < k1; ++k)
4557263363Semaste                                {
4558263363Semaste                                    if (!tmp.empty())
4559263363Semaste                                        tmp += ", ";
4560263363Semaste                                    tmp += db.names[k].move_full();
4561263363Semaste                                }
4562263363Semaste                                for (size_t k = k0; k < k1; ++k)
4563263363Semaste                                    db.names.pop_back();
4564263363Semaste                                if (!tmp.empty())
4565263363Semaste                                {
4566269024Semaste                                    if (db.names.empty())
4567269024Semaste                                        return first;
4568263363Semaste                                    if (!first_arg)
4569263363Semaste                                        db.names.back().first += ", ";
4570263363Semaste                                    else
4571263363Semaste                                        first_arg = false;
4572263363Semaste                                    db.names.back().first += tmp;
4573263363Semaste                                }
4574263363Semaste                            }
4575263363Semaste                            t = t2;
4576263363Semaste                        }
4577263363Semaste                    }
4578269024Semaste                    if (db.names.empty())
4579269024Semaste                        return first;
4580263363Semaste                    db.names.back().first += ')';
4581263363Semaste                    if (cv & 1)
4582263363Semaste                        db.names.back().first.append(" const");
4583263363Semaste                    if (cv & 2)
4584263363Semaste                        db.names.back().first.append(" volatile");
4585263363Semaste                    if (cv & 4)
4586263363Semaste                        db.names.back().first.append(" restrict");
4587263363Semaste                    if (ref == 1)
4588263363Semaste                        db.names.back().first.append(" &");
4589263363Semaste                    else if (ref == 2)
4590263363Semaste                        db.names.back().first.append(" &&");
4591263363Semaste                    db.names.back().first += ret2;
4592263363Semaste                    first = t;
4593263363Semaste                }
4594263363Semaste                else
4595263363Semaste                    first = t;
4596263363Semaste            }
4597263363Semaste            break;
4598263363Semaste          }
4599263363Semaste        }
4600263363Semaste    }
4601263363Semaste    return first;
4602263363Semaste}
4603263363Semaste
4604263363Semaste// _block_invoke
4605263363Semaste// _block_invoke<decimal-digit>+
4606263363Semaste// _block_invoke_<decimal-digit>+
4607263363Semaste
4608263363Semastetemplate <class C>
4609263363Semasteconst char*
4610263363Semasteparse_block_invoke(const char* first, const char* last, C& db)
4611263363Semaste{
4612263363Semaste    if (last - first >= 13)
4613263363Semaste    {
4614263363Semaste        const char test[] = "_block_invoke";
4615263363Semaste        const char* t = first;
4616263363Semaste        for (int i = 0; i < 13; ++i, ++t)
4617263363Semaste        {
4618263363Semaste            if (*t != test[i])
4619263363Semaste                return first;
4620263363Semaste        }
4621263363Semaste        if (t != last)
4622263363Semaste        {
4623263363Semaste            if (*t == '_')
4624263363Semaste            {
4625263363Semaste                // must have at least 1 decimal digit
4626263363Semaste                if (++t == last || !std::isdigit(*t))
4627263363Semaste                    return first;
4628263363Semaste                ++t;
4629263363Semaste            }
4630263363Semaste            // parse zero or more digits
4631263363Semaste            while (t != last && isdigit(*t))
4632263363Semaste                ++t;
4633263363Semaste        }
4634269024Semaste        if (db.names.empty())
4635269024Semaste            return first;
4636263363Semaste        db.names.back().first.insert(0, "invocation function for block in ");
4637263363Semaste        first = t;
4638263363Semaste    }
4639263363Semaste    return first;
4640263363Semaste}
4641263363Semaste
4642263363Semaste// extension
4643263363Semaste// <dot-suffix> := .<anything and everything>
4644263363Semaste
4645263363Semastetemplate <class C>
4646263363Semasteconst char*
4647263363Semasteparse_dot_suffix(const char* first, const char* last, C& db)
4648263363Semaste{
4649263363Semaste    if (first != last && *first == '.')
4650263363Semaste    {
4651269024Semaste        if (db.names.empty())
4652269024Semaste            return first;
4653263363Semaste        db.names.back().first += " (" + typename C::String(first, last) + ")";
4654263363Semaste        first = last;
4655263363Semaste    }
4656263363Semaste    return first;
4657263363Semaste}
4658263363Semaste
4659263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke
4660263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
4661263363Semaste// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
4662263363Semaste// <mangled-name> ::= _Z<encoding>
4663263363Semaste//                ::= <type>
4664263363Semaste
4665263363Semastetemplate <class C>
4666263363Semastevoid
4667263363Semastedemangle(const char* first, const char* last, C& db, int& status)
4668263363Semaste{
4669263363Semaste    if (first >= last)
4670263363Semaste    {
4671263363Semaste        status = invalid_mangled_name;
4672263363Semaste        return;
4673263363Semaste    }
4674263363Semaste    if (*first == '_')
4675263363Semaste    {
4676263363Semaste        if (last - first >= 4)
4677263363Semaste        {
4678263363Semaste            if (first[1] == 'Z')
4679263363Semaste            {
4680263363Semaste                const char* t = parse_encoding(first+2, last, db);
4681263363Semaste                if (t != first+2 && t != last && *t == '.')
4682263363Semaste                    t = parse_dot_suffix(t, last, db);
4683263363Semaste                if (t != last)
4684263363Semaste                    status = invalid_mangled_name;
4685263363Semaste            }
4686263363Semaste            else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
4687263363Semaste            {
4688263363Semaste                const char* t = parse_encoding(first+4, last, db);
4689263363Semaste                if (t != first+4 && t != last)
4690263363Semaste                {
4691263363Semaste                    const char* t1 = parse_block_invoke(t, last, db);
4692263363Semaste                    if (t1 != last)
4693263363Semaste                        status = invalid_mangled_name;
4694263363Semaste                }
4695263363Semaste                else
4696263363Semaste                    status = invalid_mangled_name;
4697263363Semaste            }
4698263363Semaste            else
4699263363Semaste                status = invalid_mangled_name;
4700263363Semaste        }
4701263363Semaste        else
4702263363Semaste            status = invalid_mangled_name;
4703263363Semaste    }
4704263363Semaste    else
4705263363Semaste    {
4706263363Semaste        const char* t = parse_type(first, last, db);
4707263363Semaste        if (t != last)
4708263363Semaste            status = invalid_mangled_name;
4709263363Semaste    }
4710263363Semaste    if (status == success && db.names.empty())
4711263363Semaste        status = invalid_mangled_name;
4712263363Semaste}
4713263363Semaste
4714263363Semastetemplate <std::size_t N>
4715263363Semasteclass arena
4716263363Semaste{
4717263363Semaste    static const std::size_t alignment = 16;
4718263363Semaste    alignas(alignment) char buf_[N];
4719263363Semaste    char* ptr_;
4720263363Semaste
4721263363Semaste    std::size_t
4722263363Semaste    align_up(std::size_t n) noexcept
4723263363Semaste        {return n + (alignment-1) & ~(alignment-1);}
4724263363Semaste
4725263363Semaste    bool
4726263363Semaste    pointer_in_buffer(char* p) noexcept
4727263363Semaste        {return buf_ <= p && p <= buf_ + N;}
4728263363Semaste
4729263363Semastepublic:
4730263363Semaste    arena() noexcept : ptr_(buf_) {}
4731263363Semaste    ~arena() {ptr_ = nullptr;}
4732263363Semaste    arena(const arena&) = delete;
4733263363Semaste    arena& operator=(const arena&) = delete;
4734263363Semaste
4735263363Semaste    char* allocate(std::size_t n);
4736263363Semaste    void deallocate(char* p, std::size_t n) noexcept;
4737263363Semaste
4738263363Semaste    static constexpr std::size_t size() {return N;}
4739263363Semaste    std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
4740263363Semaste    void reset() {ptr_ = buf_;}
4741263363Semaste};
4742263363Semaste
4743263363Semastetemplate <std::size_t N>
4744263363Semastechar*
4745263363Semastearena<N>::allocate(std::size_t n)
4746263363Semaste{
4747263363Semaste    n = align_up(n);
4748263363Semaste    if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
4749263363Semaste    {
4750263363Semaste        char* r = ptr_;
4751263363Semaste        ptr_ += n;
4752263363Semaste        return r;
4753263363Semaste    }
4754263363Semaste    return static_cast<char*>(std::malloc(n));
4755263363Semaste}
4756263363Semaste
4757263363Semastetemplate <std::size_t N>
4758263363Semastevoid
4759263363Semastearena<N>::deallocate(char* p, std::size_t n) noexcept
4760263363Semaste{
4761263363Semaste    if (pointer_in_buffer(p))
4762263363Semaste    {
4763263363Semaste        n = align_up(n);
4764263363Semaste        if (p + n == ptr_)
4765263363Semaste            ptr_ = p;
4766263363Semaste    }
4767263363Semaste    else
4768263363Semaste        std::free(p);
4769263363Semaste}
4770263363Semaste
4771263363Semastetemplate <class T, std::size_t N>
4772263363Semasteclass short_alloc
4773263363Semaste{
4774263363Semaste    arena<N>& a_;
4775263363Semastepublic:
4776263363Semaste    typedef T value_type;
4777263363Semaste
4778263363Semastepublic:
4779263363Semaste    template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
4780263363Semaste
4781263363Semaste    short_alloc(arena<N>& a) noexcept : a_(a) {}
4782263363Semaste    template <class U>
4783263363Semaste        short_alloc(const short_alloc<U, N>& a) noexcept
4784263363Semaste            : a_(a.a_) {}
4785263363Semaste    short_alloc(const short_alloc&) = default;
4786263363Semaste    short_alloc& operator=(const short_alloc&) = delete;
4787263363Semaste
4788263363Semaste    T* allocate(std::size_t n)
4789263363Semaste    {
4790263363Semaste        return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
4791263363Semaste    }
4792263363Semaste    void deallocate(T* p, std::size_t n) noexcept
4793263363Semaste    {
4794263363Semaste        a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
4795263363Semaste    }
4796263363Semaste
4797263363Semaste    template <class T1, std::size_t N1, class U, std::size_t M>
4798263363Semaste    friend
4799263363Semaste    bool
4800263363Semaste    operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
4801263363Semaste
4802263363Semaste    template <class U, std::size_t M> friend class short_alloc;
4803263363Semaste};
4804263363Semaste
4805263363Semastetemplate <class T, std::size_t N, class U, std::size_t M>
4806263363Semasteinline
4807263363Semastebool
4808263363Semasteoperator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
4809263363Semaste{
4810263363Semaste    return N == M && &x.a_ == &y.a_;
4811263363Semaste}
4812263363Semaste
4813263363Semastetemplate <class T, std::size_t N, class U, std::size_t M>
4814263363Semasteinline
4815263363Semastebool
4816263363Semasteoperator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
4817263363Semaste{
4818263363Semaste    return !(x == y);
4819263363Semaste}
4820263363Semaste
4821263363Semastetemplate <class T>
4822263363Semasteclass malloc_alloc
4823263363Semaste{
4824263363Semastepublic:
4825263363Semaste    typedef T value_type;
4826263363Semaste
4827263363Semaste    malloc_alloc() = default;
4828263363Semaste    template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {}
4829263363Semaste
4830263363Semaste    T* allocate(std::size_t n)
4831263363Semaste    {
4832263363Semaste        return static_cast<T*>(std::malloc(n*sizeof(T)));
4833263363Semaste    }
4834263363Semaste    void deallocate(T* p, std::size_t) noexcept
4835263363Semaste    {
4836263363Semaste        std::free(p);
4837263363Semaste    }
4838263363Semaste};
4839263363Semaste
4840263363Semastetemplate <class T, class U>
4841263363Semasteinline
4842263363Semastebool
4843263363Semasteoperator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept
4844263363Semaste{
4845263363Semaste    return true;
4846263363Semaste}
4847263363Semaste
4848263363Semastetemplate <class T, class U>
4849263363Semasteinline
4850263363Semastebool
4851263363Semasteoperator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept
4852263363Semaste{
4853263363Semaste    return !(x == y);
4854263363Semaste}
4855263363Semaste
4856263363Semasteconst size_t bs = 4 * 1024;
4857263363Semastetemplate <class T> using Alloc = short_alloc<T, bs>;
4858263363Semastetemplate <class T> using Vector = std::vector<T, Alloc<T>>;
4859263363Semasteusing String = std::basic_string<char, std::char_traits<char>, malloc_alloc<char>>;
4860263363Semaste
4861263363Semastestruct string_pair
4862263363Semaste{
4863263363Semaste    String first;
4864263363Semaste    String second;
4865263363Semaste
4866263363Semaste    string_pair() = default;
4867263363Semaste    string_pair(String f) : first(std::move(f)) {}
4868263363Semaste    string_pair(String f, String s)
4869263363Semaste        : first(std::move(f)), second(std::move(s)) {}
4870263363Semaste    template <size_t N>
4871263363Semaste        string_pair(const char (&s)[N]) : first(s, N-1) {}
4872263363Semaste
4873263363Semaste    size_t size() const {return first.size() + second.size();}
4874263363Semaste    String full() const {return first + second;}
4875263363Semaste    String move_full() {return std::move(first) + std::move(second);}
4876263363Semaste};
4877263363Semaste
4878263363Semastestruct Db
4879263363Semaste{
4880263363Semaste    typedef String String;
4881263363Semaste    typedef Vector<string_pair> sub_type;
4882263363Semaste    typedef Vector<sub_type> template_param_type;
4883263363Semaste    Vector<string_pair> names;
4884263363Semaste    Vector<sub_type> subs;
4885263363Semaste    Vector<template_param_type> template_param;
4886263363Semaste    unsigned cv;
4887263363Semaste    unsigned ref;
4888269024Semaste    unsigned encoding_depth;
4889263363Semaste    bool parsed_ctor_dtor_cv;
4890263363Semaste    bool tag_templates;
4891263363Semaste    bool fix_forward_references;
4892263363Semaste    bool try_to_parse_template_args;
4893263363Semaste
4894263363Semaste    template <size_t N>
4895263363Semaste    Db(arena<N>& ar) :
4896263363Semaste        names(ar),
4897263363Semaste        subs(0, names, ar),
4898263363Semaste        template_param(0, subs, ar)
4899263363Semaste    {}
4900263363Semaste};
4901263363Semaste
4902263363Semastechar*
4903263363Semaste__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
4904263363Semaste{
4905263363Semaste    if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
4906263363Semaste    {
4907263363Semaste        if (status)
4908263363Semaste            *status = invalid_args;
4909263363Semaste        return nullptr;
4910263363Semaste    }
4911263363Semaste    size_t internal_size = buf != nullptr ? *n : 0;
4912263363Semaste    arena<bs> a;
4913263363Semaste    Db db(a);
4914263363Semaste    db.cv = 0;
4915263363Semaste    db.ref = 0;
4916269024Semaste    db.encoding_depth = 0;
4917263363Semaste    db.parsed_ctor_dtor_cv = false;
4918263363Semaste    db.tag_templates = true;
4919263363Semaste    db.template_param.emplace_back(a);
4920263363Semaste    db.fix_forward_references = false;
4921263363Semaste    db.try_to_parse_template_args = true;
4922263363Semaste    int internal_status = success;
4923263363Semaste    size_t len = std::strlen(mangled_name);
4924263363Semaste    demangle(mangled_name, mangled_name + len, db,
4925263363Semaste             internal_status);
4926263363Semaste    if (internal_status == success && db.fix_forward_references &&
4927263363Semaste           !db.template_param.empty() && !db.template_param.front().empty())
4928263363Semaste    {
4929263363Semaste        db.fix_forward_references = false;
4930263363Semaste        db.tag_templates = false;
4931263363Semaste        db.names.clear();
4932263363Semaste        db.subs.clear();
4933263363Semaste        demangle(mangled_name, mangled_name + len, db, internal_status);
4934263363Semaste        if (db.fix_forward_references)
4935263363Semaste            internal_status = invalid_mangled_name;
4936263363Semaste    }
4937263363Semaste    if (internal_status == success)
4938263363Semaste    {
4939263363Semaste        size_t sz = db.names.back().size() + 1;
4940263363Semaste        if (sz > internal_size)
4941263363Semaste        {
4942263363Semaste            char* newbuf = static_cast<char*>(std::realloc(buf, sz));
4943263363Semaste            if (newbuf == nullptr)
4944263363Semaste            {
4945263363Semaste                internal_status = memory_alloc_failure;
4946263363Semaste                buf = nullptr;
4947263363Semaste            }
4948263363Semaste            else
4949263363Semaste            {
4950263363Semaste                buf = newbuf;
4951263363Semaste                if (n != nullptr)
4952263363Semaste                    *n = sz;
4953263363Semaste            }
4954263363Semaste        }
4955263363Semaste        if (buf != nullptr)
4956263363Semaste        {
4957263363Semaste            db.names.back().first += db.names.back().second;
4958263363Semaste            std::memcpy(buf, db.names.back().first.data(), sz-1);
4959263363Semaste            buf[sz-1] = char(0);
4960263363Semaste        }
4961263363Semaste    }
4962263363Semaste    else
4963263363Semaste        buf = nullptr;
4964263363Semaste    if (status)
4965263363Semaste        *status = internal_status;
4966263363Semaste    return buf;
4967263363Semaste}
4968263363Semaste
4969269024Semaste}
4970263363Semaste#endif
4971263363Semaste
4972263363Semaste
4973254721Semaste#include "llvm/ADT/DenseMap.h"
4974254721Semaste
4975254721Semaste#include "lldb/Core/ConstString.h"
4976254721Semaste#include "lldb/Core/Mangled.h"
4977254721Semaste#include "lldb/Core/RegularExpression.h"
4978254721Semaste#include "lldb/Core/Stream.h"
4979254721Semaste#include "lldb/Core/Timer.h"
4980254721Semaste#include <ctype.h>
4981254721Semaste#include <string.h>
4982254721Semaste#include <stdlib.h>
4983254721Semaste
4984254721Semasteusing namespace lldb_private;
4985254721Semaste
4986254721Semastestatic inline bool
4987254721Semastecstring_is_mangled (const char *s)
4988254721Semaste{
4989254721Semaste    if (s)
4990254721Semaste        return s[0] == '_' && s[1] == 'Z';
4991254721Semaste    return false;
4992254721Semaste}
4993254721Semaste
4994254721Semaste#pragma mark Mangled
4995254721Semaste//----------------------------------------------------------------------
4996254721Semaste// Default constructor
4997254721Semaste//----------------------------------------------------------------------
4998254721SemasteMangled::Mangled () :
4999254721Semaste    m_mangled(),
5000254721Semaste    m_demangled()
5001254721Semaste{
5002254721Semaste}
5003254721Semaste
5004254721Semaste//----------------------------------------------------------------------
5005254721Semaste// Constructor with an optional string and a boolean indicating if it is
5006254721Semaste// the mangled version.
5007254721Semaste//----------------------------------------------------------------------
5008254721SemasteMangled::Mangled (const ConstString &s, bool mangled) :
5009254721Semaste    m_mangled(),
5010254721Semaste    m_demangled()
5011254721Semaste{
5012254721Semaste    if (s)
5013254721Semaste        SetValue(s, mangled);
5014254721Semaste}
5015254721Semaste
5016254721SemasteMangled::Mangled (const ConstString &s) :
5017254721Semaste    m_mangled(),
5018254721Semaste    m_demangled()
5019254721Semaste{
5020254721Semaste    if (s)
5021254721Semaste        SetValue(s);
5022254721Semaste}
5023254721Semaste
5024254721Semaste//----------------------------------------------------------------------
5025254721Semaste// Destructor
5026254721Semaste//----------------------------------------------------------------------
5027254721SemasteMangled::~Mangled ()
5028254721Semaste{
5029254721Semaste}
5030254721Semaste
5031254721Semaste//----------------------------------------------------------------------
5032254721Semaste// Convert to pointer operator. This allows code to check any Mangled
5033254721Semaste// objects to see if they contain anything valid using code such as:
5034254721Semaste//
5035254721Semaste//  Mangled mangled(...);
5036254721Semaste//  if (mangled)
5037254721Semaste//  { ...
5038254721Semaste//----------------------------------------------------------------------
5039254721SemasteMangled::operator void* () const
5040254721Semaste{
5041254721Semaste    return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
5042254721Semaste}
5043254721Semaste
5044254721Semaste//----------------------------------------------------------------------
5045254721Semaste// Logical NOT operator. This allows code to check any Mangled
5046254721Semaste// objects to see if they are invalid using code such as:
5047254721Semaste//
5048254721Semaste//  Mangled mangled(...);
5049254721Semaste//  if (!file_spec)
5050254721Semaste//  { ...
5051254721Semaste//----------------------------------------------------------------------
5052254721Semastebool
5053254721SemasteMangled::operator! () const
5054254721Semaste{
5055254721Semaste    return !m_mangled;
5056254721Semaste}
5057254721Semaste
5058254721Semaste//----------------------------------------------------------------------
5059254721Semaste// Clear the mangled and demangled values.
5060254721Semaste//----------------------------------------------------------------------
5061254721Semastevoid
5062254721SemasteMangled::Clear ()
5063254721Semaste{
5064254721Semaste    m_mangled.Clear();
5065254721Semaste    m_demangled.Clear();
5066254721Semaste}
5067254721Semaste
5068254721Semaste
5069254721Semaste//----------------------------------------------------------------------
5070254721Semaste// Compare the the string values.
5071254721Semaste//----------------------------------------------------------------------
5072254721Semasteint
5073254721SemasteMangled::Compare (const Mangled& a, const Mangled& b)
5074254721Semaste{
5075254721Semaste    return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
5076254721Semaste}
5077254721Semaste
5078254721Semaste
5079254721Semaste
5080254721Semaste//----------------------------------------------------------------------
5081254721Semaste// Set the string value in this objects. If "mangled" is true, then
5082254721Semaste// the mangled named is set with the new value in "s", else the
5083254721Semaste// demangled name is set.
5084254721Semaste//----------------------------------------------------------------------
5085254721Semastevoid
5086254721SemasteMangled::SetValue (const ConstString &s, bool mangled)
5087254721Semaste{
5088254721Semaste    if (s)
5089254721Semaste    {
5090254721Semaste        if (mangled)
5091254721Semaste        {
5092254721Semaste            m_demangled.Clear();
5093254721Semaste            m_mangled = s;
5094254721Semaste        }
5095254721Semaste        else
5096254721Semaste        {
5097254721Semaste            m_demangled = s;
5098254721Semaste            m_mangled.Clear();
5099254721Semaste        }
5100254721Semaste    }
5101254721Semaste    else
5102254721Semaste    {
5103254721Semaste        m_demangled.Clear();
5104254721Semaste        m_mangled.Clear();
5105254721Semaste    }
5106254721Semaste}
5107254721Semaste
5108254721Semastevoid
5109254721SemasteMangled::SetValue (const ConstString &name)
5110254721Semaste{
5111254721Semaste    if (name)
5112254721Semaste    {
5113254721Semaste        if (cstring_is_mangled(name.GetCString()))
5114254721Semaste        {
5115254721Semaste            m_demangled.Clear();
5116254721Semaste            m_mangled = name;
5117254721Semaste        }
5118254721Semaste        else
5119254721Semaste        {
5120254721Semaste            m_demangled = name;
5121254721Semaste            m_mangled.Clear();
5122254721Semaste        }
5123254721Semaste    }
5124254721Semaste    else
5125254721Semaste    {
5126254721Semaste        m_demangled.Clear();
5127254721Semaste        m_mangled.Clear();
5128254721Semaste    }
5129254721Semaste}
5130254721Semaste
5131254721Semaste
5132254721Semaste//----------------------------------------------------------------------
5133254721Semaste// Generate the demangled name on demand using this accessor. Code in
5134254721Semaste// this class will need to use this accessor if it wishes to decode
5135254721Semaste// the demangled name. The result is cached and will be kept until a
5136254721Semaste// new string value is supplied to this object, or until the end of the
5137254721Semaste// object's lifetime.
5138254721Semaste//----------------------------------------------------------------------
5139254721Semasteconst ConstString&
5140254721SemasteMangled::GetDemangledName () const
5141254721Semaste{
5142254721Semaste    // Check to make sure we have a valid mangled name and that we
5143254721Semaste    // haven't already decoded our mangled name.
5144254721Semaste    if (m_mangled && !m_demangled)
5145254721Semaste    {
5146254721Semaste        // We need to generate and cache the demangled name.
5147254721Semaste        Timer scoped_timer (__PRETTY_FUNCTION__,
5148254721Semaste                            "Mangled::GetDemangledName (m_mangled = %s)",
5149254721Semaste                            m_mangled.GetCString());
5150254721Semaste
5151254721Semaste        // Don't bother running anything that isn't mangled
5152254721Semaste        const char *mangled_cstr = m_mangled.GetCString();
5153254721Semaste        if (cstring_is_mangled(mangled_cstr))
5154254721Semaste        {
5155254721Semaste            if (!m_mangled.GetMangledCounterpart(m_demangled))
5156254721Semaste            {
5157254721Semaste                // We didn't already mangle this name, demangle it and if all goes well
5158254721Semaste                // add it to our map.
5159263363Semaste#ifdef LLDB_USE_BUILTIN_DEMANGLER
5160263363Semaste                char *demangled_name = __cxa_demangle (mangled_cstr, NULL, NULL, NULL);
5161263367Semaste#elif defined(_MSC_VER)
5162263367Semaste                // Cannot demangle on msvc.
5163263367Semaste                char *demangled_name = nullptr;
5164263363Semaste#else
5165254721Semaste                char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
5166263363Semaste#endif
5167254721Semaste
5168254721Semaste                if (demangled_name)
5169254721Semaste                {
5170254721Semaste                    m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
5171254721Semaste                    free (demangled_name);
5172254721Semaste                }
5173254721Semaste            }
5174254721Semaste        }
5175254721Semaste        if (!m_demangled)
5176254721Semaste        {
5177254721Semaste            // Set the demangled string to the empty string to indicate we
5178254721Semaste            // tried to parse it once and failed.
5179254721Semaste            m_demangled.SetCString("");
5180254721Semaste        }
5181254721Semaste    }
5182254721Semaste
5183254721Semaste    return m_demangled;
5184254721Semaste}
5185254721Semaste
5186254721Semaste
5187254721Semastebool
5188254721SemasteMangled::NameMatches (const RegularExpression& regex) const
5189254721Semaste{
5190254721Semaste    if (m_mangled && regex.Execute (m_mangled.AsCString()))
5191254721Semaste        return true;
5192254721Semaste
5193254721Semaste    if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
5194254721Semaste        return true;
5195254721Semaste    return false;
5196254721Semaste}
5197254721Semaste
5198254721Semaste//----------------------------------------------------------------------
5199254721Semaste// Get the demangled name if there is one, else return the mangled name.
5200254721Semaste//----------------------------------------------------------------------
5201254721Semasteconst ConstString&
5202254721SemasteMangled::GetName (Mangled::NamePreference preference) const
5203254721Semaste{
5204254721Semaste    if (preference == ePreferDemangled)
5205254721Semaste    {
5206254721Semaste        // Call the accessor to make sure we get a demangled name in case
5207254721Semaste        // it hasn't been demangled yet...
5208254721Semaste        if (GetDemangledName())
5209254721Semaste            return m_demangled;
5210254721Semaste        return m_mangled;
5211254721Semaste    }
5212254721Semaste    else
5213254721Semaste    {
5214254721Semaste        if (m_mangled)
5215254721Semaste            return m_mangled;
5216254721Semaste        return GetDemangledName();
5217254721Semaste    }
5218254721Semaste}
5219254721Semaste
5220254721Semaste//----------------------------------------------------------------------
5221254721Semaste// Dump a Mangled object to stream "s". We don't force our
5222254721Semaste// demangled name to be computed currently (we don't use the accessor).
5223254721Semaste//----------------------------------------------------------------------
5224254721Semastevoid
5225254721SemasteMangled::Dump (Stream *s) const
5226254721Semaste{
5227254721Semaste    if (m_mangled)
5228254721Semaste    {
5229254721Semaste        *s << ", mangled = " << m_mangled;
5230254721Semaste    }
5231254721Semaste    if (m_demangled)
5232254721Semaste    {
5233254721Semaste        const char * demangled = m_demangled.AsCString();
5234254721Semaste        s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
5235254721Semaste    }
5236254721Semaste}
5237254721Semaste
5238254721Semaste//----------------------------------------------------------------------
5239254721Semaste// Dumps a debug version of this string with extra object and state
5240254721Semaste// information to stream "s".
5241254721Semaste//----------------------------------------------------------------------
5242254721Semastevoid
5243254721SemasteMangled::DumpDebug (Stream *s) const
5244254721Semaste{
5245254721Semaste    s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this);
5246254721Semaste    m_mangled.DumpDebug(s);
5247254721Semaste    s->Printf(", demangled = ");
5248254721Semaste    m_demangled.DumpDebug(s);
5249254721Semaste}
5250254721Semaste
5251254721Semaste//----------------------------------------------------------------------
5252254721Semaste// Return the size in byte that this object takes in memory. The size
5253254721Semaste// includes the size of the objects it owns, and not the strings that
5254254721Semaste// it references because they are shared strings.
5255254721Semaste//----------------------------------------------------------------------
5256254721Semastesize_t
5257254721SemasteMangled::MemorySize () const
5258254721Semaste{
5259254721Semaste    return m_mangled.MemorySize() + m_demangled.MemorySize();
5260254721Semaste}
5261254721Semaste
5262254721Semaste//----------------------------------------------------------------------
5263254721Semaste// Dump OBJ to the supplied stream S.
5264254721Semaste//----------------------------------------------------------------------
5265254721SemasteStream&
5266254721Semasteoperator << (Stream& s, const Mangled& obj)
5267254721Semaste{
5268254721Semaste    if (obj.GetMangledName())
5269254721Semaste        s << "mangled = '" << obj.GetMangledName() << "'";
5270254721Semaste
5271254721Semaste    const ConstString& demangled = obj.GetDemangledName();
5272254721Semaste    if (demangled)
5273254721Semaste        s << ", demangled = '" << demangled << '\'';
5274254721Semaste    else
5275254721Semaste        s << ", demangled = <error>";
5276254721Semaste    return s;
5277254721Semaste}
5278