blob: 402ee0c032a8824435b1183c1c12617ffcb388ee [file] [log] [blame]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001//===-------------------------- cxa_demangle.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant6c33e762013-06-17 18:10:34 +000010#define _LIBCPP_EXTERN_TEMPLATE(...)
11#define _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd213ffd2011-05-05 15:27:28 +000012
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +000013#include "__cxxabi_config.h"
14
Howard Hinnant6c33e762013-06-17 18:10:34 +000015#include <vector>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000016#include <algorithm>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000017#include <string>
Howard Hinnant6c33e762013-06-17 18:10:34 +000018#include <numeric>
19#include <cstdlib>
20#include <cstring>
21#include <cctype>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000022
Nico Weberb4c998b2015-09-20 18:10:46 +000023#ifdef _MSC_VER
24// snprintf is implemented in VS 2015
25#if _MSC_VER < 1900
26#define snprintf _snprintf_s
27#endif
28#endif
29
Howard Hinnantd213ffd2011-05-05 15:27:28 +000030namespace __cxxabiv1
31{
32
Howard Hinnant6c33e762013-06-17 18:10:34 +000033namespace
Howard Hinnantd213ffd2011-05-05 15:27:28 +000034{
35
Howard Hinnant6c33e762013-06-17 18:10:34 +000036enum
Howard Hinnantd213ffd2011-05-05 15:27:28 +000037{
Howard Hinnant6c33e762013-06-17 18:10:34 +000038 unknown_error = -4,
39 invalid_args = -3,
40 invalid_mangled_name,
41 memory_alloc_failure,
42 success
Howard Hinnantd213ffd2011-05-05 15:27:28 +000043};
44
Howard Hinnant6c33e762013-06-17 18:10:34 +000045template <class C>
46 const char* parse_type(const char* first, const char* last, C& db);
47template <class C>
48 const char* parse_encoding(const char* first, const char* last, C& db);
49template <class C>
Richard Smith24ecd092014-05-12 18:44:13 +000050 const char* parse_name(const char* first, const char* last, C& db,
51 bool* ends_with_template_args = 0);
Howard Hinnant6c33e762013-06-17 18:10:34 +000052template <class C>
53 const char* parse_expression(const char* first, const char* last, C& db);
54template <class C>
55 const char* parse_template_args(const char* first, const char* last, C& db);
56template <class C>
57 const char* parse_operator_name(const char* first, const char* last, C& db);
58template <class C>
59 const char* parse_unqualified_name(const char* first, const char* last, C& db);
60template <class C>
61 const char* parse_decltype(const char* first, const char* last, C& db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +000062
Howard Hinnant6c33e762013-06-17 18:10:34 +000063template <class C>
64void
65print_stack(const C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +000066{
Ed Schouten196cbd72015-03-19 09:17:21 +000067 fprintf(stderr, "---------\n");
68 fprintf(stderr, "names:\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000069 for (auto& s : db.names)
Ed Schouten196cbd72015-03-19 09:17:21 +000070 fprintf(stderr, "{%s#%s}\n", s.first.c_str(), s.second.c_str());
Howard Hinnant6c33e762013-06-17 18:10:34 +000071 int i = -1;
Ed Schouten196cbd72015-03-19 09:17:21 +000072 fprintf(stderr, "subs:\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000073 for (auto& v : db.subs)
Howard Hinnantd213ffd2011-05-05 15:27:28 +000074 {
Howard Hinnant6c33e762013-06-17 18:10:34 +000075 if (i >= 0)
Ed Schouten196cbd72015-03-19 09:17:21 +000076 fprintf(stderr, "S%i_ = {", i);
Howard Hinnant6c33e762013-06-17 18:10:34 +000077 else
Ed Schouten196cbd72015-03-19 09:17:21 +000078 fprintf(stderr, "S_ = {");
Howard Hinnant6c33e762013-06-17 18:10:34 +000079 for (auto& s : v)
Ed Schouten196cbd72015-03-19 09:17:21 +000080 fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
81 fprintf(stderr, "}\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000082 ++i;
Howard Hinnantd213ffd2011-05-05 15:27:28 +000083 }
Ed Schouten196cbd72015-03-19 09:17:21 +000084 fprintf(stderr, "template_param:\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000085 for (auto& t : db.template_param)
86 {
Ed Schouten196cbd72015-03-19 09:17:21 +000087 fprintf(stderr, "--\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000088 i = -1;
89 for (auto& v : t)
90 {
91 if (i >= 0)
Ed Schouten196cbd72015-03-19 09:17:21 +000092 fprintf(stderr, "T%i_ = {", i);
Howard Hinnant6c33e762013-06-17 18:10:34 +000093 else
Ed Schouten196cbd72015-03-19 09:17:21 +000094 fprintf(stderr, "T_ = {");
Howard Hinnant6c33e762013-06-17 18:10:34 +000095 for (auto& s : v)
Ed Schouten196cbd72015-03-19 09:17:21 +000096 fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
97 fprintf(stderr, "}\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +000098 ++i;
99 }
100 }
Ed Schouten196cbd72015-03-19 09:17:21 +0000101 fprintf(stderr, "---------\n\n");
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000102}
103
Howard Hinnant6c33e762013-06-17 18:10:34 +0000104template <class C>
105void
106print_state(const char* msg, const char* first, const char* last, const C& db)
Howard Hinnant5dd173b2013-04-10 19:44:03 +0000107{
Ed Schouten196cbd72015-03-19 09:17:21 +0000108 fprintf(stderr, "%s: ", msg);
Howard Hinnant6c33e762013-06-17 18:10:34 +0000109 for (; first != last; ++first)
Ed Schouten196cbd72015-03-19 09:17:21 +0000110 fprintf(stderr, "%c", *first);
111 fprintf(stderr, "\n");
Howard Hinnant6c33e762013-06-17 18:10:34 +0000112 print_stack(db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000113}
114
Howard Hinnant6c33e762013-06-17 18:10:34 +0000115// <number> ::= [n] <non-negative decimal integer>
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000116
117const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +0000118parse_number(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000119{
Howard Hinnant6c33e762013-06-17 18:10:34 +0000120 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000121 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000122 const char* t = first;
123 if (*t == 'n')
124 ++t;
125 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000126 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000127 if (*t == '0')
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000128 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000129 first = t+1;
130 }
131 else if ('1' <= *t && *t <= '9')
132 {
133 first = t+1;
134 while (first != last && std::isdigit(*first))
135 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000136 }
137 }
138 }
Howard Hinnant6c33e762013-06-17 18:10:34 +0000139 return first;
140}
141
142template <class Float>
143struct float_data;
144
145template <>
146struct float_data<float>
147{
148 static const size_t mangled_size = 8;
149 static const size_t max_demangled_size = 24;
Howard Hinnantc62cbea2013-06-17 20:25:21 +0000150 static constexpr const char* spec = "%af";
Howard Hinnant6c33e762013-06-17 18:10:34 +0000151};
152
153constexpr const char* float_data<float>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000154
155template <>
156struct float_data<double>
157{
158 static const size_t mangled_size = 16;
159 static const size_t max_demangled_size = 32;
160 static constexpr const char* spec = "%a";
Howard Hinnant6c33e762013-06-17 18:10:34 +0000161};
162
163constexpr const char* float_data<double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000164
165template <>
166struct float_data<long double>
167{
Dan Gohmand04ecd02016-01-13 16:39:30 +0000168#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
169 defined(__wasm__)
Daniel Sanders52cf98b2015-07-30 16:11:04 +0000170 static const size_t mangled_size = 32;
Ben Craig9ef2c6e2016-01-20 14:10:23 +0000171#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
Logan Chien05d51bc2014-05-10 00:42:10 +0000172 static const size_t mangled_size = 16;
173#else
Howard Hinnant6c33e762013-06-17 18:10:34 +0000174 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
Logan Chien05d51bc2014-05-10 00:42:10 +0000175#endif
Howard Hinnant6c33e762013-06-17 18:10:34 +0000176 static const size_t max_demangled_size = 40;
Howard Hinnantc62cbea2013-06-17 20:25:21 +0000177 static constexpr const char* spec = "%LaL";
Howard Hinnant6c33e762013-06-17 18:10:34 +0000178};
179
180constexpr const char* float_data<long double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000181
182template <class Float, class C>
183const char*
184parse_floating_number(const char* first, const char* last, C& db)
185{
186 const size_t N = float_data<Float>::mangled_size;
187 if (static_cast<std::size_t>(last - first) > N)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000188 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000189 last = first + N;
190 union
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000191 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000192 Float value;
193 char buf[sizeof(Float)];
194 };
195 const char* t = first;
196 char* e = buf;
197 for (; t != last; ++t, ++e)
198 {
199 if (!isxdigit(*t))
200 return first;
201 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
202 static_cast<unsigned>(*t - 'a' + 10);
203 ++t;
204 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
205 static_cast<unsigned>(*t - 'a' + 10);
206 *e = static_cast<char>((d1 << 4) + d0);
207 }
208 if (*t == 'E')
209 {
Saleem Abdulrasool2493be62015-04-27 02:21:52 +0000210#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
Howard Hinnant6c33e762013-06-17 18:10:34 +0000211 std::reverse(buf, e);
212#endif
213 char num[float_data<Float>::max_demangled_size] = {0};
Howard Hinnantc62cbea2013-06-17 20:25:21 +0000214 int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);
215 if (static_cast<std::size_t>(n) >= sizeof(num))
216 return first;
217 db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));
Howard Hinnant6c33e762013-06-17 18:10:34 +0000218 first = t+1;
219 }
220 }
221 return first;
222}
223
224// <source-name> ::= <positive length number> <identifier>
225
226template <class C>
227const char*
228parse_source_name(const char* first, const char* last, C& db)
229{
230 if (first != last)
231 {
232 char c = *first;
233 if (isdigit(c) && first+1 != last)
234 {
235 const char* t = first+1;
236 size_t n = static_cast<size_t>(c - '0');
237 for (c = *t; isdigit(c); c = *t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000238 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000239 n = n * 10 + static_cast<size_t>(c - '0');
240 if (++t == last)
241 return first;
242 }
243 if (static_cast<size_t>(last - t) >= n)
244 {
245 typename C::String r(t, n);
246 if (r.substr(0, 10) == "_GLOBAL__N")
247 db.names.push_back("(anonymous namespace)");
248 else
249 db.names.push_back(std::move(r));
250 first = t + n;
251 }
252 }
253 }
254 return first;
255}
256
257// <substitution> ::= S <seq-id> _
258// ::= S_
259// <substitution> ::= Sa # ::std::allocator
260// <substitution> ::= Sb # ::std::basic_string
261// <substitution> ::= Ss # ::std::basic_string < char,
262// ::std::char_traits<char>,
263// ::std::allocator<char> >
264// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
265// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
266// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
267
268template <class C>
269const char*
270parse_substitution(const char* first, const char* last, C& db)
271{
272 if (last - first >= 2)
273 {
274 if (*first == 'S')
275 {
276 switch (first[1])
277 {
278 case 'a':
279 db.names.push_back("std::allocator");
280 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000281 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000282 case 'b':
283 db.names.push_back("std::basic_string");
284 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000285 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000286 case 's':
287 db.names.push_back("std::string");
288 first += 2;
289 break;
290 case 'i':
291 db.names.push_back("std::istream");
292 first += 2;
293 break;
294 case 'o':
295 db.names.push_back("std::ostream");
296 first += 2;
297 break;
298 case 'd':
299 db.names.push_back("std::iostream");
300 first += 2;
301 break;
302 case '_':
303 if (!db.subs.empty())
304 {
305 for (const auto& n : db.subs.front())
306 db.names.push_back(n);
307 first += 2;
308 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000309 break;
310 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +0000311 if (std::isdigit(first[1]) || std::isupper(first[1]))
312 {
313 size_t sub = 0;
314 const char* t = first+1;
315 if (std::isdigit(*t))
316 sub = static_cast<size_t>(*t - '0');
317 else
318 sub = static_cast<size_t>(*t - 'A') + 10;
319 for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
320 {
321 sub *= 36;
322 if (std::isdigit(*t))
323 sub += static_cast<size_t>(*t - '0');
324 else
325 sub += static_cast<size_t>(*t - 'A') + 10;
326 }
327 if (t == last || *t != '_')
328 return first;
329 ++sub;
330 if (sub < db.subs.size())
331 {
332 for (const auto& n : db.subs[sub])
333 db.names.push_back(n);
334 first = t+1;
335 }
336 }
337 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000338 }
339 }
340 }
341 return first;
342}
343
344// <builtin-type> ::= v # void
345// ::= w # wchar_t
346// ::= b # bool
347// ::= c # char
348// ::= a # signed char
349// ::= h # unsigned char
350// ::= s # short
351// ::= t # unsigned short
352// ::= i # int
353// ::= j # unsigned int
354// ::= l # long
355// ::= m # unsigned long
356// ::= x # long long, __int64
357// ::= y # unsigned long long, __int64
358// ::= n # __int128
359// ::= o # unsigned __int128
360// ::= f # float
361// ::= d # double
362// ::= e # long double, __float80
363// ::= g # __float128
364// ::= z # ellipsis
365// ::= Dd # IEEE 754r decimal floating point (64 bits)
366// ::= De # IEEE 754r decimal floating point (128 bits)
367// ::= Df # IEEE 754r decimal floating point (32 bits)
368// ::= Dh # IEEE 754r half-precision floating point (16 bits)
369// ::= Di # char32_t
370// ::= Ds # char16_t
371// ::= Da # auto (in dependent new-expressions)
Anders Carlsson2950e562014-02-17 21:56:01 +0000372// ::= Dc # decltype(auto)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000373// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
374// ::= u <source-name> # vendor extended type
375
Howard Hinnant6c33e762013-06-17 18:10:34 +0000376template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000377const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +0000378parse_builtin_type(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000379{
380 if (first != last)
381 {
382 switch (*first)
383 {
384 case 'v':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000385 db.names.push_back("void");
386 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000387 break;
388 case 'w':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000389 db.names.push_back("wchar_t");
390 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000391 break;
392 case 'b':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000393 db.names.push_back("bool");
394 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000395 break;
396 case 'c':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000397 db.names.push_back("char");
398 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000399 break;
400 case 'a':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000401 db.names.push_back("signed char");
402 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000403 break;
404 case 'h':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000405 db.names.push_back("unsigned char");
406 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000407 break;
408 case 's':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000409 db.names.push_back("short");
410 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000411 break;
412 case 't':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000413 db.names.push_back("unsigned short");
414 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000415 break;
416 case 'i':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000417 db.names.push_back("int");
418 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000419 break;
420 case 'j':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000421 db.names.push_back("unsigned int");
422 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000423 break;
424 case 'l':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000425 db.names.push_back("long");
426 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000427 break;
428 case 'm':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000429 db.names.push_back("unsigned long");
430 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000431 break;
432 case 'x':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000433 db.names.push_back("long long");
434 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000435 break;
436 case 'y':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000437 db.names.push_back("unsigned long long");
438 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000439 break;
440 case 'n':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000441 db.names.push_back("__int128");
442 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000443 break;
444 case 'o':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000445 db.names.push_back("unsigned __int128");
446 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000447 break;
448 case 'f':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000449 db.names.push_back("float");
450 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000451 break;
452 case 'd':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000453 db.names.push_back("double");
454 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000455 break;
456 case 'e':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000457 db.names.push_back("long double");
458 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000459 break;
460 case 'g':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000461 db.names.push_back("__float128");
462 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000463 break;
464 case 'z':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000465 db.names.push_back("...");
466 ++first;
467 break;
468 case 'u':
469 {
470 const char*t = parse_source_name(first+1, last, db);
471 if (t != first+1)
472 first = t;
473 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000474 break;
475 case 'D':
476 if (first+1 != last)
477 {
478 switch (first[1])
479 {
480 case 'd':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000481 db.names.push_back("decimal64");
482 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000483 break;
484 case 'e':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000485 db.names.push_back("decimal128");
486 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000487 break;
488 case 'f':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000489 db.names.push_back("decimal32");
490 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000491 break;
492 case 'h':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000493 db.names.push_back("decimal16");
494 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000495 break;
496 case 'i':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000497 db.names.push_back("char32_t");
498 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000499 break;
500 case 's':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000501 db.names.push_back("char16_t");
502 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000503 break;
504 case 'a':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000505 db.names.push_back("auto");
506 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000507 break;
Anders Carlsson2950e562014-02-17 21:56:01 +0000508 case 'c':
509 db.names.push_back("decltype(auto)");
510 first += 2;
511 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000512 case 'n':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000513 db.names.push_back("std::nullptr_t");
514 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000515 break;
516 }
517 }
518 break;
519 }
520 }
521 return first;
522}
523
Howard Hinnant6c33e762013-06-17 18:10:34 +0000524// <CV-qualifiers> ::= [r] [V] [K]
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000525
526const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +0000527parse_cv_qualifiers(const char* first, const char* last, unsigned& cv)
528{
529 cv = 0;
530 if (first != last)
531 {
532 if (*first == 'r')
533 {
534 cv |= 4;
535 ++first;
536 }
537 if (*first == 'V')
538 {
539 cv |= 2;
540 ++first;
541 }
542 if (*first == 'K')
543 {
544 cv |= 1;
545 ++first;
546 }
547 }
548 return first;
549}
550
551// <template-param> ::= T_ # first template parameter
552// ::= T <parameter-2 non-negative number> _
553
554template <class C>
555const char*
556parse_template_param(const char* first, const char* last, C& db)
557{
558 if (last - first >= 2)
559 {
560 if (*first == 'T')
561 {
562 if (first[1] == '_')
563 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000564 if (db.template_param.empty())
565 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000566 if (!db.template_param.back().empty())
567 {
568 for (auto& t : db.template_param.back().front())
569 db.names.push_back(t);
570 first += 2;
571 }
572 else
573 {
Howard Hinnantb2d1f942013-06-23 19:52:45 +0000574 db.names.push_back("T_");
Howard Hinnant6c33e762013-06-17 18:10:34 +0000575 first += 2;
576 db.fix_forward_references = true;
577 }
578 }
579 else if (isdigit(first[1]))
580 {
581 const char* t = first+1;
582 size_t sub = static_cast<size_t>(*t - '0');
583 for (++t; t != last && isdigit(*t); ++t)
584 {
585 sub *= 10;
586 sub += static_cast<size_t>(*t - '0');
587 }
Howard Hinnant753a30d2013-12-11 19:44:25 +0000588 if (t == last || *t != '_' || db.template_param.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +0000589 return first;
590 ++sub;
591 if (sub < db.template_param.back().size())
592 {
593 for (auto& temp : db.template_param.back()[sub])
594 db.names.push_back(temp);
595 first = t+1;
596 }
597 else
598 {
Howard Hinnantb2d1f942013-06-23 19:52:45 +0000599 db.names.push_back(typename C::String(first, t+1));
Howard Hinnant6c33e762013-06-17 18:10:34 +0000600 first = t+1;
601 db.fix_forward_references = true;
602 }
603 }
604 }
605 }
606 return first;
607}
608
609// cc <type> <expression> # const_cast<type> (expression)
610
611template <class C>
612const char*
613parse_const_cast_expr(const char* first, const char* last, C& db)
614{
615 if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
616 {
617 const char* t = parse_type(first+2, last, db);
618 if (t != first+2)
619 {
620 const char* t1 = parse_expression(t, last, db);
621 if (t1 != t)
622 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000623 if (db.names.size() < 2)
624 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000625 auto expr = db.names.back().move_full();
626 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +0000627 if (db.names.empty())
628 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000629 db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
630 first = t1;
631 }
632 }
633 }
634 return first;
635}
636
637// dc <type> <expression> # dynamic_cast<type> (expression)
638
639template <class C>
640const char*
641parse_dynamic_cast_expr(const char* first, const char* last, C& db)
642{
643 if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')
644 {
645 const char* t = parse_type(first+2, last, db);
646 if (t != first+2)
647 {
648 const char* t1 = parse_expression(t, last, db);
649 if (t1 != t)
650 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000651 if (db.names.size() < 2)
652 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000653 auto expr = db.names.back().move_full();
654 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +0000655 if (db.names.empty())
656 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000657 db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";
658 first = t1;
659 }
660 }
661 }
662 return first;
663}
664
665// rc <type> <expression> # reinterpret_cast<type> (expression)
666
667template <class C>
668const char*
669parse_reinterpret_cast_expr(const char* first, const char* last, C& db)
670{
671 if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')
672 {
673 const char* t = parse_type(first+2, last, db);
674 if (t != first+2)
675 {
676 const char* t1 = parse_expression(t, last, db);
677 if (t1 != t)
678 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000679 if (db.names.size() < 2)
680 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000681 auto expr = db.names.back().move_full();
682 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +0000683 if (db.names.empty())
684 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000685 db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")";
686 first = t1;
687 }
688 }
689 }
690 return first;
691}
692
693// sc <type> <expression> # static_cast<type> (expression)
694
695template <class C>
696const char*
697parse_static_cast_expr(const char* first, const char* last, C& db)
698{
699 if (last - first >= 3 && first[0] == 's' && first[1] == 'c')
700 {
701 const char* t = parse_type(first+2, last, db);
702 if (t != first+2)
703 {
704 const char* t1 = parse_expression(t, last, db);
705 if (t1 != t)
706 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000707 if (db.names.size() < 2)
708 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000709 auto expr = db.names.back().move_full();
710 db.names.pop_back();
711 db.names.back() = "static_cast<" + db.names.back().move_full() + ">(" + expr + ")";
712 first = t1;
713 }
714 }
715 }
716 return first;
717}
718
719// sp <expression> # pack expansion
720
721template <class C>
722const char*
723parse_pack_expansion(const char* first, const char* last, C& db)
724{
725 if (last - first >= 3 && first[0] == 's' && first[1] == 'p')
726 {
727 const char* t = parse_expression(first+2, last, db);
728 if (t != first+2)
729 first = t;
730 }
731 return first;
732}
733
734// st <type> # sizeof (a type)
735
736template <class C>
737const char*
738parse_sizeof_type_expr(const char* first, const char* last, C& db)
739{
740 if (last - first >= 3 && first[0] == 's' && first[1] == 't')
741 {
742 const char* t = parse_type(first+2, last, db);
743 if (t != first+2)
744 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000745 if (db.names.empty())
746 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000747 db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
748 first = t;
749 }
750 }
751 return first;
752}
753
754// sz <expr> # sizeof (a expression)
755
756template <class C>
757const char*
758parse_sizeof_expr_expr(const char* first, const char* last, C& db)
759{
760 if (last - first >= 3 && first[0] == 's' && first[1] == 'z')
761 {
762 const char* t = parse_expression(first+2, last, db);
763 if (t != first+2)
764 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000765 if (db.names.empty())
766 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000767 db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
768 first = t;
769 }
770 }
771 return first;
772}
773
774// sZ <template-param> # size of a parameter pack
775
776template <class C>
777const char*
778parse_sizeof_param_pack_expr(const char* first, const char* last, C& db)
779{
780 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')
781 {
782 size_t k0 = db.names.size();
783 const char* t = parse_template_param(first+2, last, db);
784 size_t k1 = db.names.size();
785 if (t != first+2)
786 {
787 typename C::String tmp("sizeof...(");
788 size_t k = k0;
789 if (k != k1)
790 {
791 tmp += db.names[k].move_full();
792 for (++k; k != k1; ++k)
793 tmp += ", " + db.names[k].move_full();
794 }
795 tmp += ")";
796 for (; k1 != k0; --k1)
797 db.names.pop_back();
798 db.names.push_back(std::move(tmp));
799 first = t;
800 }
801 }
802 return first;
803}
804
805// <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter
806// ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
807// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _ # L > 0, first parameter
808// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
809
810template <class C>
811const char*
812parse_function_param(const char* first, const char* last, C& db)
813{
814 if (last - first >= 3 && *first == 'f')
815 {
816 if (first[1] == 'p')
817 {
818 unsigned cv;
819 const char* t = parse_cv_qualifiers(first+2, last, cv);
820 const char* t1 = parse_number(t, last);
821 if (t1 != last && *t1 == '_')
822 {
823 db.names.push_back("fp" + typename C::String(t, t1));
824 first = t1+1;
825 }
826 }
827 else if (first[1] == 'L')
828 {
829 unsigned cv;
830 const char* t0 = parse_number(first+2, last);
831 if (t0 != last && *t0 == 'p')
832 {
833 ++t0;
834 const char* t = parse_cv_qualifiers(t0, last, cv);
835 const char* t1 = parse_number(t, last);
836 if (t1 != last && *t1 == '_')
837 {
838 db.names.push_back("fp" + typename C::String(t, t1));
839 first = t1+1;
840 }
841 }
842 }
843 }
844 return first;
845}
846
847// sZ <function-param> # size of a function parameter pack
848
849template <class C>
850const char*
851parse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db)
852{
853 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')
854 {
855 const char* t = parse_function_param(first+2, last, db);
856 if (t != first+2)
857 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000858 if (db.names.empty())
859 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000860 db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
861 first = t;
862 }
863 }
864 return first;
865}
866
867// te <expression> # typeid (expression)
868// ti <type> # typeid (type)
869
870template <class C>
871const char*
872parse_typeid_expr(const char* first, const char* last, C& db)
873{
874 if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
875 {
876 const char* t;
877 if (first[1] == 'e')
878 t = parse_expression(first+2, last, db);
879 else
880 t = parse_type(first+2, last, db);
881 if (t != first+2)
882 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000883 if (db.names.empty())
884 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000885 db.names.back() = "typeid(" + db.names.back().move_full() + ")";
886 first = t;
887 }
888 }
889 return first;
890}
891
892// tw <expression> # throw expression
893
894template <class C>
895const char*
896parse_throw_expr(const char* first, const char* last, C& db)
897{
898 if (last - first >= 3 && first[0] == 't' && first[1] == 'w')
899 {
900 const char* t = parse_expression(first+2, last, db);
901 if (t != first+2)
902 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000903 if (db.names.empty())
904 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000905 db.names.back() = "throw " + db.names.back().move_full();
906 first = t;
907 }
908 }
909 return first;
910}
911
912// ds <expression> <expression> # expr.*expr
913
914template <class C>
915const char*
916parse_dot_star_expr(const char* first, const char* last, C& db)
917{
918 if (last - first >= 3 && first[0] == 'd' && first[1] == 's')
919 {
920 const char* t = parse_expression(first+2, last, db);
921 if (t != first+2)
922 {
923 const char* t1 = parse_expression(t, last, db);
924 if (t1 != t)
925 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000926 if (db.names.size() < 2)
927 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000928 auto expr = db.names.back().move_full();
929 db.names.pop_back();
930 db.names.back().first += ".*" + expr;
931 first = t1;
932 }
933 }
934 }
935 return first;
936}
937
938// <simple-id> ::= <source-name> [ <template-args> ]
939
940template <class C>
941const char*
942parse_simple_id(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000943{
944 if (first != last)
945 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000946 const char* t = parse_source_name(first, last, db);
947 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000948 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000949 const char* t1 = parse_template_args(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000950 if (t1 != t)
951 {
Howard Hinnant753a30d2013-12-11 19:44:25 +0000952 if (db.names.size() < 2)
953 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000954 auto args = db.names.back().move_full();
955 db.names.pop_back();
956 db.names.back().first += std::move(args);
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000957 }
Howard Hinnant6c33e762013-06-17 18:10:34 +0000958 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000959 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000960 else
Howard Hinnant6c33e762013-06-17 18:10:34 +0000961 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000962 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000963 return first;
964}
965
Howard Hinnant6c33e762013-06-17 18:10:34 +0000966// <unresolved-type> ::= <template-param>
967// ::= <decltype>
968// ::= <substitution>
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000969
Howard Hinnant6c33e762013-06-17 18:10:34 +0000970template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000971const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +0000972parse_unresolved_type(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000973{
Howard Hinnant6c33e762013-06-17 18:10:34 +0000974 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000975 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000976 const char* t = first;
977 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000978 {
Howard Hinnant86ccacd2012-09-13 23:49:59 +0000979 case 'T':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000980 {
981 size_t k0 = db.names.size();
982 t = parse_template_param(first, last, db);
983 size_t k1 = db.names.size();
984 if (t != first && k1 == k0 + 1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000985 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000986 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
987 first = t;
Howard Hinnantab039992012-08-01 18:56:46 +0000988 }
989 else
Howard Hinnant342f2f92012-11-30 18:43:50 +0000990 {
Howard Hinnant6c33e762013-06-17 18:10:34 +0000991 for (; k1 != k0; --k1)
992 db.names.pop_back();
Howard Hinnant342f2f92012-11-30 18:43:50 +0000993 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +0000994 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +0000995 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000996 case 'D':
Howard Hinnant6c33e762013-06-17 18:10:34 +0000997 t = parse_decltype(first, last, db);
998 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +0000999 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001000 if (db.names.empty())
1001 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001002 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1003 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001004 }
1005 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001006 case 'S':
1007 t = parse_substitution(first, last, db);
1008 if (t != first)
1009 first = t;
1010 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001011 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001012 if (last - first > 2 && first[1] == 't')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001013 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001014 t = parse_unqualified_name(first+2, last, db);
1015 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001016 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001017 if (db.names.empty())
1018 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001019 db.names.back().first.insert(0, "std::");
1020 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1021 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001022 }
1023 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001024 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001025 break;
1026 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001027 }
1028 return first;
1029}
1030
1031// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
1032// ::= <simple-id> # e.g., ~A<2*N>
1033
Howard Hinnant6c33e762013-06-17 18:10:34 +00001034template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001035const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001036parse_destructor_name(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001037{
1038 if (first != last)
1039 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001040 const char* t = parse_unresolved_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001041 if (t == first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001042 t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001043 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001044 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001045 if (db.names.empty())
1046 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001047 db.names.back().first.insert(0, "~");
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001048 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001049 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001050 }
1051 return first;
1052}
1053
1054// <base-unresolved-name> ::= <simple-id> # unresolved name
1055// extension ::= <operator-name> # unresolved operator-function-id
1056// extension ::= <operator-name> <template-args> # unresolved operator template-id
1057// ::= on <operator-name> # unresolved operator-function-id
1058// ::= on <operator-name> <template-args> # unresolved operator template-id
1059// ::= dn <destructor-name> # destructor or pseudo-destructor;
1060// # e.g. ~X or ~X<N-1>
1061
Howard Hinnant6c33e762013-06-17 18:10:34 +00001062template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001063const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001064parse_base_unresolved_name(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001065{
1066 if (last - first >= 2)
1067 {
1068 if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
1069 {
1070 if (first[0] == 'o')
1071 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001072 const char* t = parse_operator_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001073 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001074 {
1075 first = parse_template_args(t, last, db);
1076 if (first != t)
1077 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001078 if (db.names.size() < 2)
1079 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001080 auto args = db.names.back().move_full();
1081 db.names.pop_back();
1082 db.names.back().first += std::move(args);
1083 }
1084 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001085 }
1086 else
1087 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001088 const char* t = parse_destructor_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001089 if (t != first+2)
1090 first = t;
1091 }
1092 }
1093 else
1094 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001095 const char* t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001096 if (t == first)
1097 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001098 t = parse_operator_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001099 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001100 {
1101 first = parse_template_args(t, last, db);
1102 if (first != t)
1103 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001104 if (db.names.size() < 2)
1105 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001106 auto args = db.names.back().move_full();
1107 db.names.pop_back();
1108 db.names.back().first += std::move(args);
1109 }
1110 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001111 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001112 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001113 first = t;
1114 }
1115 }
1116 return first;
1117}
1118
Howard Hinnant6c33e762013-06-17 18:10:34 +00001119// <unresolved-qualifier-level> ::= <simple-id>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001120
Howard Hinnant6c33e762013-06-17 18:10:34 +00001121template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001122const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001123parse_unresolved_qualifier_level(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001124{
Howard Hinnant6c33e762013-06-17 18:10:34 +00001125 return parse_simple_id(first, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00001126}
1127
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001128// <unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00001129// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001130// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
1131// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
1132// # A::x, N::y, A<T>::z; "gs" means leading "::"
Howard Hinnant889b02d2011-06-22 19:27:39 +00001133// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
Howard Hinnant6c33e762013-06-17 18:10:34 +00001134// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00001135// # T::N::x /decltype(p)::N::x
1136// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001137
Howard Hinnant6c33e762013-06-17 18:10:34 +00001138template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001139const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001140parse_unresolved_name(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001141{
1142 if (last - first > 2)
1143 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00001144 const char* t = first;
1145 bool global = false;
1146 if (t[0] == 'g' && t[1] == 's')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001147 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00001148 global = true;
1149 t += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001150 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001151 const char* t2 = parse_base_unresolved_name(t, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00001152 if (t2 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001153 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001154 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00001155 {
1156 if (db.names.empty())
1157 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001158 db.names.back().first.insert(0, "::");
Howard Hinnant753a30d2013-12-11 19:44:25 +00001159 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001160 first = t2;
Howard Hinnant889b02d2011-06-22 19:27:39 +00001161 }
1162 else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
1163 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001164 if (t[2] == 'N')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001165 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001166 t += 3;
1167 const char* t1 = parse_unresolved_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001168 if (t1 == t || t1 == last)
1169 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001170 t = t1;
1171 t1 = parse_template_args(t, last, db);
1172 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001173 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001174 if (db.names.size() < 2)
1175 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001176 auto args = db.names.back().move_full();
1177 db.names.pop_back();
1178 db.names.back().first += std::move(args);
1179 t = t1;
1180 if (t == last)
1181 {
1182 db.names.pop_back();
1183 return first;
1184 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001185 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001186 while (*t != 'E')
1187 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001188 t1 = parse_unresolved_qualifier_level(t, last, db);
Howard Hinnant753a30d2013-12-11 19:44:25 +00001189 if (t1 == t || t1 == last || db.names.size() < 2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001190 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001191 auto s = db.names.back().move_full();
1192 db.names.pop_back();
1193 db.names.back().first += "::" + std::move(s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001194 t = t1;
1195 }
1196 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001197 t1 = parse_base_unresolved_name(t, last, db);
1198 if (t1 == t)
1199 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001200 if (!db.names.empty())
1201 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00001202 return first;
1203 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001204 if (db.names.size() < 2)
1205 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001206 auto s = db.names.back().move_full();
1207 db.names.pop_back();
1208 db.names.back().first += "::" + std::move(s);
1209 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001210 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001211 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001212 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001213 t += 2;
1214 const char* t1 = parse_unresolved_type(t, last, db);
1215 if (t1 != t)
1216 {
1217 t = t1;
1218 t1 = parse_template_args(t, last, db);
1219 if (t1 != t)
1220 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001221 if (db.names.size() < 2)
1222 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001223 auto args = db.names.back().move_full();
1224 db.names.pop_back();
1225 db.names.back().first += std::move(args);
1226 t = t1;
1227 }
1228 t1 = parse_base_unresolved_name(t, last, db);
1229 if (t1 == t)
1230 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001231 if (!db.names.empty())
1232 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00001233 return first;
1234 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001235 if (db.names.size() < 2)
1236 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001237 auto s = db.names.back().move_full();
1238 db.names.pop_back();
1239 db.names.back().first += "::" + std::move(s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001240 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001241 }
1242 else
1243 {
1244 t1 = parse_unresolved_qualifier_level(t, last, db);
1245 if (t1 == t || t1 == last)
1246 return first;
1247 t = t1;
1248 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00001249 {
1250 if (db.names.empty())
1251 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001252 db.names.back().first.insert(0, "::");
Howard Hinnant753a30d2013-12-11 19:44:25 +00001253 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001254 while (*t != 'E')
1255 {
1256 t1 = parse_unresolved_qualifier_level(t, last, db);
Howard Hinnant753a30d2013-12-11 19:44:25 +00001257 if (t1 == t || t1 == last || db.names.size() < 2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001258 return first;
1259 auto s = db.names.back().move_full();
1260 db.names.pop_back();
1261 db.names.back().first += "::" + std::move(s);
1262 t = t1;
1263 }
1264 ++t;
1265 t1 = parse_base_unresolved_name(t, last, db);
1266 if (t1 == t)
1267 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001268 if (!db.names.empty())
1269 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00001270 return first;
1271 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001272 if (db.names.size() < 2)
1273 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001274 auto s = db.names.back().move_full();
1275 db.names.pop_back();
1276 db.names.back().first += "::" + std::move(s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001277 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001278 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001279 }
1280 }
1281 }
1282 return first;
1283}
1284
1285// dt <expression> <unresolved-name> # expr.name
1286
Howard Hinnant6c33e762013-06-17 18:10:34 +00001287template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001288const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001289parse_dot_expr(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001290{
1291 if (last - first >= 3 && first[0] == 'd' && first[1] == 't')
1292 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001293 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001294 if (t != first+2)
1295 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001296 const char* t1 = parse_unresolved_name(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001297 if (t1 != t)
1298 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001299 if (db.names.size() < 2)
1300 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001301 auto name = db.names.back().move_full();
1302 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00001303 if (db.names.empty())
1304 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001305 db.names.back().first += "." + name;
1306 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001307 }
1308 }
1309 }
1310 return first;
1311}
1312
Howard Hinnant6c33e762013-06-17 18:10:34 +00001313// cl <expression>+ E # call
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001314
Howard Hinnant6c33e762013-06-17 18:10:34 +00001315template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001316const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001317parse_call_expr(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001318{
Howard Hinnant6c33e762013-06-17 18:10:34 +00001319 if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001320 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001321 const char* t = parse_expression(first+2, last, db);
1322 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001323 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001324 if (t == last)
1325 return first;
Howard Hinnant753a30d2013-12-11 19:44:25 +00001326 if (db.names.empty())
1327 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001328 db.names.back().first += db.names.back().second;
1329 db.names.back().second = typename C::String();
1330 db.names.back().first.append("(");
1331 bool first_expr = true;
1332 while (*t != 'E')
1333 {
1334 const char* t1 = parse_expression(t, last, db);
1335 if (t1 == t || t1 == last)
1336 return first;
Howard Hinnant753a30d2013-12-11 19:44:25 +00001337 if (db.names.empty())
1338 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001339 auto tmp = db.names.back().move_full();
1340 db.names.pop_back();
1341 if (!tmp.empty())
1342 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001343 if (db.names.empty())
1344 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001345 if (!first_expr)
1346 {
1347 db.names.back().first.append(", ");
1348 first_expr = false;
1349 }
1350 db.names.back().first.append(tmp);
1351 }
1352 t = t1;
1353 }
1354 ++t;
Howard Hinnant753a30d2013-12-11 19:44:25 +00001355 if (db.names.empty())
1356 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001357 db.names.back().first.append(")");
1358 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001359 }
1360 }
1361 return first;
1362}
1363
1364// [gs] nw <expression>* _ <type> E # new (expr-list) type
1365// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
1366// [gs] na <expression>* _ <type> E # new[] (expr-list) type
1367// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
1368// <initializer> ::= pi <expression>* E # parenthesized initialization
1369
Howard Hinnant6c33e762013-06-17 18:10:34 +00001370template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001371const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001372parse_new_expr(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001373{
1374 if (last - first >= 4)
1375 {
1376 const char* t = first;
1377 bool parsed_gs = false;
1378 if (t[0] == 'g' && t[1] == 's')
1379 {
1380 t += 2;
1381 parsed_gs = true;
1382 }
1383 if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))
1384 {
1385 bool is_array = t[1] == 'a';
1386 t += 2;
1387 if (t == last)
1388 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001389 bool has_expr_list = false;
1390 bool first_expr = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001391 while (*t != '_')
1392 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001393 const char* t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001394 if (t1 == t || t1 == last)
1395 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001396 has_expr_list = true;
1397 if (!first_expr)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001398 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001399 if (db.names.empty())
1400 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001401 auto tmp = db.names.back().move_full();
1402 db.names.pop_back();
1403 if (!tmp.empty())
1404 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001405 if (db.names.empty())
1406 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001407 db.names.back().first.append(", ");
1408 db.names.back().first.append(tmp);
1409 first_expr = false;
1410 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001411 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001412 t = t1;
1413 }
1414 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001415 const char* t1 = parse_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001416 if (t1 == t || t1 == last)
1417 return first;
1418 t = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001419 bool has_init = false;
1420 if (last - t >= 3 && t[0] == 'p' && t[1] == 'i')
1421 {
1422 t += 2;
1423 has_init = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001424 first_expr = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001425 while (*t != 'E')
1426 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001427 t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001428 if (t1 == t || t1 == last)
1429 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001430 if (!first_expr)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001431 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001432 if (db.names.empty())
1433 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001434 auto tmp = db.names.back().move_full();
1435 db.names.pop_back();
1436 if (!tmp.empty())
1437 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001438 if (db.names.empty())
1439 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001440 db.names.back().first.append(", ");
1441 db.names.back().first.append(tmp);
1442 first_expr = false;
1443 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001444 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001445 t = t1;
1446 }
1447 }
1448 if (*t != 'E')
1449 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001450 typename C::String init_list;
1451 if (has_init)
1452 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001453 if (db.names.empty())
1454 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001455 init_list = db.names.back().move_full();
1456 db.names.pop_back();
1457 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001458 if (db.names.empty())
1459 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001460 auto type = db.names.back().move_full();
1461 db.names.pop_back();
1462 typename C::String expr_list;
1463 if (has_expr_list)
1464 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001465 if (db.names.empty())
1466 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001467 expr_list = db.names.back().move_full();
1468 db.names.pop_back();
1469 }
1470 typename C::String r;
1471 if (parsed_gs)
1472 r = "::";
1473 if (is_array)
1474 r += "[] ";
1475 else
1476 r += " ";
1477 if (has_expr_list)
1478 r += "(" + expr_list + ") ";
1479 r += type;
1480 if (has_init)
1481 r += " (" + init_list + ")";
1482 db.names.push_back(std::move(r));
1483 first = t+1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001484 }
1485 }
1486 return first;
1487}
1488
Howard Hinnant6c33e762013-06-17 18:10:34 +00001489// cv <type> <expression> # conversion with one argument
1490// cv <type> _ <expression>* E # conversion with a different number of arguments
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001491
Howard Hinnant6c33e762013-06-17 18:10:34 +00001492template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001493const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001494parse_conversion_expr(const char* first, const char* last, C& db)
1495{
1496 if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
1497 {
1498 bool try_to_parse_template_args = db.try_to_parse_template_args;
1499 db.try_to_parse_template_args = false;
1500 const char* t = parse_type(first+2, last, db);
1501 db.try_to_parse_template_args = try_to_parse_template_args;
1502 if (t != first+2 && t != last)
1503 {
1504 if (*t != '_')
1505 {
1506 const char* t1 = parse_expression(t, last, db);
1507 if (t1 == t)
1508 return first;
1509 t = t1;
1510 }
1511 else
1512 {
1513 ++t;
1514 if (t == last)
1515 return first;
1516 if (*t == 'E')
1517 db.names.emplace_back();
1518 else
1519 {
1520 bool first_expr = true;
1521 while (*t != 'E')
1522 {
1523 const char* t1 = parse_expression(t, last, db);
1524 if (t1 == t || t1 == last)
1525 return first;
1526 if (!first_expr)
1527 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001528 if (db.names.empty())
1529 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001530 auto tmp = db.names.back().move_full();
1531 db.names.pop_back();
1532 if (!tmp.empty())
1533 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001534 if (db.names.empty())
1535 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001536 db.names.back().first.append(", ");
1537 db.names.back().first.append(tmp);
1538 first_expr = false;
1539 }
1540 }
1541 t = t1;
1542 }
1543 }
1544 ++t;
1545 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001546 if (db.names.size() < 2)
1547 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001548 auto tmp = db.names.back().move_full();
1549 db.names.pop_back();
1550 db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
1551 first = t;
1552 }
1553 }
1554 return first;
1555}
1556
1557// pt <expression> <expression> # expr->name
1558
1559template <class C>
1560const char*
1561parse_arrow_expr(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001562{
1563 if (last - first >= 3 && first[0] == 'p' && first[1] == 't')
1564 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001565 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001566 if (t != first+2)
1567 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001568 const char* t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001569 if (t1 != t)
1570 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001571 if (db.names.size() < 2)
1572 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001573 auto tmp = db.names.back().move_full();
1574 db.names.pop_back();
1575 db.names.back().first += "->";
1576 db.names.back().first += tmp;
1577 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001578 }
1579 }
1580 }
1581 return first;
1582}
1583
Howard Hinnant6c33e762013-06-17 18:10:34 +00001584// <ref-qualifier> ::= R # & ref-qualifier
1585// <ref-qualifier> ::= O # && ref-qualifier
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001586
Howard Hinnant6c33e762013-06-17 18:10:34 +00001587// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
1588
1589template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001590const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001591parse_function_type(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001592{
Howard Hinnant6c33e762013-06-17 18:10:34 +00001593 if (first != last && *first == 'F')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001594 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001595 const char* t = first+1;
1596 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001597 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001598 if (*t == 'Y')
1599 {
Saleem Abdulrasoolb2cceca2015-04-27 02:21:57 +00001600 /* extern "C" */
Howard Hinnant6c33e762013-06-17 18:10:34 +00001601 if (++t == last)
1602 return first;
1603 }
1604 const char* t1 = parse_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001605 if (t1 != t)
1606 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001607 t = t1;
1608 typename C::String sig("(");
1609 int ref_qual = 0;
1610 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001611 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001612 if (t == last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001613 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001614 db.names.pop_back();
1615 return first;
1616 }
1617 if (*t == 'E')
1618 {
1619 ++t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001620 break;
1621 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001622 if (*t == 'v')
1623 {
1624 ++t;
1625 continue;
1626 }
1627 if (*t == 'R' && t+1 != last && t[1] == 'E')
1628 {
1629 ref_qual = 1;
1630 ++t;
1631 continue;
1632 }
1633 if (*t == 'O' && t+1 != last && t[1] == 'E')
1634 {
1635 ref_qual = 2;
1636 ++t;
1637 continue;
1638 }
1639 size_t k0 = db.names.size();
1640 t1 = parse_type(t, last, db);
1641 size_t k1 = db.names.size();
1642 if (t1 == t || t1 == last)
1643 return first;
1644 for (size_t k = k0; k < k1; ++k)
1645 {
1646 if (sig.size() > 1)
1647 sig += ", ";
1648 sig += db.names[k].move_full();
1649 }
1650 for (size_t k = k0; k < k1; ++k)
1651 db.names.pop_back();
1652 t = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001653 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001654 sig += ")";
1655 switch (ref_qual)
1656 {
1657 case 1:
1658 sig += " &";
1659 break;
1660 case 2:
1661 sig += " &&";
1662 break;
1663 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00001664 if (db.names.empty())
1665 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001666 db.names.back().first += " ";
1667 db.names.back().second.insert(0, sig);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001668 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001669 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001670 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001671 }
1672 return first;
1673}
1674
1675// <pointer-to-member-type> ::= M <class type> <member type>
1676
1677template <class C>
1678const char*
1679parse_pointer_to_member_type(const char* first, const char* last, C& db)
1680{
1681 if (first != last && *first == 'M')
1682 {
1683 const char* t = parse_type(first+1, last, db);
1684 if (t != first+1)
1685 {
1686 const char* t2 = parse_type(t, last, db);
1687 if (t2 != t)
1688 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001689 if (db.names.size() < 2)
1690 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001691 auto func = std::move(db.names.back());
1692 db.names.pop_back();
1693 auto class_type = std::move(db.names.back());
Chaoren Lin3b8762a2015-05-26 23:14:26 +00001694 if (!func.second.empty() && func.second.front() == '(')
Howard Hinnant6c33e762013-06-17 18:10:34 +00001695 {
1696 db.names.back().first = std::move(func.first) + "(" + class_type.move_full() + "::*";
1697 db.names.back().second = ")" + std::move(func.second);
1698 }
1699 else
1700 {
1701 db.names.back().first = std::move(func.first) + " " + class_type.move_full() + "::*";
1702 db.names.back().second = std::move(func.second);
1703 }
1704 first = t2;
1705 }
1706 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001707 }
1708 return first;
1709}
1710
1711// <array-type> ::= A <positive dimension number> _ <element type>
1712// ::= A [<dimension expression>] _ <element type>
1713
Howard Hinnant6c33e762013-06-17 18:10:34 +00001714template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001715const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001716parse_array_type(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001717{
1718 if (first != last && *first == 'A' && first+1 != last)
1719 {
1720 if (first[1] == '_')
1721 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001722 const char* t = parse_type(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001723 if (t != first+2)
1724 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001725 if (db.names.empty())
1726 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001727 if (db.names.back().second.substr(0, 2) == " [")
1728 db.names.back().second.erase(0, 1);
1729 db.names.back().second.insert(0, " []");
1730 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001731 }
1732 }
1733 else if ('1' <= first[1] && first[1] <= '9')
1734 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001735 const char* t = parse_number(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001736 if (t != last && *t == '_')
1737 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001738 const char* t2 = parse_type(t+1, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001739 if (t2 != t+1)
1740 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001741 if (db.names.empty())
1742 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001743 if (db.names.back().second.substr(0, 2) == " [")
1744 db.names.back().second.erase(0, 1);
1745 db.names.back().second.insert(0, " [" + typename C::String(first+1, t) + "]");
1746 first = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001747 }
1748 }
1749 }
1750 else
1751 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001752 const char* t = parse_expression(first+1, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001753 if (t != first+1 && t != last && *t == '_')
1754 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001755 const char* t2 = parse_type(++t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001756 if (t2 != t)
1757 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001758 if (db.names.size() < 2)
1759 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001760 auto type = std::move(db.names.back());
1761 db.names.pop_back();
1762 auto expr = std::move(db.names.back());
1763 db.names.back().first = std::move(type.first);
1764 if (type.second.substr(0, 2) == " [")
1765 type.second.erase(0, 1);
1766 db.names.back().second = " [" + expr.move_full() + "]" + std::move(type.second);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001767 first = t2;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001768 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001769 }
1770 }
1771 }
1772 return first;
1773}
1774
1775// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
1776// ::= DT <expression> E # decltype of an expression (C++0x)
1777
Howard Hinnant6c33e762013-06-17 18:10:34 +00001778template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001779const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001780parse_decltype(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001781{
1782 if (last - first >= 4 && first[0] == 'D')
1783 {
1784 switch (first[1])
1785 {
1786 case 't':
1787 case 'T':
1788 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001789 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001790 if (t != first+2 && t != last && *t == 'E')
1791 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001792 if (db.names.empty())
1793 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001794 db.names.back() = "decltype(" + db.names.back().move_full() + ")";
1795 first = t+1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001796 }
1797 }
1798 break;
1799 }
1800 }
1801 return first;
1802}
1803
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001804// extension:
1805// <vector-type> ::= Dv <positive dimension number> _
1806// <extended element type>
1807// ::= Dv [<dimension expression>] _ <element type>
1808// <extended element type> ::= <element type>
1809// ::= p # AltiVec vector pixel
1810
Howard Hinnant6c33e762013-06-17 18:10:34 +00001811template <class C>
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001812const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001813parse_vector_type(const char* first, const char* last, C& db)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001814{
1815 if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
1816 {
1817 if ('1' <= first[2] && first[2] <= '9')
1818 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001819 const char* t = parse_number(first+2, last);
1820 if (t == last || *t != '_')
1821 return first;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001822 const char* num = first + 2;
Howard Hinnant3e5c7d02012-03-08 18:45:24 +00001823 size_t sz = static_cast<size_t>(t - num);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001824 if (++t != last)
1825 {
1826 if (*t != 'p')
1827 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001828 const char* t1 = parse_type(t, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001829 if (t1 != t)
1830 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001831 if (db.names.empty())
1832 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001833 db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
1834 first = t1;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001835 }
1836 }
1837 else
1838 {
1839 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001840 db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]");
1841 first = t;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001842 }
1843 }
1844 }
1845 else
1846 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001847 typename C::String num;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001848 const char* t1 = first+2;
1849 if (*t1 != '_')
1850 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001851 const char* t = parse_expression(t1, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001852 if (t != t1)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001853 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001854 if (db.names.empty())
1855 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001856 num = db.names.back().move_full();
1857 db.names.pop_back();
1858 t1 = t;
1859 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001860 }
1861 if (t1 != last && *t1 == '_' && ++t1 != last)
1862 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001863 const char* t = parse_type(t1, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001864 if (t != t1)
1865 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001866 if (db.names.empty())
1867 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001868 db.names.back().first += " vector[" + num + "]";
1869 first = t;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001870 }
1871 }
1872 }
1873 }
1874 return first;
1875}
1876
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001877// <type> ::= <builtin-type>
1878// ::= <function-type>
1879// ::= <class-enum-type>
1880// ::= <array-type>
1881// ::= <pointer-to-member-type>
1882// ::= <template-param>
1883// ::= <template-template-param> <template-args>
1884// ::= <decltype>
1885// ::= <substitution>
1886// ::= <CV-qualifiers> <type>
1887// ::= P <type> # pointer-to
1888// ::= R <type> # reference-to
1889// ::= O <type> # rvalue reference-to (C++0x)
1890// ::= C <type> # complex pair (C 2000)
1891// ::= G <type> # imaginary (C 2000)
1892// ::= Dp <type> # pack expansion (C++0x)
1893// ::= U <source-name> <type> # vendor extended type qualifier
Howard Hinnant19e36dd2013-06-19 13:43:18 +00001894// extension := U <objc-name> <objc-type> # objc-type<identifier>
Howard Hinnantab87dcf2011-12-15 20:02:15 +00001895// extension := <vector-type> # <vector-type> starts with Dv
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001896
Howard Hinnant19e36dd2013-06-19 13:43:18 +00001897// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
1898// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
1899
Howard Hinnant6c33e762013-06-17 18:10:34 +00001900template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001901const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001902parse_type(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001903{
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001904 if (first != last)
1905 {
1906 switch (*first)
1907 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001908 case 'r':
1909 case 'V':
1910 case 'K':
1911 {
1912 unsigned cv = 0;
1913 const char* t = parse_cv_qualifiers(first, last, cv);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001914 if (t != first)
1915 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001916 bool is_function = *t == 'F';
1917 size_t k0 = db.names.size();
1918 const char* t1 = parse_type(t, last, db);
1919 size_t k1 = db.names.size();
1920 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001921 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001922 if (is_function)
1923 db.subs.pop_back();
1924 db.subs.emplace_back(db.names.get_allocator());
1925 for (size_t k = k0; k < k1; ++k)
1926 {
1927 if (is_function)
1928 {
1929 size_t p = db.names[k].second.size();
1930 if (db.names[k].second[p-2] == '&')
1931 p -= 3;
1932 else if (db.names[k].second.back() == '&')
1933 p -= 2;
1934 if (cv & 1)
1935 {
1936 db.names[k].second.insert(p, " const");
1937 p += 6;
1938 }
1939 if (cv & 2)
1940 {
1941 db.names[k].second.insert(p, " volatile");
1942 p += 9;
1943 }
1944 if (cv & 4)
1945 db.names[k].second.insert(p, " restrict");
1946 }
1947 else
1948 {
1949 if (cv & 1)
1950 db.names[k].first.append(" const");
1951 if (cv & 2)
1952 db.names[k].first.append(" volatile");
1953 if (cv & 4)
1954 db.names[k].first.append(" restrict");
1955 }
1956 db.subs.back().push_back(db.names[k]);
1957 }
1958 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001959 }
1960 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001961 }
1962 break;
1963 default:
1964 {
1965 const char* t = parse_builtin_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001966 if (t != first)
1967 {
1968 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001969 }
1970 else
1971 {
1972 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001973 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001974 case 'A':
1975 t = parse_array_type(first, last, db);
1976 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001977 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001978 if (db.names.empty())
1979 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001980 first = t;
1981 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1982 }
1983 break;
1984 case 'C':
1985 t = parse_type(first+1, last, db);
1986 if (t != first+1)
1987 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001988 if (db.names.empty())
1989 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001990 db.names.back().first.append(" complex");
1991 first = t;
1992 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
1993 }
1994 break;
1995 case 'F':
1996 t = parse_function_type(first, last, db);
1997 if (t != first)
1998 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00001999 if (db.names.empty())
2000 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002001 first = t;
2002 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2003 }
2004 break;
2005 case 'G':
2006 t = parse_type(first+1, last, db);
2007 if (t != first+1)
2008 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002009 if (db.names.empty())
2010 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002011 db.names.back().first.append(" imaginary");
2012 first = t;
2013 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2014 }
2015 break;
2016 case 'M':
2017 t = parse_pointer_to_member_type(first, last, db);
2018 if (t != first)
2019 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002020 if (db.names.empty())
2021 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002022 first = t;
2023 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2024 }
2025 break;
2026 case 'O':
2027 {
2028 size_t k0 = db.names.size();
2029 t = parse_type(first+1, last, db);
2030 size_t k1 = db.names.size();
2031 if (t != first+1)
2032 {
2033 db.subs.emplace_back(db.names.get_allocator());
2034 for (size_t k = k0; k < k1; ++k)
2035 {
2036 if (db.names[k].second.substr(0, 2) == " [")
2037 {
2038 db.names[k].first += " (";
2039 db.names[k].second.insert(0, ")");
2040 }
Chaoren Lin3b8762a2015-05-26 23:14:26 +00002041 else if (!db.names[k].second.empty() &&
2042 db.names[k].second.front() == '(')
Howard Hinnant6c33e762013-06-17 18:10:34 +00002043 {
2044 db.names[k].first += "(";
2045 db.names[k].second.insert(0, ")");
2046 }
2047 db.names[k].first.append("&&");
2048 db.subs.back().push_back(db.names[k]);
2049 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002050 first = t;
2051 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002052 break;
2053 }
2054 case 'P':
2055 {
2056 size_t k0 = db.names.size();
2057 t = parse_type(first+1, last, db);
2058 size_t k1 = db.names.size();
2059 if (t != first+1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002060 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002061 db.subs.emplace_back(db.names.get_allocator());
2062 for (size_t k = k0; k < k1; ++k)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002063 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002064 if (db.names[k].second.substr(0, 2) == " [")
2065 {
2066 db.names[k].first += " (";
2067 db.names[k].second.insert(0, ")");
2068 }
Chaoren Lin3b8762a2015-05-26 23:14:26 +00002069 else if (!db.names[k].second.empty() &&
2070 db.names[k].second.front() == '(')
Howard Hinnant6c33e762013-06-17 18:10:34 +00002071 {
2072 db.names[k].first += "(";
2073 db.names[k].second.insert(0, ")");
2074 }
Howard Hinnant19e36dd2013-06-19 13:43:18 +00002075 if (first[1] != 'U' || db.names[k].first.substr(0, 12) != "objc_object<")
2076 {
2077 db.names[k].first.append("*");
2078 }
2079 else
2080 {
2081 db.names[k].first.replace(0, 11, "id");
2082 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002083 db.subs.back().push_back(db.names[k]);
2084 }
2085 first = t;
2086 }
2087 break;
2088 }
2089 case 'R':
2090 {
2091 size_t k0 = db.names.size();
2092 t = parse_type(first+1, last, db);
2093 size_t k1 = db.names.size();
2094 if (t != first+1)
2095 {
2096 db.subs.emplace_back(db.names.get_allocator());
2097 for (size_t k = k0; k < k1; ++k)
2098 {
2099 if (db.names[k].second.substr(0, 2) == " [")
2100 {
2101 db.names[k].first += " (";
2102 db.names[k].second.insert(0, ")");
2103 }
Chaoren Lin3b8762a2015-05-26 23:14:26 +00002104 else if (!db.names[k].second.empty() &&
2105 db.names[k].second.front() == '(')
Howard Hinnant6c33e762013-06-17 18:10:34 +00002106 {
2107 db.names[k].first += "(";
2108 db.names[k].second.insert(0, ")");
2109 }
2110 db.names[k].first.append("&");
2111 db.subs.back().push_back(db.names[k]);
2112 }
2113 first = t;
2114 }
2115 break;
2116 }
2117 case 'T':
2118 {
2119 size_t k0 = db.names.size();
2120 t = parse_template_param(first, last, db);
2121 size_t k1 = db.names.size();
2122 if (t != first)
2123 {
2124 db.subs.emplace_back(db.names.get_allocator());
2125 for (size_t k = k0; k < k1; ++k)
2126 db.subs.back().push_back(db.names[k]);
2127 if (db.try_to_parse_template_args && k1 == k0+1)
2128 {
2129 const char* t1 = parse_template_args(t, last, db);
2130 if (t1 != t)
2131 {
2132 auto args = db.names.back().move_full();
2133 db.names.pop_back();
2134 db.names.back().first += std::move(args);
2135 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2136 t = t1;
2137 }
2138 }
2139 first = t;
2140 }
2141 break;
2142 }
2143 case 'U':
2144 if (first+1 != last)
2145 {
2146 t = parse_source_name(first+1, last, db);
2147 if (t != first+1)
2148 {
2149 const char* t2 = parse_type(t, last, db);
2150 if (t2 != t)
2151 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002152 if (db.names.size() < 2)
2153 return first;
Howard Hinnant19e36dd2013-06-19 13:43:18 +00002154 auto type = db.names.back().move_full();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002155 db.names.pop_back();
Howard Hinnant19e36dd2013-06-19 13:43:18 +00002156 if (db.names.back().first.substr(0, 9) != "objcproto")
2157 {
2158 db.names.back() = type + " " + db.names.back().move_full();
2159 }
2160 else
2161 {
2162 auto proto = db.names.back().move_full();
2163 db.names.pop_back();
2164 t = parse_source_name(proto.data() + 9, proto.data() + proto.size(), db);
2165 if (t != proto.data() + 9)
2166 {
2167 db.names.back() = type + "<" + db.names.back().move_full() + ">";
2168 }
2169 else
2170 {
2171 db.names.push_back(type + " " + proto);
2172 }
2173 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002174 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2175 first = t2;
2176 }
2177 }
2178 }
2179 break;
2180 case 'S':
2181 if (first+1 != last && first[1] == 't')
2182 {
2183 t = parse_name(first, last, db);
2184 if (t != first)
2185 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002186 if (db.names.empty())
2187 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002188 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002189 first = t;
2190 }
2191 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002192 else
2193 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002194 t = parse_substitution(first, last, db);
2195 if (t != first)
2196 {
2197 first = t;
2198 // Parsed a substitution. If the substitution is a
2199 // <template-param> it might be followed by <template-args>.
2200 t = parse_template_args(first, last, db);
2201 if (t != first)
2202 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002203 if (db.names.size() < 2)
2204 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002205 auto template_args = db.names.back().move_full();
2206 db.names.pop_back();
2207 db.names.back().first += template_args;
2208 // Need to create substitution for <template-template-param> <template-args>
2209 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2210 first = t;
2211 }
2212 }
2213 }
2214 break;
2215 case 'D':
2216 if (first+1 != last)
2217 {
2218 switch (first[1])
2219 {
2220 case 'p':
2221 {
2222 size_t k0 = db.names.size();
2223 t = parse_type(first+2, last, db);
2224 size_t k1 = db.names.size();
Howard Hinnantf6725172013-06-21 17:04:24 +00002225 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002226 {
2227 db.subs.emplace_back(db.names.get_allocator());
2228 for (size_t k = k0; k < k1; ++k)
2229 db.subs.back().push_back(db.names[k]);
2230 first = t;
2231 return first;
2232 }
2233 break;
2234 }
2235 case 't':
2236 case 'T':
2237 t = parse_decltype(first, last, db);
2238 if (t != first)
2239 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002240 if (db.names.empty())
2241 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002242 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2243 first = t;
2244 return first;
2245 }
2246 break;
2247 case 'v':
2248 t = parse_vector_type(first, last, db);
2249 if (t != first)
2250 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002251 if (db.names.empty())
2252 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002253 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2254 first = t;
2255 return first;
2256 }
2257 break;
2258 }
2259 }
2260 // drop through
2261 default:
2262 // must check for builtin-types before class-enum-types to avoid
2263 // ambiguities with operator-names
2264 t = parse_builtin_type(first, last, db);
2265 if (t != first)
2266 {
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002267 first = t;
2268 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00002269 else
2270 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002271 t = parse_name(first, last, db);
2272 if (t != first)
2273 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002274 if (db.names.empty())
2275 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002276 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
2277 first = t;
2278 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00002279 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002280 break;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00002281 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002282 }
2283 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002284 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002285 }
2286 }
2287 return first;
2288}
2289
2290// <operator-name>
2291// ::= aa # &&
2292// ::= ad # & (unary)
2293// ::= an # &
2294// ::= aN # &=
2295// ::= aS # =
2296// ::= cl # ()
2297// ::= cm # ,
2298// ::= co # ~
2299// ::= cv <type> # (cast)
2300// ::= da # delete[]
2301// ::= de # * (unary)
2302// ::= dl # delete
2303// ::= dv # /
2304// ::= dV # /=
2305// ::= eo # ^
2306// ::= eO # ^=
2307// ::= eq # ==
2308// ::= ge # >=
2309// ::= gt # >
2310// ::= ix # []
2311// ::= le # <=
Howard Hinnantf29757a2014-01-06 23:05:04 +00002312// ::= li <source-name> # operator ""
Howard Hinnant6c33e762013-06-17 18:10:34 +00002313// ::= ls # <<
2314// ::= lS # <<=
2315// ::= lt # <
2316// ::= mi # -
2317// ::= mI # -=
2318// ::= ml # *
2319// ::= mL # *=
2320// ::= mm # -- (postfix in <expression> context)
2321// ::= na # new[]
2322// ::= ne # !=
2323// ::= ng # - (unary)
2324// ::= nt # !
2325// ::= nw # new
2326// ::= oo # ||
2327// ::= or # |
2328// ::= oR # |=
2329// ::= pm # ->*
2330// ::= pl # +
2331// ::= pL # +=
2332// ::= pp # ++ (postfix in <expression> context)
2333// ::= ps # + (unary)
2334// ::= pt # ->
2335// ::= qu # ?
2336// ::= rm # %
2337// ::= rM # %=
2338// ::= rs # >>
2339// ::= rS # >>=
2340// ::= v <digit> <source-name> # vendor extended operator
2341
2342template <class C>
2343const char*
2344parse_operator_name(const char* first, const char* last, C& db)
2345{
2346 if (last - first >= 2)
2347 {
2348 switch (first[0])
2349 {
2350 case 'a':
2351 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002352 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002353 case 'a':
2354 db.names.push_back("operator&&");
2355 first += 2;
2356 break;
2357 case 'd':
2358 case 'n':
2359 db.names.push_back("operator&");
2360 first += 2;
2361 break;
2362 case 'N':
2363 db.names.push_back("operator&=");
2364 first += 2;
2365 break;
2366 case 'S':
2367 db.names.push_back("operator=");
2368 first += 2;
2369 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002370 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002371 break;
2372 case 'c':
2373 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002374 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002375 case 'l':
2376 db.names.push_back("operator()");
2377 first += 2;
2378 break;
2379 case 'm':
2380 db.names.push_back("operator,");
2381 first += 2;
2382 break;
2383 case 'o':
2384 db.names.push_back("operator~");
2385 first += 2;
2386 break;
2387 case 'v':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002388 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002389 bool try_to_parse_template_args = db.try_to_parse_template_args;
2390 db.try_to_parse_template_args = false;
2391 const char* t = parse_type(first+2, last, db);
2392 db.try_to_parse_template_args = try_to_parse_template_args;
2393 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002394 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002395 if (db.names.empty())
2396 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002397 db.names.back().first.insert(0, "operator ");
2398 db.parsed_ctor_dtor_cv = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002399 first = t;
2400 }
2401 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002402 break;
2403 }
2404 break;
2405 case 'd':
2406 switch (first[1])
2407 {
2408 case 'a':
2409 db.names.push_back("operator delete[]");
2410 first += 2;
2411 break;
2412 case 'e':
2413 db.names.push_back("operator*");
2414 first += 2;
2415 break;
2416 case 'l':
2417 db.names.push_back("operator delete");
2418 first += 2;
2419 break;
2420 case 'v':
2421 db.names.push_back("operator/");
2422 first += 2;
2423 break;
2424 case 'V':
2425 db.names.push_back("operator/=");
2426 first += 2;
2427 break;
2428 }
2429 break;
2430 case 'e':
2431 switch (first[1])
2432 {
2433 case 'o':
2434 db.names.push_back("operator^");
2435 first += 2;
2436 break;
2437 case 'O':
2438 db.names.push_back("operator^=");
2439 first += 2;
2440 break;
2441 case 'q':
2442 db.names.push_back("operator==");
2443 first += 2;
2444 break;
2445 }
2446 break;
2447 case 'g':
2448 switch (first[1])
2449 {
2450 case 'e':
2451 db.names.push_back("operator>=");
2452 first += 2;
2453 break;
2454 case 't':
2455 db.names.push_back("operator>");
2456 first += 2;
2457 break;
2458 }
2459 break;
2460 case 'i':
2461 if (first[1] == 'x')
2462 {
2463 db.names.push_back("operator[]");
2464 first += 2;
2465 }
2466 break;
2467 case 'l':
2468 switch (first[1])
2469 {
2470 case 'e':
2471 db.names.push_back("operator<=");
2472 first += 2;
2473 break;
Howard Hinnantf29757a2014-01-06 23:05:04 +00002474 case 'i':
2475 {
2476 const char* t = parse_source_name(first+2, last, db);
2477 if (t != first+2)
2478 {
2479 if (db.names.empty())
2480 return first;
2481 db.names.back().first.insert(0, "operator\"\" ");
2482 first = t;
2483 }
2484 }
2485 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002486 case 's':
2487 db.names.push_back("operator<<");
2488 first += 2;
2489 break;
2490 case 'S':
2491 db.names.push_back("operator<<=");
2492 first += 2;
2493 break;
2494 case 't':
2495 db.names.push_back("operator<");
2496 first += 2;
2497 break;
2498 }
2499 break;
2500 case 'm':
2501 switch (first[1])
2502 {
2503 case 'i':
2504 db.names.push_back("operator-");
2505 first += 2;
2506 break;
2507 case 'I':
2508 db.names.push_back("operator-=");
2509 first += 2;
2510 break;
2511 case 'l':
2512 db.names.push_back("operator*");
2513 first += 2;
2514 break;
2515 case 'L':
2516 db.names.push_back("operator*=");
2517 first += 2;
2518 break;
2519 case 'm':
2520 db.names.push_back("operator--");
2521 first += 2;
2522 break;
2523 }
2524 break;
2525 case 'n':
2526 switch (first[1])
2527 {
2528 case 'a':
2529 db.names.push_back("operator new[]");
2530 first += 2;
2531 break;
2532 case 'e':
2533 db.names.push_back("operator!=");
2534 first += 2;
2535 break;
2536 case 'g':
2537 db.names.push_back("operator-");
2538 first += 2;
2539 break;
2540 case 't':
2541 db.names.push_back("operator!");
2542 first += 2;
2543 break;
2544 case 'w':
2545 db.names.push_back("operator new");
2546 first += 2;
2547 break;
2548 }
2549 break;
2550 case 'o':
2551 switch (first[1])
2552 {
2553 case 'o':
2554 db.names.push_back("operator||");
2555 first += 2;
2556 break;
2557 case 'r':
2558 db.names.push_back("operator|");
2559 first += 2;
2560 break;
2561 case 'R':
2562 db.names.push_back("operator|=");
2563 first += 2;
2564 break;
2565 }
2566 break;
2567 case 'p':
2568 switch (first[1])
2569 {
2570 case 'm':
2571 db.names.push_back("operator->*");
2572 first += 2;
2573 break;
2574 case 'l':
2575 db.names.push_back("operator+");
2576 first += 2;
2577 break;
2578 case 'L':
2579 db.names.push_back("operator+=");
2580 first += 2;
2581 break;
2582 case 'p':
2583 db.names.push_back("operator++");
2584 first += 2;
2585 break;
2586 case 's':
2587 db.names.push_back("operator+");
2588 first += 2;
2589 break;
2590 case 't':
2591 db.names.push_back("operator->");
2592 first += 2;
2593 break;
2594 }
2595 break;
2596 case 'q':
2597 if (first[1] == 'u')
2598 {
2599 db.names.push_back("operator?");
2600 first += 2;
2601 }
2602 break;
2603 case 'r':
2604 switch (first[1])
2605 {
2606 case 'm':
2607 db.names.push_back("operator%");
2608 first += 2;
2609 break;
2610 case 'M':
2611 db.names.push_back("operator%=");
2612 first += 2;
2613 break;
2614 case 's':
2615 db.names.push_back("operator>>");
2616 first += 2;
2617 break;
2618 case 'S':
2619 db.names.push_back("operator>>=");
2620 first += 2;
2621 break;
2622 }
2623 break;
2624 case 'v':
2625 if (std::isdigit(first[1]))
2626 {
2627 const char* t = parse_source_name(first+2, last, db);
2628 if (t != first+2)
2629 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002630 if (db.names.empty())
2631 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002632 db.names.back().first.insert(0, "operator ");
2633 first = t;
2634 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002635 }
2636 break;
2637 }
2638 }
2639 return first;
2640}
2641
Howard Hinnant6c33e762013-06-17 18:10:34 +00002642template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002643const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00002644parse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)
2645{
2646 const char* t = parse_number(first, last);
2647 if (t != first && t != last && *t == 'E')
2648 {
2649 if (lit.size() > 3)
2650 db.names.push_back("(" + lit + ")");
2651 else
2652 db.names.emplace_back();
2653 if (*first == 'n')
2654 {
2655 db.names.back().first += '-';
2656 ++first;
2657 }
2658 db.names.back().first.append(first, t);
2659 if (lit.size() <= 3)
2660 db.names.back().first += lit;
2661 first = t+1;
2662 }
2663 return first;
2664}
2665
2666// <expr-primary> ::= L <type> <value number> E # integer literal
2667// ::= L <type> <value float> E # floating literal
2668// ::= L <string type> E # string literal
2669// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
2670// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
2671// ::= L <mangled-name> E # external name
2672
2673template <class C>
2674const char*
2675parse_expr_primary(const char* first, const char* last, C& db)
2676{
2677 if (last - first >= 4 && *first == 'L')
2678 {
2679 switch (first[1])
2680 {
2681 case 'w':
Howard Hinnant93433df2013-06-20 21:49:34 +00002682 {
2683 const char* t = parse_integer_literal(first+2, last, "wchar_t", db);
2684 if (t != first+2)
2685 first = t;
2686 }
2687 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002688 case 'b':
2689 if (first[3] == 'E')
2690 {
2691 switch (first[2])
2692 {
2693 case '0':
2694 db.names.push_back("false");
2695 first += 4;
2696 break;
2697 case '1':
2698 db.names.push_back("true");
2699 first += 4;
2700 break;
2701 }
2702 }
2703 break;
2704 case 'c':
Howard Hinnant93433df2013-06-20 21:49:34 +00002705 {
2706 const char* t = parse_integer_literal(first+2, last, "char", db);
2707 if (t != first+2)
2708 first = t;
2709 }
2710 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002711 case 'a':
Howard Hinnant93433df2013-06-20 21:49:34 +00002712 {
2713 const char* t = parse_integer_literal(first+2, last, "signed char", db);
2714 if (t != first+2)
2715 first = t;
2716 }
2717 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002718 case 'h':
Howard Hinnant93433df2013-06-20 21:49:34 +00002719 {
2720 const char* t = parse_integer_literal(first+2, last, "unsigned char", db);
2721 if (t != first+2)
2722 first = t;
2723 }
2724 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002725 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00002726 {
2727 const char* t = parse_integer_literal(first+2, last, "short", db);
2728 if (t != first+2)
2729 first = t;
2730 }
2731 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002732 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00002733 {
2734 const char* t = parse_integer_literal(first+2, last, "unsigned short", db);
2735 if (t != first+2)
2736 first = t;
2737 }
2738 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002739 case 'i':
Howard Hinnant93433df2013-06-20 21:49:34 +00002740 {
2741 const char* t = parse_integer_literal(first+2, last, "", db);
2742 if (t != first+2)
2743 first = t;
2744 }
2745 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002746 case 'j':
Howard Hinnant93433df2013-06-20 21:49:34 +00002747 {
2748 const char* t = parse_integer_literal(first+2, last, "u", db);
2749 if (t != first+2)
2750 first = t;
2751 }
2752 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002753 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00002754 {
2755 const char* t = parse_integer_literal(first+2, last, "l", db);
2756 if (t != first+2)
2757 first = t;
2758 }
2759 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002760 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00002761 {
2762 const char* t = parse_integer_literal(first+2, last, "ul", db);
2763 if (t != first+2)
2764 first = t;
2765 }
2766 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002767 case 'x':
Howard Hinnant93433df2013-06-20 21:49:34 +00002768 {
2769 const char* t = parse_integer_literal(first+2, last, "ll", db);
2770 if (t != first+2)
2771 first = t;
2772 }
2773 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002774 case 'y':
Howard Hinnant93433df2013-06-20 21:49:34 +00002775 {
2776 const char* t = parse_integer_literal(first+2, last, "ull", db);
2777 if (t != first+2)
2778 first = t;
2779 }
2780 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002781 case 'n':
Howard Hinnant93433df2013-06-20 21:49:34 +00002782 {
2783 const char* t = parse_integer_literal(first+2, last, "__int128", db);
2784 if (t != first+2)
2785 first = t;
2786 }
2787 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002788 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00002789 {
2790 const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db);
2791 if (t != first+2)
2792 first = t;
2793 }
2794 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002795 case 'f':
Howard Hinnant93433df2013-06-20 21:49:34 +00002796 {
2797 const char* t = parse_floating_number<float>(first+2, last, db);
2798 if (t != first+2)
2799 first = t;
2800 }
2801 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002802 case 'd':
Howard Hinnant93433df2013-06-20 21:49:34 +00002803 {
2804 const char* t = parse_floating_number<double>(first+2, last, db);
2805 if (t != first+2)
2806 first = t;
2807 }
2808 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002809 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00002810 {
2811 const char* t = parse_floating_number<long double>(first+2, last, db);
2812 if (t != first+2)
2813 first = t;
2814 }
2815 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002816 case '_':
2817 if (first[2] == 'Z')
2818 {
2819 const char* t = parse_encoding(first+3, last, db);
2820 if (t != first+3 && t != last && *t == 'E')
2821 first = t+1;
2822 }
2823 break;
2824 case 'T':
2825 // Invalid mangled name per
2826 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2827 break;
2828 default:
2829 {
2830 // might be named type
2831 const char* t = parse_type(first+1, last, db);
2832 if (t != first+1 && t != last)
2833 {
2834 if (*t != 'E')
2835 {
2836 const char* n = t;
2837 for (; n != last && isdigit(*n); ++n)
2838 ;
2839 if (n != t && n != last && *n == 'E')
2840 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002841 if (db.names.empty())
2842 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002843 db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n);
2844 first = n+1;
2845 break;
2846 }
2847 }
2848 else
2849 {
2850 first = t+1;
2851 break;
2852 }
2853 }
2854 }
2855 }
2856 }
2857 return first;
2858}
2859
2860template <class String>
2861String
2862base_name(String& s)
2863{
2864 if (s.empty())
2865 return s;
2866 if (s == "std::string")
2867 {
2868 s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >";
2869 return "basic_string";
2870 }
2871 if (s == "std::istream")
2872 {
2873 s = "std::basic_istream<char, std::char_traits<char> >";
2874 return "basic_istream";
2875 }
2876 if (s == "std::ostream")
2877 {
2878 s = "std::basic_ostream<char, std::char_traits<char> >";
2879 return "basic_ostream";
2880 }
2881 if (s == "std::iostream")
2882 {
2883 s = "std::basic_iostream<char, std::char_traits<char> >";
2884 return "basic_iostream";
2885 }
2886 const char* const pf = s.data();
2887 const char* pe = pf + s.size();
2888 if (pe[-1] == '>')
2889 {
2890 unsigned c = 1;
2891 while (true)
2892 {
2893 if (--pe == pf)
2894 return String();
2895 if (pe[-1] == '<')
2896 {
2897 if (--c == 0)
2898 {
2899 --pe;
2900 break;
2901 }
2902 }
2903 else if (pe[-1] == '>')
2904 ++c;
2905 }
2906 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00002907 if (pe - pf <= 1)
2908 return String();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002909 const char* p0 = pe - 1;
2910 for (; p0 != pf; --p0)
2911 {
2912 if (*p0 == ':')
2913 {
2914 ++p0;
2915 break;
2916 }
2917 }
2918 return String(p0, pe);
2919}
2920
2921// <ctor-dtor-name> ::= C1 # complete object constructor
2922// ::= C2 # base object constructor
2923// ::= C3 # complete object allocating constructor
2924// extension ::= C5 # ?
2925// ::= D0 # deleting destructor
2926// ::= D1 # complete object destructor
2927// ::= D2 # base object destructor
2928// extension ::= D5 # ?
2929
2930template <class C>
2931const char*
2932parse_ctor_dtor_name(const char* first, const char* last, C& db)
2933{
2934 if (last-first >= 2 && !db.names.empty())
2935 {
2936 switch (first[0])
2937 {
2938 case 'C':
2939 switch (first[1])
2940 {
2941 case '1':
2942 case '2':
2943 case '3':
2944 case '5':
Howard Hinnant753a30d2013-12-11 19:44:25 +00002945 if (db.names.empty())
2946 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002947 db.names.push_back(base_name(db.names.back().first));
2948 first += 2;
2949 db.parsed_ctor_dtor_cv = true;
2950 break;
2951 }
2952 break;
2953 case 'D':
2954 switch (first[1])
2955 {
2956 case '0':
2957 case '1':
2958 case '2':
2959 case '5':
Howard Hinnant753a30d2013-12-11 19:44:25 +00002960 if (db.names.empty())
2961 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002962 db.names.push_back("~" + base_name(db.names.back().first));
2963 first += 2;
2964 db.parsed_ctor_dtor_cv = true;
2965 break;
2966 }
2967 break;
2968 }
2969 }
2970 return first;
2971}
2972
2973// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
2974// ::= <closure-type-name>
2975//
2976// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2977//
2978// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
2979
2980template <class C>
2981const char*
2982parse_unnamed_type_name(const char* first, const char* last, C& db)
2983{
2984 if (last - first > 2 && first[0] == 'U')
2985 {
2986 char type = first[1];
2987 switch (type)
2988 {
2989 case 't':
2990 {
2991 db.names.push_back(typename C::String("'unnamed"));
2992 const char* t0 = first+2;
2993 if (t0 == last)
2994 {
2995 db.names.pop_back();
2996 return first;
2997 }
2998 if (std::isdigit(*t0))
2999 {
3000 const char* t1 = t0 + 1;
3001 while (t1 != last && std::isdigit(*t1))
3002 ++t1;
3003 db.names.back().first.append(t0, t1);
3004 t0 = t1;
3005 }
3006 db.names.back().first.push_back('\'');
3007 if (t0 == last || *t0 != '_')
3008 {
3009 db.names.pop_back();
3010 return first;
3011 }
3012 first = t0 + 1;
3013 }
3014 break;
3015 case 'l':
3016 {
3017 db.names.push_back(typename C::String("'lambda'("));
3018 const char* t0 = first+2;
3019 if (first[2] == 'v')
3020 {
3021 db.names.back().first += ')';
3022 ++t0;
3023 }
3024 else
3025 {
3026 const char* t1 = parse_type(t0, last, db);
3027 if (t1 == t0)
3028 {
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003029 if(!db.names.empty())
3030 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003031 return first;
3032 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00003033 if (db.names.size() < 2)
3034 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003035 auto tmp = db.names.back().move_full();
3036 db.names.pop_back();
3037 db.names.back().first.append(tmp);
3038 t0 = t1;
3039 while (true)
3040 {
3041 t1 = parse_type(t0, last, db);
3042 if (t1 == t0)
3043 break;
Howard Hinnant753a30d2013-12-11 19:44:25 +00003044 if (db.names.size() < 2)
3045 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003046 tmp = db.names.back().move_full();
3047 db.names.pop_back();
3048 if (!tmp.empty())
3049 {
3050 db.names.back().first.append(", ");
3051 db.names.back().first.append(tmp);
3052 }
3053 t0 = t1;
3054 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003055 if(db.names.empty())
3056 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003057 db.names.back().first.append(")");
3058 }
3059 if (t0 == last || *t0 != 'E')
3060 {
Saleem Abdulrasooled8daea2016-12-31 18:09:51 +00003061 if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003062 db.names.pop_back();
Saleem Abdulrasooled8daea2016-12-31 18:09:51 +00003063 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003064 }
3065 ++t0;
3066 if (t0 == last)
3067 {
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003068 if(!db.names.empty())
3069 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003070 return first;
3071 }
3072 if (std::isdigit(*t0))
3073 {
3074 const char* t1 = t0 + 1;
3075 while (t1 != last && std::isdigit(*t1))
3076 ++t1;
3077 db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
3078 t0 = t1;
3079 }
3080 if (t0 == last || *t0 != '_')
3081 {
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003082 if(!db.names.empty())
3083 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003084 return first;
3085 }
3086 first = t0 + 1;
3087 }
3088 break;
3089 }
3090 }
3091 return first;
3092}
3093
3094// <unqualified-name> ::= <operator-name>
3095// ::= <ctor-dtor-name>
3096// ::= <source-name>
3097// ::= <unnamed-type-name>
3098
3099template <class C>
3100const char*
3101parse_unqualified_name(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003102{
3103 if (first != last)
3104 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003105 const char* t;
3106 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003107 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003108 case 'C':
3109 case 'D':
3110 t = parse_ctor_dtor_name(first, last, db);
3111 if (t != first)
3112 first = t;
3113 break;
3114 case 'U':
3115 t = parse_unnamed_type_name(first, last, db);
3116 if (t != first)
3117 first = t;
3118 break;
3119 case '1':
3120 case '2':
3121 case '3':
3122 case '4':
3123 case '5':
3124 case '6':
3125 case '7':
3126 case '8':
3127 case '9':
3128 t = parse_source_name(first, last, db);
3129 if (t != first)
3130 first = t;
3131 break;
3132 default:
3133 t = parse_operator_name(first, last, db);
3134 if (t != first)
3135 first = t;
3136 break;
3137 };
3138 }
3139 return first;
3140}
3141
3142// <unscoped-name> ::= <unqualified-name>
3143// ::= St <unqualified-name> # ::std::
3144// extension ::= StL<unqualified-name>
3145
3146template <class C>
3147const char*
3148parse_unscoped_name(const char* first, const char* last, C& db)
3149{
3150 if (last - first >= 2)
3151 {
3152 const char* t0 = first;
3153 bool St = false;
3154 if (first[0] == 'S' && first[1] == 't')
3155 {
3156 t0 += 2;
3157 St = true;
3158 if (t0 != last && *t0 == 'L')
3159 ++t0;
3160 }
3161 const char* t1 = parse_unqualified_name(t0, last, db);
3162 if (t1 != t0)
3163 {
3164 if (St)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003165 {
3166 if (db.names.empty())
3167 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003168 db.names.back().first.insert(0, "std::");
Howard Hinnant753a30d2013-12-11 19:44:25 +00003169 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003170 first = t1;
3171 }
3172 }
3173 return first;
3174}
3175
3176// at <type> # alignof (a type)
3177
3178template <class C>
3179const char*
3180parse_alignof_type(const char* first, const char* last, C& db)
3181{
3182 if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
3183 {
3184 const char* t = parse_type(first+2, last, db);
3185 if (t != first+2)
3186 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003187 if (db.names.empty())
3188 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003189 db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
3190 first = t;
3191 }
3192 }
3193 return first;
3194}
3195
3196// az <expression> # alignof (a expression)
3197
3198template <class C>
3199const char*
3200parse_alignof_expr(const char* first, const char* last, C& db)
3201{
3202 if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
3203 {
3204 const char* t = parse_expression(first+2, last, db);
3205 if (t != first+2)
3206 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003207 if (db.names.empty())
3208 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003209 db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
3210 first = t;
3211 }
3212 }
3213 return first;
3214}
3215
3216template <class C>
3217const char*
3218parse_noexcept_expression(const char* first, const char* last, C& db)
3219{
3220 const char* t1 = parse_expression(first, last, db);
3221 if (t1 != first)
3222 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003223 if (db.names.empty())
3224 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003225 db.names.back().first = "noexcept (" + db.names.back().move_full() + ")";
3226 first = t1;
3227 }
3228 return first;
3229}
3230
3231template <class C>
3232const char*
3233parse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db)
3234{
3235 const char* t1 = parse_expression(first, last, db);
3236 if (t1 != first)
3237 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003238 if (db.names.empty())
3239 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003240 db.names.back().first = op + "(" + db.names.back().move_full() + ")";
3241 first = t1;
3242 }
3243 return first;
3244}
3245
3246template <class C>
3247const char*
3248parse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db)
3249{
3250 const char* t1 = parse_expression(first, last, db);
3251 if (t1 != first)
3252 {
3253 const char* t2 = parse_expression(t1, last, db);
3254 if (t2 != t1)
3255 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003256 if (db.names.size() < 2)
3257 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003258 auto op2 = db.names.back().move_full();
3259 db.names.pop_back();
3260 auto op1 = db.names.back().move_full();
3261 auto& nm = db.names.back().first;
3262 nm.clear();
3263 if (op == ">")
3264 nm += '(';
3265 nm += "(" + op1 + ") " + op + " (" + op2 + ")";
3266 if (op == ">")
3267 nm += ')';
3268 first = t2;
3269 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003270 else if(!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003271 db.names.pop_back();
3272 }
3273 return first;
3274}
3275
3276// <expression> ::= <unary operator-name> <expression>
3277// ::= <binary operator-name> <expression> <expression>
3278// ::= <ternary operator-name> <expression> <expression> <expression>
3279// ::= cl <expression>+ E # call
3280// ::= cv <type> <expression> # conversion with one argument
3281// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
3282// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
3283// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
3284// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
3285// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
3286// ::= [gs] dl <expression> # delete expression
3287// ::= [gs] da <expression> # delete[] expression
3288// ::= pp_ <expression> # prefix ++
3289// ::= mm_ <expression> # prefix --
3290// ::= ti <type> # typeid (type)
3291// ::= te <expression> # typeid (expression)
3292// ::= dc <type> <expression> # dynamic_cast<type> (expression)
3293// ::= sc <type> <expression> # static_cast<type> (expression)
3294// ::= cc <type> <expression> # const_cast<type> (expression)
3295// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
3296// ::= st <type> # sizeof (a type)
3297// ::= sz <expression> # sizeof (an expression)
3298// ::= at <type> # alignof (a type)
3299// ::= az <expression> # alignof (an expression)
3300// ::= nx <expression> # noexcept (expression)
3301// ::= <template-param>
3302// ::= <function-param>
3303// ::= dt <expression> <unresolved-name> # expr.name
3304// ::= pt <expression> <unresolved-name> # expr->name
3305// ::= ds <expression> <expression> # expr.*expr
3306// ::= sZ <template-param> # size of a parameter pack
3307// ::= sZ <function-param> # size of a function parameter pack
3308// ::= sp <expression> # pack expansion
3309// ::= tw <expression> # throw expression
3310// ::= tr # throw with no operand (rethrow)
3311// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
3312// # freestanding dependent name (e.g., T::x),
3313// # objectless nonstatic member reference
3314// ::= <expr-primary>
3315
3316template <class C>
3317const char*
3318parse_expression(const char* first, const char* last, C& db)
3319{
3320 if (last - first >= 2)
3321 {
3322 const char* t = first;
3323 bool parsed_gs = false;
3324 if (last - first >= 4 && t[0] == 'g' && t[1] == 's')
3325 {
3326 t += 2;
3327 parsed_gs = true;
3328 }
3329 switch (*t)
3330 {
3331 case 'L':
3332 first = parse_expr_primary(first, last, db);
3333 break;
3334 case 'T':
3335 first = parse_template_param(first, last, db);
3336 break;
3337 case 'f':
3338 first = parse_function_param(first, last, db);
3339 break;
3340 case 'a':
3341 switch (t[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003342 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003343 case 'a':
Howard Hinnant93433df2013-06-20 21:49:34 +00003344 t = parse_binary_expression(first+2, last, "&&", db);
3345 if (t != first+2)
3346 first = t;
3347 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003348 case 'd':
Howard Hinnant93433df2013-06-20 21:49:34 +00003349 t = parse_prefix_expression(first+2, last, "&", db);
3350 if (t != first+2)
3351 first = t;
3352 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003353 case 'n':
Howard Hinnant93433df2013-06-20 21:49:34 +00003354 t = parse_binary_expression(first+2, last, "&", db);
3355 if (t != first+2)
3356 first = t;
3357 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003358 case 'N':
Howard Hinnant93433df2013-06-20 21:49:34 +00003359 t = parse_binary_expression(first+2, last, "&=", db);
3360 if (t != first+2)
3361 first = t;
3362 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003363 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00003364 t = parse_binary_expression(first+2, last, "=", db);
3365 if (t != first+2)
3366 first = t;
3367 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003368 case 't':
3369 first = parse_alignof_type(first, last, db);
3370 break;
3371 case 'z':
3372 first = parse_alignof_expr(first, last, db);
3373 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003374 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003375 break;
3376 case 'c':
3377 switch (t[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003378 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003379 case 'c':
3380 first = parse_const_cast_expr(first, last, db);
3381 break;
3382 case 'l':
3383 first = parse_call_expr(first, last, db);
3384 break;
3385 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00003386 t = parse_binary_expression(first+2, last, ",", db);
3387 if (t != first+2)
3388 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003389 break;
3390 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00003391 t = parse_prefix_expression(first+2, last, "~", db);
3392 if (t != first+2)
3393 first = t;
3394 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003395 case 'v':
3396 first = parse_conversion_expr(first, last, db);
3397 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003398 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003399 break;
3400 case 'd':
3401 switch (t[1])
3402 {
3403 case 'a':
3404 {
3405 const char* t1 = parse_expression(t+2, last, db);
3406 if (t1 != t+2)
3407 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003408 if (db.names.empty())
3409 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003410 db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
3411 "delete[] " + db.names.back().move_full();
3412 first = t1;
3413 }
3414 }
3415 break;
3416 case 'c':
3417 first = parse_dynamic_cast_expr(first, last, db);
3418 break;
3419 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00003420 t = parse_prefix_expression(first+2, last, "*", db);
3421 if (t != first+2)
3422 first = t;
3423 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003424 case 'l':
3425 {
3426 const char* t1 = parse_expression(t+2, last, db);
3427 if (t1 != t+2)
3428 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003429 if (db.names.empty())
3430 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003431 db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
3432 "delete " + db.names.back().move_full();
3433 first = t1;
3434 }
3435 }
3436 break;
3437 case 'n':
3438 return parse_unresolved_name(first, last, db);
3439 case 's':
3440 first = parse_dot_star_expr(first, last, db);
3441 break;
3442 case 't':
3443 first = parse_dot_expr(first, last, db);
3444 break;
3445 case 'v':
Howard Hinnant93433df2013-06-20 21:49:34 +00003446 t = parse_binary_expression(first+2, last, "/", db);
3447 if (t != first+2)
3448 first = t;
3449 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003450 case 'V':
Howard Hinnant93433df2013-06-20 21:49:34 +00003451 t = parse_binary_expression(first+2, last, "/=", db);
3452 if (t != first+2)
3453 first = t;
3454 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003455 }
3456 break;
3457 case 'e':
3458 switch (t[1])
3459 {
3460 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00003461 t = parse_binary_expression(first+2, last, "^", db);
3462 if (t != first+2)
3463 first = t;
3464 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003465 case 'O':
Howard Hinnant93433df2013-06-20 21:49:34 +00003466 t = parse_binary_expression(first+2, last, "^=", db);
3467 if (t != first+2)
3468 first = t;
3469 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003470 case 'q':
Howard Hinnant93433df2013-06-20 21:49:34 +00003471 t = parse_binary_expression(first+2, last, "==", db);
3472 if (t != first+2)
3473 first = t;
3474 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003475 }
3476 break;
3477 case 'g':
3478 switch (t[1])
3479 {
3480 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00003481 t = parse_binary_expression(first+2, last, ">=", db);
3482 if (t != first+2)
3483 first = t;
3484 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003485 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00003486 t = parse_binary_expression(first+2, last, ">", db);
3487 if (t != first+2)
3488 first = t;
3489 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003490 }
3491 break;
3492 case 'i':
3493 if (t[1] == 'x')
3494 {
3495 const char* t1 = parse_expression(first+2, last, db);
3496 if (t1 != first+2)
3497 {
3498 const char* t2 = parse_expression(t1, last, db);
3499 if (t2 != t1)
3500 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003501 if (db.names.size() < 2)
3502 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003503 auto op2 = db.names.back().move_full();
3504 db.names.pop_back();
3505 auto op1 = db.names.back().move_full();
3506 db.names.back() = "(" + op1 + ")[" + op2 + "]";
3507 first = t2;
3508 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003509 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003510 db.names.pop_back();
3511 }
3512 }
3513 break;
3514 case 'l':
3515 switch (t[1])
3516 {
3517 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00003518 t = parse_binary_expression(first+2, last, "<=", db);
3519 if (t != first+2)
3520 first = t;
3521 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003522 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00003523 t = parse_binary_expression(first+2, last, "<<", db);
3524 if (t != first+2)
3525 first = t;
3526 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003527 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00003528 t = parse_binary_expression(first+2, last, "<<=", db);
3529 if (t != first+2)
3530 first = t;
3531 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003532 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00003533 t = parse_binary_expression(first+2, last, "<", db);
3534 if (t != first+2)
3535 first = t;
3536 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003537 }
3538 break;
3539 case 'm':
3540 switch (t[1])
3541 {
3542 case 'i':
Howard Hinnant93433df2013-06-20 21:49:34 +00003543 t = parse_binary_expression(first+2, last, "-", db);
3544 if (t != first+2)
3545 first = t;
3546 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003547 case 'I':
Howard Hinnant93433df2013-06-20 21:49:34 +00003548 t = parse_binary_expression(first+2, last, "-=", db);
3549 if (t != first+2)
3550 first = t;
3551 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003552 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00003553 t = parse_binary_expression(first+2, last, "*", db);
3554 if (t != first+2)
3555 first = t;
3556 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003557 case 'L':
Howard Hinnant93433df2013-06-20 21:49:34 +00003558 t = parse_binary_expression(first+2, last, "*=", db);
3559 if (t != first+2)
3560 first = t;
3561 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003562 case 'm':
3563 if (first+2 != last && first[2] == '_')
Howard Hinnant93433df2013-06-20 21:49:34 +00003564 {
3565 t = parse_prefix_expression(first+3, last, "--", db);
3566 if (t != first+3)
3567 first = t;
3568 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003569 else
3570 {
3571 const char* t1 = parse_expression(first+2, last, db);
3572 if (t1 != first+2)
3573 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003574 if (db.names.empty())
3575 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003576 db.names.back() = "(" + db.names.back().move_full() + ")--";
3577 first = t1;
3578 }
3579 }
3580 break;
3581 }
3582 break;
3583 case 'n':
3584 switch (t[1])
3585 {
3586 case 'a':
3587 case 'w':
3588 first = parse_new_expr(first, last, db);
3589 break;
3590 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00003591 t = parse_binary_expression(first+2, last, "!=", db);
3592 if (t != first+2)
3593 first = t;
3594 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003595 case 'g':
Howard Hinnant93433df2013-06-20 21:49:34 +00003596 t = parse_prefix_expression(first+2, last, "-", db);
3597 if (t != first+2)
3598 first = t;
3599 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003600 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00003601 t = parse_prefix_expression(first+2, last, "!", db);
3602 if (t != first+2)
3603 first = t;
3604 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003605 case 'x':
Howard Hinnant93433df2013-06-20 21:49:34 +00003606 t = parse_noexcept_expression(first+2, last, db);
3607 if (t != first+2)
3608 first = t;
3609 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003610 }
3611 break;
3612 case 'o':
3613 switch (t[1])
3614 {
3615 case 'n':
3616 return parse_unresolved_name(first, last, db);
3617 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00003618 t = parse_binary_expression(first+2, last, "||", db);
3619 if (t != first+2)
3620 first = t;
3621 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003622 case 'r':
Howard Hinnant93433df2013-06-20 21:49:34 +00003623 t = parse_binary_expression(first+2, last, "|", db);
3624 if (t != first+2)
3625 first = t;
3626 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003627 case 'R':
Howard Hinnant93433df2013-06-20 21:49:34 +00003628 t = parse_binary_expression(first+2, last, "|=", db);
3629 if (t != first+2)
3630 first = t;
3631 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003632 }
3633 break;
3634 case 'p':
3635 switch (t[1])
3636 {
3637 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00003638 t = parse_binary_expression(first+2, last, "->*", db);
3639 if (t != first+2)
3640 first = t;
3641 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003642 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00003643 t = parse_binary_expression(first+2, last, "+", db);
3644 if (t != first+2)
3645 first = t;
3646 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003647 case 'L':
Howard Hinnant93433df2013-06-20 21:49:34 +00003648 t = parse_binary_expression(first+2, last, "+=", db);
3649 if (t != first+2)
3650 first = t;
3651 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003652 case 'p':
3653 if (first+2 != last && first[2] == '_')
Howard Hinnant93433df2013-06-20 21:49:34 +00003654 {
3655 t = parse_prefix_expression(first+3, last, "++", db);
3656 if (t != first+3)
3657 first = t;
3658 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003659 else
3660 {
3661 const char* t1 = parse_expression(first+2, last, db);
3662 if (t1 != first+2)
3663 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003664 if (db.names.empty())
3665 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003666 db.names.back() = "(" + db.names.back().move_full() + ")++";
3667 first = t1;
3668 }
3669 }
3670 break;
3671 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00003672 t = parse_prefix_expression(first+2, last, "+", db);
3673 if (t != first+2)
3674 first = t;
3675 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003676 case 't':
3677 first = parse_arrow_expr(first, last, db);
3678 break;
3679 }
3680 break;
3681 case 'q':
3682 if (t[1] == 'u')
3683 {
3684 const char* t1 = parse_expression(first+2, last, db);
3685 if (t1 != first+2)
3686 {
3687 const char* t2 = parse_expression(t1, last, db);
3688 if (t2 != t1)
3689 {
3690 const char* t3 = parse_expression(t2, last, db);
3691 if (t3 != t2)
3692 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003693 if (db.names.size() < 3)
3694 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003695 auto op3 = db.names.back().move_full();
3696 db.names.pop_back();
3697 auto op2 = db.names.back().move_full();
3698 db.names.pop_back();
3699 auto op1 = db.names.back().move_full();
3700 db.names.back() = "(" + op1 + ") ? (" + op2 + ") : (" + op3 + ")";
3701 first = t3;
3702 }
3703 else
3704 {
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003705 if (db.names.size() < 2)
3706 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003707 db.names.pop_back();
3708 db.names.pop_back();
3709 }
3710 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003711 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003712 db.names.pop_back();
3713 }
3714 }
3715 break;
3716 case 'r':
3717 switch (t[1])
3718 {
3719 case 'c':
3720 first = parse_reinterpret_cast_expr(first, last, db);
3721 break;
3722 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00003723 t = parse_binary_expression(first+2, last, "%", db);
3724 if (t != first+2)
3725 first = t;
3726 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003727 case 'M':
Howard Hinnant93433df2013-06-20 21:49:34 +00003728 t = parse_binary_expression(first+2, last, "%=", db);
3729 if (t != first+2)
3730 first = t;
3731 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003732 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00003733 t = parse_binary_expression(first+2, last, ">>", db);
3734 if (t != first+2)
3735 first = t;
3736 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003737 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00003738 t = parse_binary_expression(first+2, last, ">>=", db);
3739 if (t != first+2)
3740 first = t;
3741 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003742 }
3743 break;
3744 case 's':
3745 switch (t[1])
3746 {
3747 case 'c':
3748 first = parse_static_cast_expr(first, last, db);
3749 break;
3750 case 'p':
3751 first = parse_pack_expansion(first, last, db);
3752 break;
3753 case 'r':
3754 return parse_unresolved_name(first, last, db);
3755 case 't':
3756 first = parse_sizeof_type_expr(first, last, db);
3757 break;
3758 case 'z':
3759 first = parse_sizeof_expr_expr(first, last, db);
3760 break;
3761 case 'Z':
3762 if (last - t >= 3)
3763 {
3764 switch (t[2])
3765 {
3766 case 'T':
3767 first = parse_sizeof_param_pack_expr(first, last, db);
3768 break;
3769 case 'f':
3770 first = parse_sizeof_function_param_pack_expr(first, last, db);
3771 break;
3772 }
3773 }
3774 break;
3775 }
3776 break;
3777 case 't':
3778 switch (t[1])
3779 {
3780 case 'e':
3781 case 'i':
3782 first = parse_typeid_expr(first, last, db);
3783 break;
3784 case 'r':
3785 db.names.push_back("throw");
3786 first += 2;
3787 break;
3788 case 'w':
3789 first = parse_throw_expr(first, last, db);
3790 break;
3791 }
3792 break;
3793 case '1':
3794 case '2':
3795 case '3':
3796 case '4':
3797 case '5':
3798 case '6':
3799 case '7':
3800 case '8':
3801 case '9':
3802 return parse_unresolved_name(first, last, db);
3803 }
3804 }
3805 return first;
3806}
3807
3808// <template-arg> ::= <type> # type or template
3809// ::= X <expression> E # expression
3810// ::= <expr-primary> # simple expressions
3811// ::= J <template-arg>* E # argument pack
3812// ::= LZ <encoding> E # extension
3813
3814template <class C>
3815const char*
3816parse_template_arg(const char* first, const char* last, C& db)
3817{
3818 if (first != last)
3819 {
3820 const char* t;
3821 switch (*first)
3822 {
3823 case 'X':
3824 t = parse_expression(first+1, last, db);
3825 if (t != first+1)
3826 {
3827 if (t != last && *t == 'E')
3828 first = t+1;
3829 }
3830 break;
3831 case 'J':
3832 t = first+1;
3833 if (t == last)
3834 return first;
3835 while (*t != 'E')
3836 {
3837 const char* t1 = parse_template_arg(t, last, db);
3838 if (t1 == t)
3839 return first;
3840 t = t1;
3841 }
3842 first = t+1;
3843 break;
3844 case 'L':
3845 // <expr-primary> or LZ <encoding> E
3846 if (first+1 != last && first[1] == 'Z')
3847 {
3848 t = parse_encoding(first+2, last, db);
3849 if (t != first+2 && t != last && *t == 'E')
3850 first = t+1;
3851 }
3852 else
3853 first = parse_expr_primary(first, last, db);
3854 break;
3855 default:
3856 // <type>
3857 first = parse_type(first, last, db);
3858 break;
3859 }
3860 }
3861 return first;
3862}
3863
3864// <template-args> ::= I <template-arg>* E
3865// extension, the abi says <template-arg>+
3866
3867template <class C>
3868const char*
3869parse_template_args(const char* first, const char* last, C& db)
3870{
3871 if (last - first >= 2 && *first == 'I')
3872 {
3873 if (db.tag_templates)
3874 db.template_param.back().clear();
3875 const char* t = first+1;
3876 typename C::String args("<");
3877 while (*t != 'E')
3878 {
3879 if (db.tag_templates)
3880 db.template_param.emplace_back(db.names.get_allocator());
3881 size_t k0 = db.names.size();
3882 const char* t1 = parse_template_arg(t, last, db);
3883 size_t k1 = db.names.size();
3884 if (db.tag_templates)
3885 db.template_param.pop_back();
3886 if (t1 == t || t1 == last)
3887 return first;
3888 if (db.tag_templates)
3889 {
3890 db.template_param.back().emplace_back(db.names.get_allocator());
3891 for (size_t k = k0; k < k1; ++k)
3892 db.template_param.back().back().push_back(db.names[k]);
3893 }
3894 for (size_t k = k0; k < k1; ++k)
3895 {
3896 if (args.size() > 1)
3897 args += ", ";
3898 args += db.names[k].move_full();
3899 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003900 for (; k1 > k0; --k1)
3901 if (!db.names.empty())
3902 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003903 t = t1;
3904 }
3905 first = t + 1;
3906 if (args.back() != '>')
3907 args += ">";
3908 else
3909 args += " >";
3910 db.names.push_back(std::move(args));
3911
3912 }
3913 return first;
3914}
3915
3916// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
3917// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
3918//
3919// <prefix> ::= <prefix> <unqualified-name>
3920// ::= <template-prefix> <template-args>
3921// ::= <template-param>
3922// ::= <decltype>
3923// ::= # empty
3924// ::= <substitution>
3925// ::= <prefix> <data-member-prefix>
3926// extension ::= L
3927//
3928// <template-prefix> ::= <prefix> <template unqualified-name>
3929// ::= <template-param>
3930// ::= <substitution>
3931
3932template <class C>
3933const char*
Richard Smith24ecd092014-05-12 18:44:13 +00003934parse_nested_name(const char* first, const char* last, C& db,
3935 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003936{
3937 if (first != last && *first == 'N')
3938 {
3939 unsigned cv;
3940 const char* t0 = parse_cv_qualifiers(first+1, last, cv);
3941 if (t0 == last)
3942 return first;
3943 db.ref = 0;
3944 if (*t0 == 'R')
3945 {
3946 db.ref = 1;
3947 ++t0;
3948 }
3949 else if (*t0 == 'O')
3950 {
3951 db.ref = 2;
3952 ++t0;
3953 }
3954 db.names.emplace_back();
3955 if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
3956 {
3957 t0 += 2;
3958 db.names.back().first = "std";
3959 }
3960 if (t0 == last)
3961 {
3962 db.names.pop_back();
3963 return first;
3964 }
3965 bool pop_subs = false;
Richard Smith24ecd092014-05-12 18:44:13 +00003966 bool component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003967 while (*t0 != 'E')
3968 {
Richard Smith24ecd092014-05-12 18:44:13 +00003969 component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003970 const char* t1;
3971 switch (*t0)
3972 {
3973 case 'S':
3974 if (t0 + 1 != last && t0[1] == 't')
3975 goto do_parse_unqualified_name;
3976 t1 = parse_substitution(t0, last, db);
3977 if (t1 != t0 && t1 != last)
3978 {
3979 auto name = db.names.back().move_full();
3980 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00003981 if (db.names.empty())
3982 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003983 if (!db.names.back().first.empty())
3984 {
3985 db.names.back().first += "::" + name;
3986 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
3987 }
3988 else
3989 db.names.back().first = name;
3990 pop_subs = true;
3991 t0 = t1;
3992 }
3993 else
3994 return first;
3995 break;
3996 case 'T':
3997 t1 = parse_template_param(t0, last, db);
3998 if (t1 != t0 && t1 != last)
3999 {
4000 auto name = db.names.back().move_full();
4001 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004002 if (db.names.empty())
4003 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004004 if (!db.names.back().first.empty())
4005 db.names.back().first += "::" + name;
4006 else
4007 db.names.back().first = name;
4008 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4009 pop_subs = true;
4010 t0 = t1;
4011 }
4012 else
4013 return first;
4014 break;
4015 case 'D':
4016 if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
4017 goto do_parse_unqualified_name;
4018 t1 = parse_decltype(t0, last, db);
4019 if (t1 != t0 && t1 != last)
4020 {
4021 auto name = db.names.back().move_full();
4022 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004023 if (db.names.empty())
4024 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004025 if (!db.names.back().first.empty())
4026 db.names.back().first += "::" + name;
4027 else
4028 db.names.back().first = name;
4029 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4030 pop_subs = true;
4031 t0 = t1;
4032 }
4033 else
4034 return first;
4035 break;
4036 case 'I':
4037 t1 = parse_template_args(t0, last, db);
4038 if (t1 != t0 && t1 != last)
4039 {
4040 auto name = db.names.back().move_full();
4041 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004042 if (db.names.empty())
4043 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004044 db.names.back().first += name;
4045 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4046 t0 = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00004047 component_ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004048 }
4049 else
4050 return first;
4051 break;
4052 case 'L':
4053 if (++t0 == last)
4054 return first;
4055 break;
4056 default:
4057 do_parse_unqualified_name:
4058 t1 = parse_unqualified_name(t0, last, db);
4059 if (t1 != t0 && t1 != last)
4060 {
4061 auto name = db.names.back().move_full();
4062 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004063 if (db.names.empty())
4064 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004065 if (!db.names.back().first.empty())
4066 db.names.back().first += "::" + name;
4067 else
4068 db.names.back().first = name;
4069 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4070 pop_subs = true;
4071 t0 = t1;
4072 }
4073 else
4074 return first;
4075 }
4076 }
4077 first = t0 + 1;
4078 db.cv = cv;
Howard Hinnantf6725172013-06-21 17:04:24 +00004079 if (pop_subs && !db.subs.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004080 db.subs.pop_back();
Richard Smith24ecd092014-05-12 18:44:13 +00004081 if (ends_with_template_args)
4082 *ends_with_template_args = component_ends_with_template_args;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004083 }
4084 return first;
4085}
4086
4087// <discriminator> := _ <non-negative number> # when number < 10
4088// := __ <non-negative number> _ # when number >= 10
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004089// extension := decimal-digit+ # at the end of string
Howard Hinnant6c33e762013-06-17 18:10:34 +00004090
4091const char*
4092parse_discriminator(const char* first, const char* last)
4093{
4094 // parse but ignore discriminator
4095 if (first != last)
4096 {
4097 if (*first == '_')
4098 {
4099 const char* t1 = first+1;
4100 if (t1 != last)
4101 {
4102 if (std::isdigit(*t1))
4103 first = t1+1;
4104 else if (*t1 == '_')
4105 {
4106 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4107 ;
4108 if (t1 != last && *t1 == '_')
4109 first = t1 + 1;
4110 }
4111 }
4112 }
4113 else if (std::isdigit(*first))
4114 {
4115 const char* t1 = first+1;
4116 for (; t1 != last && std::isdigit(*t1); ++t1)
4117 ;
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004118 if (t1 == last)
4119 first = last;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004120 }
4121 }
4122 return first;
4123}
4124
4125// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
4126// := Z <function encoding> E s [<discriminator>]
4127// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
4128
4129template <class C>
4130const char*
Richard Smith24ecd092014-05-12 18:44:13 +00004131parse_local_name(const char* first, const char* last, C& db,
4132 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004133{
4134 if (first != last && *first == 'Z')
4135 {
4136 const char* t = parse_encoding(first+1, last, db);
4137 if (t != first+1 && t != last && *t == 'E' && ++t != last)
4138 {
4139 switch (*t)
4140 {
4141 case 's':
4142 first = parse_discriminator(t+1, last);
Howard Hinnant753a30d2013-12-11 19:44:25 +00004143 if (db.names.empty())
4144 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004145 db.names.back().first.append("::string literal");
4146 break;
4147 case 'd':
4148 if (++t != last)
4149 {
4150 const char* t1 = parse_number(t, last);
4151 if (t1 != last && *t1 == '_')
4152 {
4153 t = t1 + 1;
Richard Smith24ecd092014-05-12 18:44:13 +00004154 t1 = parse_name(t, last, db,
4155 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004156 if (t1 != t)
4157 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004158 if (db.names.size() < 2)
4159 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004160 auto name = db.names.back().move_full();
4161 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004162 if (db.names.empty())
4163 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004164 db.names.back().first.append("::");
4165 db.names.back().first.append(name);
4166 first = t1;
4167 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004168 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004169 db.names.pop_back();
4170 }
4171 }
4172 break;
4173 default:
4174 {
Richard Smith24ecd092014-05-12 18:44:13 +00004175 const char* t1 = parse_name(t, last, db,
4176 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004177 if (t1 != t)
4178 {
4179 // parse but ignore discriminator
4180 first = parse_discriminator(t1, last);
Howard Hinnant753a30d2013-12-11 19:44:25 +00004181 if (db.names.size() < 2)
4182 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004183 auto name = db.names.back().move_full();
4184 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004185 if (db.names.empty())
4186 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004187 db.names.back().first.append("::");
4188 db.names.back().first.append(name);
4189 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004190 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004191 db.names.pop_back();
4192 }
4193 break;
4194 }
4195 }
4196 }
4197 return first;
4198}
4199
4200// <name> ::= <nested-name> // N
4201// ::= <local-name> # See Scope Encoding below // Z
4202// ::= <unscoped-template-name> <template-args>
4203// ::= <unscoped-name>
4204
4205// <unscoped-template-name> ::= <unscoped-name>
4206// ::= <substitution>
4207
4208template <class C>
4209const char*
Richard Smith24ecd092014-05-12 18:44:13 +00004210parse_name(const char* first, const char* last, C& db,
4211 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004212{
4213 if (last - first >= 2)
4214 {
4215 const char* t0 = first;
4216 // extension: ignore L here
4217 if (*t0 == 'L')
4218 ++t0;
4219 switch (*t0)
4220 {
4221 case 'N':
4222 {
Richard Smith24ecd092014-05-12 18:44:13 +00004223 const char* t1 = parse_nested_name(t0, last, db,
4224 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004225 if (t1 != t0)
4226 first = t1;
4227 break;
4228 }
4229 case 'Z':
4230 {
Richard Smith24ecd092014-05-12 18:44:13 +00004231 const char* t1 = parse_local_name(t0, last, db,
4232 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004233 if (t1 != t0)
4234 first = t1;
4235 break;
4236 }
4237 default:
4238 {
4239 const char* t1 = parse_unscoped_name(t0, last, db);
4240 if (t1 != t0)
4241 {
4242 if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
4243 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004244 if (db.names.empty())
4245 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004246 db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
4247 t0 = t1;
4248 t1 = parse_template_args(t0, last, db);
4249 if (t1 != t0)
4250 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004251 if (db.names.size() < 2)
4252 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004253 auto tmp = db.names.back().move_full();
4254 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004255 if (db.names.empty())
4256 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004257 db.names.back().first += tmp;
4258 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00004259 if (ends_with_template_args)
4260 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004261 }
4262 }
4263 else // <unscoped-name>
4264 first = t1;
4265 }
4266 else
4267 { // try <substitution> <template-args>
4268 t1 = parse_substitution(t0, last, db);
Howard Hinnantb4033ff2013-06-20 01:55:07 +00004269 if (t1 != t0 && t1 != last && *t1 == 'I')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004270 {
4271 t0 = t1;
4272 t1 = parse_template_args(t0, last, db);
4273 if (t1 != t0)
4274 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004275 if (db.names.size() < 2)
4276 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004277 auto tmp = db.names.back().move_full();
4278 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004279 if (db.names.empty())
4280 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004281 db.names.back().first += tmp;
4282 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00004283 if (ends_with_template_args)
4284 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004285 }
4286 }
4287 }
4288 break;
4289 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004290 }
4291 }
4292 return first;
4293}
4294
4295// <call-offset> ::= h <nv-offset> _
4296// ::= v <v-offset> _
4297//
4298// <nv-offset> ::= <offset number>
4299// # non-virtual base override
4300//
4301// <v-offset> ::= <offset number> _ <virtual offset number>
4302// # virtual base override, with vcall offset
4303
4304const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004305parse_call_offset(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004306{
4307 if (first != last)
4308 {
4309 switch (*first)
4310 {
4311 case 'h':
4312 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004313 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004314 if (t != first + 1 && t != last && *t == '_')
4315 first = t + 1;
4316 }
4317 break;
4318 case 'v':
4319 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004320 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004321 if (t != first + 1 && t != last && *t == '_')
4322 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004323 const char* t2 = parse_number(++t, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004324 if (t2 != t && t2 != last && *t2 == '_')
4325 first = t2 + 1;
4326 }
4327 }
4328 break;
4329 }
4330 }
4331 return first;
4332}
4333
4334// <special-name> ::= TV <type> # virtual table
4335// ::= TT <type> # VTT structure (construction vtable index)
4336// ::= TI <type> # typeinfo structure
4337// ::= TS <type> # typeinfo name (null-terminated byte string)
4338// ::= Tc <call-offset> <call-offset> <base encoding>
4339// # base is the nominal target function of thunk
4340// # first call-offset is 'this' adjustment
4341// # second call-offset is result adjustment
4342// ::= T <call-offset> <base encoding>
4343// # base is the nominal target function of thunk
4344// ::= GV <object name> # Guard variable for one-time initialization
4345// # No <type>
Howard Hinnantf2700352011-12-09 20:07:56 +00004346// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4347// extension ::= GR <object name> # reference temporary for object
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004348
Howard Hinnant6c33e762013-06-17 18:10:34 +00004349template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004350const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004351parse_special_name(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004352{
4353 if (last - first > 2)
4354 {
4355 const char* t;
4356 switch (*first)
4357 {
4358 case 'T':
4359 switch (first[1])
4360 {
4361 case 'V':
4362 // TV <type> # virtual table
Howard Hinnant6c33e762013-06-17 18:10:34 +00004363 t = parse_type(first+2, last, db);
4364 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004365 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004366 if (db.names.empty())
4367 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004368 db.names.back().first.insert(0, "vtable for ");
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004369 first = t;
4370 }
4371 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004372 case 'T':
4373 // TT <type> # VTT structure (construction vtable index)
4374 t = parse_type(first+2, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00004375 if (t != first+2)
4376 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004377 if (db.names.empty())
4378 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004379 db.names.back().first.insert(0, "VTT for ");
4380 first = t;
4381 }
4382 break;
4383 case 'I':
4384 // TI <type> # typeinfo structure
4385 t = parse_type(first+2, last, db);
4386 if (t != first+2)
4387 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004388 if (db.names.empty())
4389 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004390 db.names.back().first.insert(0, "typeinfo for ");
4391 first = t;
4392 }
4393 break;
4394 case 'S':
4395 // TS <type> # typeinfo name (null-terminated byte string)
4396 t = parse_type(first+2, last, db);
4397 if (t != first+2)
4398 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004399 if (db.names.empty())
4400 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004401 db.names.back().first.insert(0, "typeinfo name for ");
4402 first = t;
4403 }
4404 break;
4405 case 'c':
4406 // Tc <call-offset> <call-offset> <base encoding>
4407 {
4408 const char* t0 = parse_call_offset(first+2, last);
4409 if (t0 == first+2)
4410 break;
4411 const char* t1 = parse_call_offset(t0, last);
4412 if (t1 == t0)
4413 break;
4414 t = parse_encoding(t1, last, db);
4415 if (t != t1)
4416 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004417 if (db.names.empty())
4418 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004419 db.names.back().first.insert(0, "covariant return thunk to ");
4420 first = t;
4421 }
4422 }
4423 break;
4424 case 'C':
4425 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
4426 t = parse_type(first+2, last, db);
4427 if (t != first+2)
4428 {
4429 const char* t0 = parse_number(t, last);
Howard Hinnantf2700352011-12-09 20:07:56 +00004430 if (t0 != t && t0 != last && *t0 == '_')
4431 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004432 const char* t1 = parse_type(++t0, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00004433 if (t1 != t0)
4434 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004435 if (db.names.size() < 2)
4436 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004437 auto left = db.names.back().move_full();
4438 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004439 if (db.names.empty())
4440 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004441 db.names.back().first = "construction vtable for " +
4442 std::move(left) + "-in-" +
4443 db.names.back().move_full();
4444 first = t1;
Howard Hinnantf2700352011-12-09 20:07:56 +00004445 }
4446 }
4447 }
4448 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004449 default:
4450 // T <call-offset> <base encoding>
4451 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004452 const char* t0 = parse_call_offset(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004453 if (t0 == first+1)
4454 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004455 t = parse_encoding(t0, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004456 if (t != t0)
4457 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004458 if (db.names.empty())
4459 return first;
Marshall Clowfdccce62015-10-12 20:45:05 +00004460 if (first[1] == 'v')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004461 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004462 db.names.back().first.insert(0, "virtual thunk to ");
4463 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004464 }
4465 else
4466 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004467 db.names.back().first.insert(0, "non-virtual thunk to ");
4468 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004469 }
4470 }
4471 }
4472 break;
4473 }
4474 break;
4475 case 'G':
Howard Hinnantf2700352011-12-09 20:07:56 +00004476 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004477 {
Howard Hinnantf2700352011-12-09 20:07:56 +00004478 case 'V':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004479 // GV <object name> # Guard variable for one-time initialization
Howard Hinnant6c33e762013-06-17 18:10:34 +00004480 t = parse_name(first+2, last, db);
4481 if (t != first+2)
4482 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004483 if (db.names.empty())
4484 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004485 db.names.back().first.insert(0, "guard variable for ");
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004486 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004487 }
Howard Hinnantf2700352011-12-09 20:07:56 +00004488 break;
4489 case 'R':
4490 // extension ::= GR <object name> # reference temporary for object
Howard Hinnant6c33e762013-06-17 18:10:34 +00004491 t = parse_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004492 if (t != first+2)
4493 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004494 if (db.names.empty())
4495 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004496 db.names.back().first.insert(0, "reference temporary for ");
4497 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004498 }
4499 break;
4500 }
4501 break;
4502 }
4503 }
4504 return first;
4505}
4506
Howard Hinnant753a30d2013-12-11 19:44:25 +00004507template <class T>
4508class save_value
4509{
4510 T& restore_;
4511 T original_value_;
4512public:
4513 save_value(T& restore)
4514 : restore_(restore),
4515 original_value_(restore)
4516 {}
4517
4518 ~save_value()
4519 {
4520 restore_ = std::move(original_value_);
4521 }
4522
4523 save_value(const save_value&) = delete;
4524 save_value& operator=(const save_value&) = delete;
4525};
4526
Howard Hinnant6c33e762013-06-17 18:10:34 +00004527// <encoding> ::= <function name> <bare-function-type>
4528// ::= <data name>
4529// ::= <special-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004530
Howard Hinnant6c33e762013-06-17 18:10:34 +00004531template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004532const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004533parse_encoding(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004534{
4535 if (first != last)
4536 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004537 save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
4538 ++db.encoding_depth;
4539 save_value<decltype(db.tag_templates)> sb(db.tag_templates);
4540 if (db.encoding_depth > 1)
4541 db.tag_templates = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004542 switch (*first)
4543 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004544 case 'G':
4545 case 'T':
4546 first = parse_special_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004547 break;
4548 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00004549 {
Richard Smith24ecd092014-05-12 18:44:13 +00004550 bool ends_with_template_args = false;
4551 const char* t = parse_name(first, last, db,
4552 &ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004553 unsigned cv = db.cv;
4554 unsigned ref = db.ref;
4555 if (t != first)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00004556 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004557 if (t != last && *t != 'E' && *t != '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004558 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004559 save_value<bool> sb2(db.tag_templates);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004560 db.tag_templates = false;
4561 const char* t2;
4562 typename C::String ret2;
Howard Hinnant753a30d2013-12-11 19:44:25 +00004563 if (db.names.empty())
4564 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004565 const typename C::String& nm = db.names.back().first;
Howard Hinnant753a30d2013-12-11 19:44:25 +00004566 if (nm.empty())
4567 return first;
Richard Smith24ecd092014-05-12 18:44:13 +00004568 if (!db.parsed_ctor_dtor_cv && ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004569 {
4570 t2 = parse_type(t, last, db);
4571 if (t2 == t)
4572 return first;
Howard Hinnant753a30d2013-12-11 19:44:25 +00004573 if (db.names.size() < 2)
4574 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004575 auto ret1 = std::move(db.names.back().first);
4576 ret2 = std::move(db.names.back().second);
4577 if (ret2.empty())
4578 ret1 += ' ';
4579 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004580 if (db.names.empty())
4581 return first;
4582
Howard Hinnant6c33e762013-06-17 18:10:34 +00004583 db.names.back().first.insert(0, ret1);
4584 t = t2;
4585 }
4586 db.names.back().first += '(';
4587 if (t != last && *t == 'v')
4588 {
4589 ++t;
4590 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004591 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004592 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004593 bool first_arg = true;
4594 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004595 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004596 size_t k0 = db.names.size();
4597 t2 = parse_type(t, last, db);
4598 size_t k1 = db.names.size();
4599 if (t2 == t)
4600 break;
4601 if (k1 > k0)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004602 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004603 typename C::String tmp;
4604 for (size_t k = k0; k < k1; ++k)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004605 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004606 if (!tmp.empty())
4607 tmp += ", ";
4608 tmp += db.names[k].move_full();
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004609 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004610 for (size_t k = k0; k < k1; ++k) {
4611 if (db.names.empty())
4612 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004613 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004614 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004615 if (!tmp.empty())
4616 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004617 if (db.names.empty())
4618 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004619 if (!first_arg)
4620 db.names.back().first += ", ";
4621 else
4622 first_arg = false;
4623 db.names.back().first += tmp;
4624 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004625 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004626 t = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004627 }
4628 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00004629 if (db.names.empty())
4630 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004631 db.names.back().first += ')';
4632 if (cv & 1)
4633 db.names.back().first.append(" const");
4634 if (cv & 2)
4635 db.names.back().first.append(" volatile");
4636 if (cv & 4)
4637 db.names.back().first.append(" restrict");
4638 if (ref == 1)
4639 db.names.back().first.append(" &");
4640 else if (ref == 2)
4641 db.names.back().first.append(" &&");
4642 db.names.back().first += ret2;
4643 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004644 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004645 else
4646 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004647 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004648 break;
4649 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004650 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004651 }
4652 return first;
4653}
4654
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004655// _block_invoke
4656// _block_invoke<decimal-digit>+
4657// _block_invoke_<decimal-digit>+
4658
Howard Hinnant6c33e762013-06-17 18:10:34 +00004659template <class C>
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004660const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004661parse_block_invoke(const char* first, const char* last, C& db)
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004662{
4663 if (last - first >= 13)
4664 {
4665 const char test[] = "_block_invoke";
4666 const char* t = first;
4667 for (int i = 0; i < 13; ++i, ++t)
4668 {
4669 if (*t != test[i])
4670 return first;
4671 }
4672 if (t != last)
4673 {
4674 if (*t == '_')
4675 {
4676 // must have at least 1 decimal digit
Howard Hinnant6c33e762013-06-17 18:10:34 +00004677 if (++t == last || !std::isdigit(*t))
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004678 return first;
4679 ++t;
4680 }
4681 // parse zero or more digits
4682 while (t != last && isdigit(*t))
4683 ++t;
4684 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00004685 if (db.names.empty())
4686 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004687 db.names.back().first.insert(0, "invocation function for block in ");
4688 first = t;
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004689 }
4690 return first;
4691}
4692
Howard Hinnant6c33e762013-06-17 18:10:34 +00004693// extension
4694// <dot-suffix> := .<anything and everything>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004695
Howard Hinnant6c33e762013-06-17 18:10:34 +00004696template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004697const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004698parse_dot_suffix(const char* first, const char* last, C& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004699{
Howard Hinnant6c33e762013-06-17 18:10:34 +00004700 if (first != last && *first == '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004701 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004702 if (db.names.empty())
4703 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004704 db.names.back().first += " (" + typename C::String(first, last) + ")";
4705 first = last;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004706 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004707 return first;
4708}
4709
Howard Hinnant5dd173b2013-04-10 19:44:03 +00004710// <block-involcaton-function> ___Z<encoding>_block_invoke
4711// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
4712// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004713// <mangled-name> ::= _Z<encoding>
4714// ::= <type>
4715
Howard Hinnant6c33e762013-06-17 18:10:34 +00004716template <class C>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004717void
Howard Hinnant6c33e762013-06-17 18:10:34 +00004718demangle(const char* first, const char* last, C& db, int& status)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004719{
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00004720 if (first >= last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004721 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004722 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004723 return;
4724 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004725 if (*first == '_')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004726 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004727 if (last - first >= 4)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004728 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004729 if (first[1] == 'Z')
4730 {
4731 const char* t = parse_encoding(first+2, last, db);
4732 if (t != first+2 && t != last && *t == '.')
4733 t = parse_dot_suffix(t, last, db);
4734 if (t != last)
4735 status = invalid_mangled_name;
4736 }
4737 else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
4738 {
4739 const char* t = parse_encoding(first+4, last, db);
4740 if (t != first+4 && t != last)
4741 {
4742 const char* t1 = parse_block_invoke(t, last, db);
4743 if (t1 != last)
4744 status = invalid_mangled_name;
4745 }
4746 else
4747 status = invalid_mangled_name;
4748 }
4749 else
4750 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004751 }
4752 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00004753 status = invalid_mangled_name;
4754 }
4755 else
4756 {
4757 const char* t = parse_type(first, last, db);
4758 if (t != last)
4759 status = invalid_mangled_name;
4760 }
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00004761 if (status == success && db.names.empty())
4762 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004763}
4764
Howard Hinnant6c33e762013-06-17 18:10:34 +00004765template <std::size_t N>
4766class arena
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004767{
Howard Hinnant6c33e762013-06-17 18:10:34 +00004768 static const std::size_t alignment = 16;
4769 alignas(alignment) char buf_[N];
4770 char* ptr_;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004771
Howard Hinnant6c33e762013-06-17 18:10:34 +00004772 std::size_t
4773 align_up(std::size_t n) noexcept
Nick Lewyckyfaf34fb2015-03-05 02:56:05 +00004774 {return (n + (alignment-1)) & ~(alignment-1);}
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004775
Howard Hinnant6c33e762013-06-17 18:10:34 +00004776 bool
4777 pointer_in_buffer(char* p) noexcept
4778 {return buf_ <= p && p <= buf_ + N;}
4779
4780public:
4781 arena() noexcept : ptr_(buf_) {}
4782 ~arena() {ptr_ = nullptr;}
4783 arena(const arena&) = delete;
4784 arena& operator=(const arena&) = delete;
4785
4786 char* allocate(std::size_t n);
4787 void deallocate(char* p, std::size_t n) noexcept;
4788
4789 static constexpr std::size_t size() {return N;}
4790 std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
4791 void reset() {ptr_ = buf_;}
4792};
4793
4794template <std::size_t N>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004795char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00004796arena<N>::allocate(std::size_t n)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004797{
Howard Hinnant6c33e762013-06-17 18:10:34 +00004798 n = align_up(n);
4799 if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004800 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004801 char* r = ptr_;
4802 ptr_ += n;
4803 return r;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004804 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004805 return static_cast<char*>(std::malloc(n));
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004806}
4807
Howard Hinnant6c33e762013-06-17 18:10:34 +00004808template <std::size_t N>
4809void
4810arena<N>::deallocate(char* p, std::size_t n) noexcept
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004811{
Howard Hinnant6c33e762013-06-17 18:10:34 +00004812 if (pointer_in_buffer(p))
4813 {
4814 n = align_up(n);
4815 if (p + n == ptr_)
4816 ptr_ = p;
4817 }
4818 else
4819 std::free(p);
4820}
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004821
Howard Hinnant6c33e762013-06-17 18:10:34 +00004822template <class T, std::size_t N>
4823class short_alloc
4824{
4825 arena<N>& a_;
4826public:
4827 typedef T value_type;
4828
4829public:
4830 template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
4831
4832 short_alloc(arena<N>& a) noexcept : a_(a) {}
4833 template <class U>
4834 short_alloc(const short_alloc<U, N>& a) noexcept
4835 : a_(a.a_) {}
4836 short_alloc(const short_alloc&) = default;
4837 short_alloc& operator=(const short_alloc&) = delete;
4838
4839 T* allocate(std::size_t n)
4840 {
4841 return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
4842 }
4843 void deallocate(T* p, std::size_t n) noexcept
4844 {
4845 a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
4846 }
4847
4848 template <class T1, std::size_t N1, class U, std::size_t M>
4849 friend
4850 bool
4851 operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
4852
4853 template <class U, std::size_t M> friend class short_alloc;
4854};
4855
4856template <class T, std::size_t N, class U, std::size_t M>
4857inline
4858bool
4859operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
4860{
4861 return N == M && &x.a_ == &y.a_;
4862}
4863
4864template <class T, std::size_t N, class U, std::size_t M>
4865inline
4866bool
4867operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
4868{
4869 return !(x == y);
4870}
4871
4872template <class T>
4873class malloc_alloc
4874{
4875public:
4876 typedef T value_type;
Nico Weberb4c998b2015-09-20 18:10:46 +00004877 typedef T& reference;
4878 typedef const T& const_reference;
4879 typedef T* pointer;
4880 typedef const T* const_pointer;
4881 typedef std::size_t size_type;
4882 typedef std::ptrdiff_t difference_type;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004883
4884 malloc_alloc() = default;
4885 template <class U> malloc_alloc(const malloc_alloc<U>&) noexcept {}
4886
4887 T* allocate(std::size_t n)
4888 {
4889 return static_cast<T*>(std::malloc(n*sizeof(T)));
4890 }
4891 void deallocate(T* p, std::size_t) noexcept
4892 {
4893 std::free(p);
4894 }
Nico Weberb4c998b2015-09-20 18:10:46 +00004895
4896 template <class U> struct rebind { using other = malloc_alloc<U>; };
4897 template <class U, class... Args>
4898 void construct(U* p, Args&&... args)
4899 {
4900 ::new ((void*)p) U(std::forward<Args>(args)...);
4901 }
4902 void destroy(T* p)
4903 {
4904 p->~T();
4905 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004906};
4907
4908template <class T, class U>
4909inline
4910bool
4911operator==(const malloc_alloc<T>&, const malloc_alloc<U>&) noexcept
4912{
4913 return true;
4914}
4915
4916template <class T, class U>
4917inline
4918bool
4919operator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) noexcept
4920{
4921 return !(x == y);
4922}
4923
4924const size_t bs = 4 * 1024;
4925template <class T> using Alloc = short_alloc<T, bs>;
4926template <class T> using Vector = std::vector<T, Alloc<T>>;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004927
Nico Weber2b683fb2014-05-30 17:27:21 +00004928template <class StrT>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004929struct string_pair
4930{
Nico Weber2b683fb2014-05-30 17:27:21 +00004931 StrT first;
4932 StrT second;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004933
4934 string_pair() = default;
Nico Weber2b683fb2014-05-30 17:27:21 +00004935 string_pair(StrT f) : first(std::move(f)) {}
4936 string_pair(StrT f, StrT s)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004937 : first(std::move(f)), second(std::move(s)) {}
4938 template <size_t N>
4939 string_pair(const char (&s)[N]) : first(s, N-1) {}
4940
4941 size_t size() const {return first.size() + second.size();}
Nico Weber2b683fb2014-05-30 17:27:21 +00004942 StrT full() const {return first + second;}
4943 StrT move_full() {return std::move(first) + std::move(second);}
Howard Hinnant6c33e762013-06-17 18:10:34 +00004944};
4945
Howard Hinnant061240c2013-10-22 16:45:48 +00004946struct Db
4947{
Nico Weber2b683fb2014-05-30 17:27:21 +00004948 typedef std::basic_string<char, std::char_traits<char>,
4949 malloc_alloc<char>> String;
4950 typedef Vector<string_pair<String>> sub_type;
Howard Hinnant061240c2013-10-22 16:45:48 +00004951 typedef Vector<sub_type> template_param_type;
Nico Weber2b683fb2014-05-30 17:27:21 +00004952 sub_type names;
4953 template_param_type subs;
Howard Hinnant061240c2013-10-22 16:45:48 +00004954 Vector<template_param_type> template_param;
Saleem Abdulrasool2ecedcc2016-11-18 19:01:53 +00004955 unsigned cv = 0;
4956 unsigned ref = 0;
4957 unsigned encoding_depth = 0;
4958 bool parsed_ctor_dtor_cv = false;
4959 bool tag_templates = true;
4960 bool fix_forward_references = false;
4961 bool try_to_parse_template_args = true;
Howard Hinnant061240c2013-10-22 16:45:48 +00004962
4963 template <size_t N>
4964 Db(arena<N>& ar) :
4965 names(ar),
4966 subs(0, names, ar),
4967 template_param(0, subs, ar)
4968 {}
4969};
4970
Howard Hinnant6c33e762013-06-17 18:10:34 +00004971} // unnamed namespace
4972
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +00004973extern "C" _LIBCXXABI_FUNC_VIS char *
Saleem Abdulrasool77a304b2015-12-04 02:14:41 +00004974__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004975 if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004976 {
4977 if (status)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004978 *status = invalid_args;
4979 return nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004980 }
Saleem Abdulrasool8cfa5a32016-11-14 01:55:54 +00004981
Howard Hinnant8ad6a222013-07-26 22:14:53 +00004982 size_t internal_size = buf != nullptr ? *n : 0;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004983 arena<bs> a;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004984 Db db(a);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004985 db.template_param.emplace_back(a);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004986 int internal_status = success;
Jonathan Roelofs0cbb1da2017-01-18 18:12:39 +00004987 size_t len = std::strlen(mangled_name);
Howard Hinnantb2d1f942013-06-23 19:52:45 +00004988 demangle(mangled_name, mangled_name + len, db,
Howard Hinnant6c33e762013-06-17 18:10:34 +00004989 internal_status);
Howard Hinnantb2d1f942013-06-23 19:52:45 +00004990 if (internal_status == success && db.fix_forward_references &&
4991 !db.template_param.empty() && !db.template_param.front().empty())
4992 {
4993 db.fix_forward_references = false;
4994 db.tag_templates = false;
4995 db.names.clear();
4996 db.subs.clear();
4997 demangle(mangled_name, mangled_name + len, db, internal_status);
4998 if (db.fix_forward_references)
4999 internal_status = invalid_mangled_name;
5000 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005001 if (internal_status == success)
5002 {
5003 size_t sz = db.names.back().size() + 1;
5004 if (sz > internal_size)
5005 {
5006 char* newbuf = static_cast<char*>(std::realloc(buf, sz));
5007 if (newbuf == nullptr)
5008 {
5009 internal_status = memory_alloc_failure;
5010 buf = nullptr;
5011 }
5012 else
Howard Hinnant8ad6a222013-07-26 22:14:53 +00005013 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005014 buf = newbuf;
Howard Hinnant8ad6a222013-07-26 22:14:53 +00005015 if (n != nullptr)
5016 *n = sz;
5017 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005018 }
5019 if (buf != nullptr)
5020 {
5021 db.names.back().first += db.names.back().second;
5022 std::memcpy(buf, db.names.back().first.data(), sz-1);
5023 buf[sz-1] = char(0);
5024 }
5025 }
5026 else
5027 buf = nullptr;
5028 if (status)
5029 *status = internal_status;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005030 return buf;
5031}
5032
Howard Hinnant6c33e762013-06-17 18:10:34 +00005033} // __cxxabiv1