xref: /illumos-gate/usr/src/lib/libdemangle/common/cxx.c (revision 51396a8ee7fb52fe0ab33bfe7b4f495ad431904a)
1 /*
2  * Ported from LLVM's libcxxabi trunk/src/cxa_demangle.cpp
3  * LICENSE.TXT contents is available as ../THIRDPARTYLICENSE
4  *
5  *                     The LLVM Compiler Infrastructure
6  *
7  * This file is dual licensed under the MIT and the University of Illinois Open
8  * Source Licenses. See LICENSE.TXT for details.
9  *
10  */
11 
12 /*
13  * Copyright 2018 Jason King.
14  */
15 #include <ctype.h>
16 #include <errno.h>
17 #include <locale.h>
18 #include <note.h>
19 #include <string.h>
20 #include <setjmp.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sys/isa_defs.h>
24 #include <sys/debug.h>
25 #include "demangle-sys.h"
26 #include "demangle_int.h"
27 #include "cxx.h"
28 
29 #ifndef	ARRAY_SIZE
30 #define	ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
31 #endif
32 
33 #define	CPP_QUAL_CONST		(1U)
34 #define	CPP_QUAL_VOLATILE	(2U)
35 #define	CPP_QUAL_RESTRICT	(4U)
36 
37 typedef struct cpp_db_s {
38 	sysdem_ops_t	*cpp_ops;
39 	jmp_buf		cpp_jmp;
40 	name_t		cpp_name;
41 	sub_t		cpp_subs;
42 	templ_t		cpp_templ;
43 	unsigned	cpp_cv;
44 	unsigned	cpp_ref;
45 	unsigned	cpp_depth;
46 	boolean_t	cpp_parsed_ctor_dtor_cv;
47 	boolean_t	cpp_tag_templates;
48 	boolean_t	cpp_fix_forward_references;
49 	boolean_t	cpp_try_to_parse_template_args;
50 	locale_t	cpp_loc;
51 } cpp_db_t;
52 
53 #define	CK(x)						\
54 	do {						\
55 		if (!(x)) {				\
56 			longjmp(db->cpp_jmp, 1);	\
57 		}					\
58 	NOTE(CONSTCOND)					\
59 	} while (0)
60 
61 #define	TOP_L(db) (&(name_top(&(db)->cpp_name)->strp_l))
62 #define	RLEN(f, l) ((size_t)((l) - (f)))
63 #define	NAMT(db, n) (nlen(db) - n)
64 
65 static inline boolean_t is_xdigit(int);
66 
67 static boolean_t nempty(cpp_db_t *);
68 static size_t nlen(cpp_db_t *);
69 static void nadd_l(cpp_db_t *, const char *, size_t);
70 static void njoin(cpp_db_t *, size_t, const char *);
71 static void nfmt(cpp_db_t *, const char *, const char *);
72 
73 static void save_top(cpp_db_t *, size_t);
74 static void sub(cpp_db_t *, size_t);
75 
76 static boolean_t tempty(const cpp_db_t *);
77 static size_t ttlen(const cpp_db_t *);
78 
79 static void tsub(cpp_db_t *, size_t);
80 static void tpush(cpp_db_t *);
81 static void tpop(cpp_db_t *);
82 static void tsave(cpp_db_t *, size_t);
83 
84 static boolean_t db_init(cpp_db_t *, sysdem_ops_t *);
85 static void db_fini(cpp_db_t *);
86 static void dump(cpp_db_t *, FILE *);
87 
88 static void demangle(const char *, const char *, cpp_db_t *);
89 
90 static const char *parse_type(const char *, const char *, cpp_db_t *);
91 static const char *parse_builtin_type(const char *, const char *, cpp_db_t *);
92 static const char *parse_qual_type(const char *, const char *, cpp_db_t *);
93 static const char *parse_encoding(const char *, const char *, cpp_db_t *);
94 static const char *parse_dot_suffix(const char *, const char *, cpp_db_t *);
95 static const char *parse_block_invoke(const char *, const char *, cpp_db_t *);
96 static const char *parse_special_name(const char *, const char *, cpp_db_t *);
97 static const char *parse_name(const char *, const char *, boolean_t *,
98     cpp_db_t *);
99 static const char *parse_call_offset(const char *, const char *, locale_t);
100 static const char *parse_number(const char *, const char *, locale_t);
101 static const char *parse_nested_name(const char *, const char *, boolean_t *,
102     cpp_db_t *);
103 static const char *parse_local_name(const char *, const char *, boolean_t *,
104     cpp_db_t *);
105 static const char *parse_unscoped_name(const char *, const char *, cpp_db_t *);
106 static const char *parse_template_args(const char *, const char *, cpp_db_t *);
107 static const char *parse_substitution(const char *, const char *, cpp_db_t *);
108 static const char *parse_discriminator(const char *, const char *, locale_t);
109 static const char *parse_cv_qualifiers(const char *, const char *, unsigned *);
110 static const char *parse_template_param(const char *, const char *, cpp_db_t *);
111 static const char *parse_decltype(const char *, const char *, cpp_db_t *);
112 static const char *parse_template_args(const char *, const char *, cpp_db_t *);
113 static const char *parse_unqualified_name(const char *, const char *,
114     cpp_db_t *);
115 static const char *parse_template_arg(const char *, const char *, cpp_db_t *);
116 static const char *parse_expression(const char *, const char *, cpp_db_t *);
117 static const char *parse_expr_primary(const char *, const char *, cpp_db_t *);
118 static const char *parse_binary_expr(const char *, const char *,
119     const char *, cpp_db_t *);
120 static const char *parse_prefix_expr(const char *, const char *,
121     const char *, cpp_db_t *);
122 static const char *parse_gs(const char *, const char *, cpp_db_t *);
123 static const char *parse_idx_expr(const char *, const char *, cpp_db_t *);
124 static const char *parse_mm_expr(const char *, const char *, cpp_db_t *);
125 static const char *parse_pp_expr(const char *, const char *, cpp_db_t *);
126 static const char *parse_trinary_expr(const char *, const char *, cpp_db_t *);
127 static const char *parse_new_expr(const char *, const char *, cpp_db_t *);
128 static const char *parse_del_expr(const char *, const char *, cpp_db_t *);
129 static const char *parse_cast_expr(const char *, const char *, cpp_db_t *);
130 static const char *parse_sizeof_param_pack_expr(const char *, const char *,
131     cpp_db_t *);
132 static const char *parse_typeid_expr(const char *, const char *, cpp_db_t *);
133 static const char *parse_throw_expr(const char *, const char *, cpp_db_t *);
134 static const char *parse_dot_star_expr(const char *, const char *, cpp_db_t *);
135 static const char *parse_dot_expr(const char *, const char *, cpp_db_t *);
136 static const char *parse_call_expr(const char *, const char *, cpp_db_t *);
137 static const char *parse_arrow_expr(const char *, const char *, cpp_db_t *);
138 static const char *parse_conv_expr(const char *, const char *, cpp_db_t *);
139 static const char *parse_function_param(const char *, const char *, cpp_db_t *);
140 static const char *parse_base_unresolved_name(const char *, const char *,
141     cpp_db_t *);
142 static const char *parse_unresolved_name(const char *, const char *,
143     cpp_db_t *);
144 static const char *parse_noexcept_expr(const char *, const char *, cpp_db_t *);
145 static const char *parse_alignof(const char *, const char *, cpp_db_t *);
146 static const char *parse_sizeof(const char *, const char *, cpp_db_t *);
147 static const char *parse_unnamed_type_name(const char *, const char *,
148     cpp_db_t *);
149 static const char *parse_ctor_dtor_name(const char *, const char *, cpp_db_t *);
150 static const char *parse_source_name(const char *, const char *, cpp_db_t *);
151 static const char *parse_operator_name(const char *, const char *, cpp_db_t *);
152 static const char *parse_pack_expansion(const char *, const char *, cpp_db_t *);
153 static const char *parse_unresolved_type(const char *, const char *,
154     cpp_db_t *);
155 static const char *parse_unresolved_qualifier_level(const char *, const char *,
156     cpp_db_t *);
157 static const char *parse_destructor_name(const char *, const char *,
158     cpp_db_t *);
159 static const char *parse_function_type(const char *, const char *, cpp_db_t *);
160 static const char *parse_array_type(const char *, const char *, cpp_db_t *);
161 static const char *parse_pointer_to_member_type(const char *, const char *,
162     cpp_db_t *);
163 static const char *parse_vector_type(const char *, const char *, cpp_db_t *);
164 
165 size_t cpp_name_max_depth = 1024;	/* max depth of name stack */
166 
167 char *
168 cpp_demangle(const char *src, size_t srclen, sysdem_ops_t *ops)
169 {
170 	char *volatile result = NULL;
171 	cpp_db_t db;
172 
173 	if (!db_init(&db, ops))
174 		goto done;
175 	if (setjmp(db.cpp_jmp) != 0)
176 		goto done;
177 
178 	errno = 0;
179 	demangle(src, src + srclen, &db);
180 
181 	if (errno == 0 && db.cpp_fix_forward_references &&
182 	    !templ_empty(&db.cpp_templ) &&
183 	    !sub_empty(&db.cpp_templ.tpl_items[0])) {
184 		db.cpp_fix_forward_references = B_FALSE;
185 		db.cpp_tag_templates = B_FALSE;
186 		name_clear(&db.cpp_name);
187 		sub_clear(&db.cpp_subs);
188 
189 		if (setjmp(db.cpp_jmp) != 0)
190 			goto done;
191 
192 		demangle(src, src + srclen, &db);
193 
194 		if (db.cpp_fix_forward_references) {
195 			errno = EINVAL;
196 			goto done;
197 		}
198 	}
199 
200 	if (errno != 0)
201 		goto done;
202 
203 	if (nempty(&db)) {
204 		errno = EINVAL;
205 		goto done;
206 	}
207 
208 	njoin(&db, 1, "");
209 
210 	if (nlen(&db) > 0) {
211 		str_t *s = TOP_L(&db);
212 		char *res = zalloc(ops, s->str_len + 1);
213 		if (res == NULL)
214 			goto done;
215 
216 		(void) memcpy(res, s->str_s, s->str_len);
217 		result = res;
218 	}
219 
220 done:
221 	if (demangle_debug)
222 		dump(&db, stdout);
223 
224 	db_fini(&db);
225 	return (result);
226 }
227 
228 static void
229 demangle(const char *first, const char *last, cpp_db_t *db)
230 {
231 	const char *t = NULL;
232 
233 	if (first >= last) {
234 		errno = EINVAL;
235 		return;
236 	}
237 
238 	if (first[0] != '_') {
239 		t = parse_type(first, last, db);
240 		if (t == first) {
241 			errno = EINVAL;
242 			return;
243 		}
244 		goto done;
245 	}
246 
247 	if (last - first < 4) {
248 		errno = EINVAL;
249 		return;
250 	}
251 
252 	if (first[1] == 'Z') {
253 		t = parse_encoding(first + 2, last, db);
254 
255 		if (t != first + 2 && t != last && t[0] == '.') {
256 			t = parse_dot_suffix(t, last, db);
257 			if (nlen(db) > 1)
258 				njoin(db, 2, "");
259 		}
260 
261 		goto done;
262 	}
263 
264 	if (first[1] != '_' || first[2] != '_' || first[3] != 'Z')
265 		goto done;
266 
267 	t = parse_encoding(first + 4, last, db);
268 	if (t != first + 4 && t != last)
269 		t = parse_block_invoke(t, last, db);
270 
271 done:
272 	if (t != last)
273 		errno = EINVAL;
274 }
275 
276 static const char *
277 parse_dot_suffix(const char *first, const char *last, cpp_db_t *db)
278 {
279 	VERIFY3P(first, <=, last);
280 
281 	if (first == last || first[0] != '.')
282 		return (first);
283 
284 	if (nempty(db))
285 		return (first);
286 
287 	nadd_l(db, first, RLEN(first, last));
288 	nfmt(db, " ({0})", NULL);
289 
290 	return (last);
291 }
292 
293 /*
294  * _block_invoke
295  * _block_invoke<digit>*
296  * _block_invoke_<digit>+
297  */
298 static const char *
299 parse_block_invoke(const char *first, const char *last, cpp_db_t *db)
300 {
301 	VERIFY3P(first, <=, last);
302 
303 	if (last - first < 13)
304 		return (first);
305 
306 	const char test[] = "_block_invoke";
307 	const char *t = first;
308 
309 	if (strncmp(first, test, sizeof (test) - 1) != 0)
310 		return (first);
311 
312 	t += sizeof (test);
313 	if (t == last)
314 		goto done;
315 
316 	if (t[0] == '_') {
317 		/* need at least one digit */
318 		if (t + 1 == last || !isdigit_l(t[1], db->cpp_loc))
319 			return (first);
320 		t += 2;
321 	}
322 
323 	while (t < last && isdigit_l(t[0], db->cpp_loc))
324 		t++;
325 
326 done:
327 	if (nempty(db))
328 		return (first);
329 
330 	nfmt(db, "invocation function for block in {0}", NULL);
331 	return (t);
332 }
333 
334 /*
335  * <encoding> ::= <function name><bare-function-type>
336  *            ::= <data name>
337  *            ::= <special name>
338  */
339 static const char *
340 parse_encoding(const char *first, const char *last, cpp_db_t *db)
341 {
342 	VERIFY3P(first, <=, last);
343 
344 	if (first == last)
345 		return (first);
346 
347 	const char *t = NULL;
348 	const char *t2 = NULL;
349 	unsigned cv = 0;
350 	unsigned ref = 0;
351 	boolean_t tag_templ_save = db->cpp_tag_templates;
352 
353 	if (++db->cpp_depth > 1)
354 		db->cpp_tag_templates = B_TRUE;
355 
356 	if (first[0] == 'G' || first[0] == 'T') {
357 		t = parse_special_name(first, last, db);
358 		goto done;
359 	}
360 
361 	boolean_t ends_with_template_args = B_FALSE;
362 	t = parse_name(first, last, &ends_with_template_args, db);
363 	if (t == first)
364 		goto fail;
365 
366 	cv = db->cpp_cv;
367 	ref = db->cpp_ref;
368 
369 	if (t == last || t[0] == 'E' || t[0] == '.')
370 		goto done;
371 
372 	db->cpp_tag_templates = B_FALSE;
373 	if (nempty(db) || str_length(TOP_L(db)) == 0)
374 		goto fail;
375 
376 	if (!db->cpp_parsed_ctor_dtor_cv && ends_with_template_args) {
377 		t2 = parse_type(t, last, db);
378 		if (t2 == t || nlen(db) < 2)
379 			goto fail;
380 
381 		str_pair_t *sp = name_top(&db->cpp_name);
382 
383 		if (str_length(&sp->strp_r) == 0)
384 			(void) str_append(&sp->strp_l, " ", 1);
385 
386 		nfmt(db, "{0:L}{1:L}", "{1:R}{0:R}");
387 		t = t2;
388 	}
389 
390 	if (t == last || nempty(db))
391 		goto fail;
392 
393 	size_t n = nlen(db);
394 
395 	if (t[0] == 'v') {
396 		t++;
397 	} else {
398 		for (;;) {
399 			t2 = parse_type(t, last, db);
400 			if (t2 == t || t == last)
401 				break;
402 
403 			t = t2;
404 		}
405 	}
406 
407 	/*
408 	 * a bit of a hack, but a template substitution can apparently be
409 	 * an empty string at the end of an argument list, so avoid
410 	 * <...., >
411 	 */
412 	if (NAMT(db, n) > 1 && str_pair_len(name_top(&db->cpp_name)) == 0)
413 		name_pop(&db->cpp_name, NULL);
414 
415 	njoin(db, NAMT(db, n), ", ");
416 	nfmt(db, "({0})", NULL);
417 
418 	str_t *s = TOP_L(db);
419 
420 	if (cv & CPP_QUAL_CONST) {
421 		CK(str_append(s, " const", 0));
422 	}
423 	if (cv & CPP_QUAL_VOLATILE) {
424 		CK(str_append(s, " volatile", 0));
425 	}
426 	if (cv & CPP_QUAL_RESTRICT) {
427 		CK(str_append(s, " restrict", 0));
428 	}
429 	if (ref == 1) {
430 		CK(str_append(s, " &", 0));
431 	}
432 	if (ref == 2) {
433 		CK(str_append(s, " &&", 0));
434 	}
435 
436 	nfmt(db, "{1:L}{0}{1:R}", NULL);
437 
438 done:
439 	db->cpp_tag_templates = tag_templ_save;
440 	db->cpp_depth--;
441 	return (t);
442 
443 fail:
444 	db->cpp_tag_templates = tag_templ_save;
445 	db->cpp_depth--;
446 	return (first);
447 }
448 
449 /*
450  * <special-name> ::= TV <type>    # virtual table
451  *                ::= TT <type>    # VTT structure (construction vtable index)
452  *                ::= TI <type>    # typeinfo structure
453  *                ::= TS <type>    # typeinfo name (null-terminated byte string)
454  *                ::= Tc <call-offset> <call-offset> <base encoding>
455  *                    # base is the nominal target function of thunk
456  *                    # first call-offset is 'this' adjustment
457  *                    # second call-offset is result adjustment
458  *                ::= T <call-offset> <base encoding>
459  *                    # base is the nominal target function of thunk
460  *                ::= GV <object name> # Guard variable for one-time init
461  *                                     # No <type>
462  *                ::= TW <object name> # Thread-local wrapper
463  *                ::= TH <object name> # Thread-local initialization
464  *      extension ::= TC <first type> <number> _ <second type>
465  *                                     # construction vtable for second-in-first
466  *      extension ::= GR <object name> # reference temporary for object
467  */
468 static const char *
469 parse_special_name(const char *first, const char *last, cpp_db_t *db)
470 {
471 	VERIFY3P(first, <=, last);
472 
473 	const char *t = first;
474 	const char *t1 = NULL;
475 	size_t n = nlen(db);
476 
477 	if (last - first < 2)
478 		return (first);
479 
480 	switch (t[0]) {
481 	case 'T':
482 		switch (t[1]) {
483 		case 'V':
484 			nadd_l(db, "vtable for", 0);
485 			t = parse_type(first + 2, last, db);
486 			break;
487 		case 'T':
488 			nadd_l(db, "VTT for", 0);
489 			t = parse_type(first + 2, last, db);
490 			break;
491 		case 'I':
492 			nadd_l(db, "typeinfo for", 0);
493 			t = parse_type(first + 2, last, db);
494 			break;
495 		case 'S':
496 			nadd_l(db, "typeinfo name for", 0);
497 			t = parse_type(first + 2, last, db);
498 			break;
499 		case 'c':
500 			nadd_l(db, "covariant return thunk to", 0);
501 			t1 = parse_call_offset(first + 2, last, db->cpp_loc);
502 			if (t1 == t)
503 				return (first);
504 			t = parse_call_offset(t1, last, db->cpp_loc);
505 			if (t == t1)
506 				return (first);
507 			t1 = parse_encoding(t, last, db);
508 			if (t1 == t)
509 				return (first);
510 			break;
511 		case 'C':
512 			t = parse_type(first + 2, last, db);
513 			if (t == first + 2)
514 				return (first);
515 			t1 = parse_number(t, last, db->cpp_loc);
516 			if (*t1 != '_')
517 				return (first);
518 			t = parse_type(t1 + 1, last, db);
519 			if (t == t1 + 1 || nlen(db) < 2)
520 				return (first);
521 			nfmt(db, "construction vtable for {0}-in-{1}", NULL);
522 			return (t);
523 		case 'W':
524 			nadd_l(db, "thread-local wrapper routine for", 0);
525 			t = parse_name(first + 2, last, NULL, db);
526 			break;
527 		case 'H':
528 			nadd_l(db, "thread-local initialization routine for",
529 			    0);
530 			t = parse_name(first + 2, last, NULL, db);
531 			break;
532 		default:
533 			if (first[1] == 'v') {
534 				nadd_l(db, "virtual thunk to", 0);
535 			} else {
536 				nadd_l(db, "non-virtual thunk to", 0);
537 			}
538 
539 			t = parse_call_offset(first + 1, last, db->cpp_loc);
540 			if (t == first + 1)
541 				return (first);
542 			t1 = parse_encoding(t, last, db);
543 			if (t == t1)
544 				return (first);
545 			t = t1;
546 			break;
547 		}
548 		break;
549 	case 'G':
550 		switch (first[1]) {
551 		case 'V':
552 			nadd_l(db, "guard variable for", 0);
553 			t = parse_name(first + 2, last, NULL, db);
554 			break;
555 		case 'R':
556 			nadd_l(db, "reference temporary for", 0);
557 			t = parse_name(first + 2, last, NULL, db);
558 			break;
559 		default:
560 			return (first);
561 		}
562 		break;
563 	default:
564 		return (first);
565 	}
566 
567 	size_t amt = NAMT(db, n);
568 	if (t == first + 2 || amt < 2)
569 		return (first);
570 
571 	njoin(db, amt, " ");
572 	return (t);
573 }
574 
575 /*
576  * <call-offset> ::= h <nv-offset> _
577  *               ::= v <v-offset> _
578  *
579  * <nv-offset> ::= <offset number>
580  *               # non-virtual base override
581  *
582  * <v-offset>  ::= <offset number> _ <virtual offset number>
583  *               # virtual base override, with vcall offset
584  */
585 static const char *
586 parse_call_offset(const char *first, const char *last, locale_t loc)
587 {
588 	VERIFY3P(first, <=, last);
589 
590 	const char *t = NULL;
591 	const char *t1 = NULL;
592 
593 	if (first == last)
594 		return (first);
595 
596 	if (first[0] != 'h' && first[0] != 'v')
597 		return (first);
598 
599 	t = parse_number(first + 1, last, loc);
600 	if (t == first + 1 || t == last || t[0] != '_')
601 		return (first);
602 
603 	/* skip _ */
604 	t++;
605 
606 	if (first[0] == 'h')
607 		return (t);
608 
609 	t1 = parse_number(t, last, loc);
610 	if (t == t1 || t1 == last || t1[0] != '_')
611 		return (first);
612 
613 	/* skip _ */
614 	t1++;
615 
616 	return (t1);
617 }
618 
619 /*
620  * <name> ::= <nested-name> // N
621  *        ::= <local-name> # See Scope Encoding below  // Z
622  *        ::= <unscoped-template-name> <template-args>
623  *        ::= <unscoped-name>
624  *
625  * <unscoped-template-name> ::= <unscoped-name>
626  *                          ::= <substitution>
627  */
628 static const char *
629 parse_name(const char *first, const char *last,
630     boolean_t *ends_with_template_args, cpp_db_t *db)
631 {
632 	VERIFY3P(first, <=, last);
633 
634 	const char *t = first;
635 	const char *t1 = NULL;
636 
637 	if (last - first < 2)
638 		return (first);
639 
640 	/* extension: ignore L here */
641 	if (t[0] == 'L')
642 		t++;
643 
644 	switch (t[0]) {
645 	case 'N':
646 		t1 = parse_nested_name(t, last, ends_with_template_args, db);
647 		return ((t == t1) ? first : t1);
648 	case 'Z':
649 		t1 = parse_local_name(t, last, ends_with_template_args, db);
650 		return ((t == t1) ? first : t1);
651 	}
652 
653 	/*
654 	 * <unscoped-name>
655 	 * <unscoped-name> <template-args>
656 	 * <substitution> <template-args>
657 	 */
658 	t1 = parse_unscoped_name(t, last, db);
659 
660 	/* <unscoped-name> */
661 	if (t != t1 && t1[0] != 'I')
662 		return (t1);
663 
664 	if (t == t1) {
665 		t1 = parse_substitution(t, last, db);
666 		if (t == t1 || t1 == last || t1[0] != 'I')
667 			return (first);
668 	} else {
669 		save_top(db, 1);
670 	}
671 
672 	t = parse_template_args(t1, last, db);
673 	if (t1 == t || nlen(db) < 2)
674 		return (first);
675 
676 	nfmt(db, "{1:L}{0}", "{1:R}");
677 
678 	if (ends_with_template_args != NULL)
679 		*ends_with_template_args = B_TRUE;
680 
681 	return (t);
682 }
683 
684 /* BEGIN CSTYLED */
685 /*
686  * <local-name> := Z <function encoding> E <entity name> [<discriminator>]
687  *              := Z <function encoding> E s [<discriminator>]
688  *              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
689  */
690 /* END CSTYLED */
691 const char *
692 parse_local_name(const char *first, const char *last,
693     boolean_t *ends_with_template_args, cpp_db_t *db)
694 {
695 	VERIFY3P(first, <=, last);
696 
697 	const char *t = NULL;
698 	const char *t1 = NULL;
699 	const char *t2 = NULL;
700 
701 	if (first == last || first[0] != 'Z')
702 		return (first);
703 
704 	t = parse_encoding(first + 1, last, db);
705 	if (t == first + 1 || t == last || t[0] != 'E')
706 		return (first);
707 
708 	VERIFY(!nempty(db));
709 
710 	/* skip E */
711 	t++;
712 
713 	if (t[0] == 's') {
714 		nfmt(db, "{0:L}::string literal", "{0:R}");
715 		return (parse_discriminator(t, last, db->cpp_loc));
716 	}
717 
718 	if (t[0] == 'd') {
719 		t1 = parse_number(t + 1, last, db->cpp_loc);
720 		if (t1[0] != '_')
721 			return (first);
722 		t1++;
723 	} else {
724 		t1 = t;
725 	}
726 
727 	t2 = parse_name(t1, last, ends_with_template_args, db);
728 	if (t2 == t1)
729 		return (first);
730 
731 	nfmt(db, "{1:L}::{0}", "{1:R}");
732 
733 	/* parsed, but ignored */
734 	if (t[0] != 'd')
735 		t2 = parse_discriminator(t2, last, db->cpp_loc);
736 
737 	return (t2);
738 }
739 
740 /* BEGIN CSTYLED */
741 /*
742  * <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
743  *               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
744  *
745  * <prefix> ::= <prefix> <unqualified-name>
746  *          ::= <template-prefix> <template-args>
747  *          ::= <template-param>
748  *          ::= <decltype>
749  *          ::= # empty
750  *          ::= <substitution>
751  *          ::= <prefix> <data-member-prefix>
752  *  extension ::= L
753  *
754  * <template-prefix> ::= <prefix> <template unqualified-name>
755  *                   ::= <template-param>
756  *                   ::= <substitution>
757  */
758 /* END CSTYLED */
759 static const char *
760 parse_nested_name(const char *first, const char *last,
761     boolean_t *ends_with_template_args, cpp_db_t *db)
762 {
763 	VERIFY3P(first, <=, last);
764 
765 	if (first == last || first[0] != 'N')
766 		return (first);
767 
768 	unsigned cv = 0;
769 	const char *t = parse_cv_qualifiers(first + 1, last, &cv);
770 
771 	if (t == last)
772 		return (first);
773 
774 	boolean_t more = B_FALSE;
775 
776 	switch (t[0]) {
777 	case 'R':
778 		db->cpp_ref = 1;
779 		t++;
780 		break;
781 	case 'O':
782 		db->cpp_ref = 2;
783 		t++;
784 		break;
785 	case 'S':
786 		if (last - first < 2 || t[1] != 't')
787 			break;
788 		if (last - first == 2)
789 			return (first);
790 		nadd_l(db, "std", 3);
791 		more = B_TRUE;
792 		t += 2;
793 		break;
794 	}
795 
796 	boolean_t pop_subs = B_FALSE;
797 	boolean_t component_ends_with_template_args = B_FALSE;
798 
799 	while (t[0] != 'E' && t != last) {
800 		const char *t1 = NULL;
801 		size_t n = nlen(db);
802 		component_ends_with_template_args = B_FALSE;
803 
804 		switch (t[0]) {
805 		case 'S':
806 			if (t + 1 != last && t[1] == 't')
807 				break;
808 
809 			t1 = parse_substitution(t, last, db);
810 			if (t1 == t || t1 == last || NAMT(db, n) != 1)
811 				return (first);
812 
813 			if (!more) {
814 				nfmt(db, "{0}", NULL);
815 			} else {
816 				VERIFY3U(nlen(db), >, 1);
817 				nfmt(db, "{1:L}::{0}", "{1:R}");
818 				save_top(db, 1);
819 			}
820 
821 			more = B_TRUE;
822 			pop_subs = B_TRUE;
823 			t = t1;
824 			continue;
825 
826 		case 'T':
827 			t1 = parse_template_param(t, last, db);
828 			if (t1 == t || t1 == last || NAMT(db, n) != 1)
829 				return (first);
830 
831 			if (!more) {
832 				nfmt(db, "{0}", NULL);
833 			} else {
834 				VERIFY3U(nlen(db), >, 1);
835 				nfmt(db, "{1:L}::{0}", "{1:R}");
836 			}
837 
838 			save_top(db, 1);
839 			more = B_TRUE;
840 			pop_subs = B_TRUE;
841 			t = t1;
842 			continue;
843 
844 		case 'D':
845 			if (t + 1 != last && t[1] != 't' && t[1] != 'T')
846 				break;
847 			t1 = parse_decltype(t, last, db);
848 			if (t1 == t || t1 == last || NAMT(db, n) != 1)
849 				return (first);
850 
851 			if (!more) {
852 				nfmt(db, "{0}", NULL);
853 			} else {
854 				VERIFY3U(nlen(db), >, 1);
855 				nfmt(db, "{1:L}::{0}", "{1:R}");
856 			}
857 
858 			save_top(db, 1);
859 			more = B_TRUE;
860 			pop_subs = B_TRUE;
861 			t = t1;
862 			continue;
863 
864 		case 'I':
865 			/*
866 			 * Must have at least one component before
867 			 * <template-args>
868 			 */
869 			if (!more)
870 				return (first);
871 
872 			t1 = parse_template_args(t, last, db);
873 			if (t1 == t || t1 == last)
874 				return (first);
875 
876 			VERIFY3U(nlen(db), >, 1);
877 			nfmt(db, "{1:L}{0}", "{1:R}");
878 			save_top(db, 1);
879 			t = t1;
880 			component_ends_with_template_args = B_TRUE;
881 			continue;
882 
883 		case 'L':
884 			if (t + 1 == last)
885 				return (first);
886 			t++;
887 			continue;
888 
889 		default:
890 			break;
891 		}
892 
893 		t1 = parse_unqualified_name(t, last, db);
894 		if (t1 == t || t1 == last || NAMT(db, n) != 1)
895 			return (first);
896 
897 		if (!more) {
898 			nfmt(db, "{0}", NULL);
899 		} else {
900 			VERIFY3U(nlen(db), >, 1);
901 			nfmt(db, "{1:L}::{0}", "{1:R}");
902 		}
903 
904 		save_top(db, 1);
905 		more = B_TRUE;
906 		pop_subs = B_TRUE;
907 		t = t1;
908 	}
909 
910 	/* need to parse at least one thing */
911 	if (!more)
912 		return (first);
913 
914 	db->cpp_cv = cv;
915 	if (pop_subs && !sub_empty(&db->cpp_subs))
916 		sub_pop(&db->cpp_subs);
917 
918 	if (ends_with_template_args != NULL)
919 		*ends_with_template_args = component_ends_with_template_args;
920 
921 	if (t[0] != 'E')
922 		return (first);
923 
924 	return (t + 1);
925 }
926 
927 /*
928  * <template-arg> ::= <type>                   # type or template
929  *                ::= X <expression> E         # expression
930  *                ::= <expr-primary>           # simple expressions
931  *                ::= J <template-arg>* E      # argument pack
932  *                ::= LZ <encoding> E          # extension
933  */
934 static const char *
935 parse_template_arg(const char *first, const char *last, cpp_db_t *db)
936 {
937 	VERIFY3P(first, <=, last);
938 
939 	const char *t = NULL;
940 	const char *t1 = NULL;
941 
942 	if (first == last)
943 		return (first);
944 
945 	switch (first[0]) {
946 	case 'X':
947 		t = parse_expression(first + 1, last, db);
948 		if (t == first + 1 || t[0] != 'E')
949 			return (first);
950 
951 		/* E */
952 		t++;
953 		break;
954 
955 	case 'J':
956 		t = first + 1;
957 		if (t == last)
958 			return (first);
959 
960 		while (t[0] != 'E') {
961 			t1 = parse_template_arg(t, last, db);
962 			if (t == t1)
963 				return (first);
964 			t = t1;
965 		}
966 
967 		/* E */
968 		t++;
969 		break;
970 
971 	case 'L':
972 		if (first + 1 == last || first[1] != 'Z') {
973 			t = parse_expr_primary(first, last, db);
974 		} else {
975 			t = parse_encoding(first + 2, last, db);
976 			if (t == first + 2 || t == last || t[0] != 'E')
977 				return (first);
978 
979 			/* E */
980 			t++;
981 		}
982 		break;
983 
984 	default:
985 		t = parse_type(first, last, db);
986 	}
987 
988 	return (t);
989 }
990 
991 /* BEGIN CSTYLED */
992 /*
993  * <expression> ::= <unary operator-name> <expression>
994  *              ::= <binary operator-name> <expression> <expression>
995  *              ::= <ternary operator-name> <expression> <expression> <expression>
996  *              ::= cl <expression>+ E                                   # call
997  *              ::= cv <type> <expression>                               # conversion with one argument
998  *              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments
999  *              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type
1000  *              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
1001  *              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
1002  *              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
1003  *              ::= [gs] dl <expression>                                 # delete expression
1004  *              ::= [gs] da <expression>                                 # delete[] expression
1005  *              ::= pp_ <expression>                                     # prefix ++
1006  *              ::= mm_ <expression>                                     # prefix --
1007  *              ::= ti <type>                                            # typeid (type)
1008  *              ::= te <expression>                                      # typeid (expression)
1009  *              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)
1010  *              ::= sc <type> <expression>                               # static_cast<type> (expression)
1011  *              ::= cc <type> <expression>                               # const_cast<type> (expression)
1012  *              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)
1013  *              ::= st <type>                                            # sizeof (a type)
1014  *              ::= sz <expression>                                      # sizeof (an expression)
1015  *              ::= at <type>                                            # alignof (a type)
1016  *              ::= az <expression>                                      # alignof (an expression)
1017  *              ::= nx <expression>                                      # noexcept (expression)
1018  *              ::= <template-param>
1019  *              ::= <function-param>
1020  *              ::= dt <expression> <unresolved-name>                    # expr.name
1021  *              ::= pt <expression> <unresolved-name>                    # expr->name
1022  *              ::= ds <expression> <expression>                         # expr.*expr
1023  *              ::= sZ <template-param>                                  # size of a parameter pack
1024  *              ::= sZ <function-param>                                  # size of a function parameter pack
1025  *              ::= sp <expression>                                      # pack expansion
1026  *              ::= tw <expression>                                      # throw expression
1027  *              ::= tr                                                   # throw with no operand (rethrow)
1028  *              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),
1029  *                                                                       # freestanding dependent name (e.g., T::x),
1030  *                                                                       # objectless nonstatic member reference
1031  *              ::= <expr-primary>
1032  */
1033 /* END CSTYLED */
1034 
1035 #define	PA(cd, arg, fn) {	\
1036 	.code = cd,		\
1037 	.p.parse_expr_arg = fn,	\
1038 	.fntype = EXPR_ARG,	\
1039 	.val = arg		\
1040 }
1041 
1042 #define	PN(cd, fn) {			\
1043 	.code = cd,			\
1044 	.p.parse_expr_noarg = fn,	\
1045 	.fntype = EXPR_NOARG		\
1046 }
1047 
1048 static struct {
1049 	const char code[3];
1050 	union {
1051 		const char *(*parse_expr_arg)(const char *, const char *,
1052 		    const char *, cpp_db_t *);
1053 		const char *(*parse_expr_noarg)(const char *, const char *,
1054 		    cpp_db_t *);
1055 	} p;
1056 	enum {
1057 		EXPR_ARG,
1058 		EXPR_NOARG
1059 	} fntype;
1060 	const char val[4];
1061 } expr_tbl[] = {
1062 	PA("aN", "&=", parse_binary_expr),
1063 	PA("aS", "=", parse_binary_expr),
1064 	PA("aa", "&&", parse_binary_expr),
1065 	PA("ad", "&", parse_prefix_expr),
1066 	PA("an", "&", parse_binary_expr),
1067 	PN("at", parse_alignof),
1068 	PN("az", parse_alignof),
1069 	PN("cc", parse_cast_expr),
1070 	PN("cl", parse_call_expr),
1071 	PA("cm", ",", parse_binary_expr),
1072 	PA("co", "~", parse_prefix_expr),
1073 	PN("cv", parse_conv_expr),
1074 	PN("da", parse_del_expr),
1075 	PA("dV", "/=", parse_binary_expr),
1076 	PN("dc", parse_cast_expr),
1077 	PA("de", "*", parse_prefix_expr),
1078 	PN("dl", parse_del_expr),
1079 	PN("dn", parse_unresolved_name),
1080 	PN("ds", parse_dot_star_expr),
1081 	PN("dt", parse_dot_expr),
1082 	PA("dv", "/", parse_binary_expr),
1083 	PA("eO", "^=", parse_binary_expr),
1084 	PA("eo", "^", parse_binary_expr),
1085 	PA("eq", "==", parse_binary_expr),
1086 	PA("ge", ">=", parse_binary_expr),
1087 	PN("gs", parse_gs),
1088 	PA("gt", ">", parse_binary_expr),
1089 	PN("ix", parse_idx_expr),
1090 	PA("lS", "<<=", parse_binary_expr),
1091 	PA("le", "<=", parse_binary_expr),
1092 	PA("ls", "<<", parse_binary_expr),
1093 	PA("lt", "<", parse_binary_expr),
1094 	PA("mI", "-=", parse_binary_expr),
1095 	PA("mL", "*=", parse_binary_expr),
1096 	PN("mm", parse_mm_expr),
1097 	PA("mi", "-", parse_binary_expr),
1098 	PA("ml", "*", parse_binary_expr),
1099 	PN("na", parse_new_expr),
1100 	PA("ne", "!=", parse_binary_expr),
1101 	PA("ng", "-", parse_prefix_expr),
1102 	PA("nt", "!", parse_prefix_expr),
1103 	PN("nw", parse_new_expr),
1104 	PN("nx", parse_noexcept_expr),
1105 	PA("oR", "|=", parse_binary_expr),
1106 	PN("on", parse_unresolved_name),
1107 	PA("oo", "||", parse_binary_expr),
1108 	PA("or", "|", parse_binary_expr),
1109 	PA("pL", "+=", parse_binary_expr),
1110 	PA("pl", "+", parse_binary_expr),
1111 	PA("pm", "->*", parse_binary_expr),
1112 	PN("pp", parse_pp_expr),
1113 	PA("ps", "+", parse_prefix_expr),
1114 	PN("pt", parse_arrow_expr),
1115 	PN("qu", parse_trinary_expr),
1116 	PA("rM", "%=", parse_binary_expr),
1117 	PA("rS", ">>=", parse_binary_expr),
1118 	PN("rc", parse_cast_expr),
1119 	PA("rm", "%", parse_binary_expr),
1120 	PA("rs", ">>", parse_binary_expr),
1121 	PN("sc", parse_cast_expr),
1122 	PN("sp", parse_pack_expansion),
1123 	PN("sr", parse_unresolved_name),
1124 	PN("st", parse_sizeof),
1125 	PN("sz", parse_sizeof),
1126 	PN("sZ", parse_sizeof_param_pack_expr),
1127 	PN("te", parse_typeid_expr),
1128 	PN("tr", parse_throw_expr),
1129 	PN("tw", parse_throw_expr)
1130 };
1131 #undef PA
1132 #undef PN
1133 
1134 static const char *
1135 parse_expression(const char *first, const char *last, cpp_db_t *db)
1136 {
1137 	VERIFY3P(first, <=, last);
1138 
1139 	if (last - first < 2)
1140 		return (first);
1141 
1142 	for (size_t i = 0; i < ARRAY_SIZE(expr_tbl); i++) {
1143 		if (strncmp(expr_tbl[i].code, first, 2) != 0)
1144 			continue;
1145 		switch (expr_tbl[i].fntype) {
1146 		case EXPR_ARG:
1147 			return (expr_tbl[i].p.parse_expr_arg(first, last,
1148 			    expr_tbl[i].val, db));
1149 		case EXPR_NOARG:
1150 			return (expr_tbl[i].p.parse_expr_noarg(first, last,
1151 			    db));
1152 		}
1153 	}
1154 
1155 	switch (first[0]) {
1156 	case 'L':
1157 		return (parse_expr_primary(first, last, db));
1158 	case 'T':
1159 		return (parse_template_param(first, last, db));
1160 	case 'f':
1161 		return (parse_function_param(first, last, db));
1162 	case '1':
1163 	case '2':
1164 	case '3':
1165 	case '4':
1166 	case '5':
1167 	case '6':
1168 	case '7':
1169 	case '8':
1170 	case '9':
1171 		return (parse_unresolved_name(first, last, db));
1172 	}
1173 
1174 	return (first);
1175 }
1176 
1177 static const char *
1178 parse_binary_expr(const char *first, const char *last, const char *op,
1179     cpp_db_t *db)
1180 {
1181 	VERIFY3P(first, <=, last);
1182 
1183 	if (last - first < 2)
1184 		return (first);
1185 
1186 	size_t n = nlen(db);
1187 
1188 	const char *t1 = parse_expression(first + 2, last, db);
1189 	if (t1 == first + 2)
1190 		return (first);
1191 
1192 	nadd_l(db, op, 0);
1193 
1194 	const char *t2 = parse_expression(t1, last, db);
1195 	if (t2 == t1)
1196 		return (first);
1197 
1198 	if (NAMT(db, n) != 3)
1199 		return (first);
1200 
1201 	VERIFY3U(nlen(db), >, 2);
1202 
1203 	nfmt(db, "({2}) {1} ({0})", NULL);
1204 	if (strcmp(op, ">") == 0)
1205 		nfmt(db, "({0})", NULL);
1206 
1207 	return (t2);
1208 }
1209 
1210 static const char *
1211 parse_prefix_expr(const char *first, const char *last, const char *op,
1212     cpp_db_t *db)
1213 {
1214 	VERIFY3P(first, <=, last);
1215 
1216 	if (last - first < 2)
1217 		return (first);
1218 
1219 	nadd_l(db, op, 0);
1220 
1221 	const char *t = parse_expression(first + 2, last, db);
1222 	if (t == first + 2) {
1223 		return (first);
1224 	}
1225 
1226 	VERIFY3U(nlen(db), >, 1);
1227 
1228 	nfmt(db, "{1}({0})", NULL);
1229 	return (t);
1230 }
1231 
1232 static const char *
1233 parse_gs(const char *first, const char *last, cpp_db_t *db)
1234 {
1235 	VERIFY3P(first, <=, last);
1236 
1237 	const char *t = NULL;
1238 
1239 	if (last - first < 4)
1240 		return (first);
1241 
1242 	if (first[2] == 'n' && (first[3] == 'a' || first[3] == 'w'))
1243 		t = parse_new_expr(first + 2, last, db);
1244 	else if (first[2] == 'd' && (first[3] == 'l' || first[3] == 'a'))
1245 		t = parse_del_expr(first + 2, last, db);
1246 	else
1247 		return (first);
1248 
1249 	if (t == first + 2)
1250 		return (first);
1251 
1252 	VERIFY3U(nlen(db), >, 0);
1253 
1254 	nfmt(db, "::{0}", NULL);
1255 	return (t);
1256 }
1257 
1258 /*
1259  * [gs] nw <expression>* _ <type> E		# new (expr-list) type
1260  * [gs] nw <expression>* _ <type> <initializer>	# new (expr-list) type (init)
1261  * [gs] na <expression>* _ <type> E		# new[] (expr-list) type
1262  * [gs] na <expression>* _ <type> <initializer>	# new[] (expr-list) type (init)
1263  * <initializer> ::= pi <expression>* E		# parenthesized initialization
1264  */
1265 static const char *
1266 parse_new_expr(const char *first, const char *last, cpp_db_t *db)
1267 {
1268 	VERIFY3P(first, <=, last);
1269 
1270 	/* note [gs] is already handled by parse_gs() */
1271 	if (last - first < 3)
1272 		return (first);
1273 
1274 	VERIFY3U(first[0], ==, 'n');
1275 	VERIFY(first[1] == 'a' || first[1] == 'w');
1276 
1277 	const char *t1 = first + 2;
1278 	const char *t2 = NULL;
1279 	size_t n = nlen(db);
1280 
1281 	nadd_l(db, (first[1] == 'w') ? "new" : "new[]", 0);
1282 
1283 	while (t1 != last && t1[0] != '_') {
1284 		t2 = parse_expression(t1, last, db);
1285 		VERIFY3P(t2, !=, NULL);
1286 		if (t2 == t1)
1287 			return (first);
1288 		t1 = t2;
1289 	}
1290 	if (t1 == last)
1291 		return (first);
1292 
1293 	if (NAMT(db, n) > 1) {
1294 		njoin(db, NAMT(db, n) - 1, ", ");
1295 		nfmt(db, "({0})", NULL);
1296 	}
1297 
1298 	t2 = parse_type(t1 + 1, last, db);
1299 	if (t1 + 1 == t2)
1300 		return (first);
1301 
1302 	if (t2[0] != 'E') {
1303 		if (last - t2 < 3)
1304 			return (first);
1305 		if (t2[0] != 'p' && t2[1] != 'i')
1306 			return (first);
1307 
1308 		t2 += 2;
1309 		const char *t3 = t2;
1310 		size_t n1 = nlen(db);
1311 
1312 		while (t2[0] != 'E' && t2 != last) {
1313 			t3 = parse_expression(t2, last, db);
1314 
1315 			if (t2 == t3)
1316 				return (first);
1317 			t2 = t3;
1318 		}
1319 		if (t3 == last || t3[0] != 'E')
1320 			return (first);
1321 
1322 		if (NAMT(db, n1) > 0) {
1323 			njoin(db, NAMT(db, n1), ", ");
1324 			nfmt(db, "({0})", NULL);
1325 		}
1326 	}
1327 
1328 	njoin(db, NAMT(db, n), " ");
1329 	return (t2 + 1);
1330 }
1331 
1332 static const char *
1333 parse_del_expr(const char *first, const char *last, cpp_db_t *db)
1334 {
1335 	VERIFY3P(first, <=, last);
1336 
1337 	if (last - first < 3)
1338 		return (first);
1339 
1340 	VERIFY3U(first[0], ==, 'd');
1341 	VERIFY(first[1] == 'l' || first[1] == 'a');
1342 
1343 	size_t n = nlen(db);
1344 	const char *t = parse_expression(first + 2, last, db);
1345 	if (t == first + 2 || NAMT(db, n) != 1)
1346 		return (first);
1347 
1348 	nfmt(db, (first[1] == 'a') ? "delete[] {0}" : "delete {0}", NULL);
1349 	return (t);
1350 }
1351 
1352 static const char *
1353 parse_idx_expr(const char *first, const char *last, cpp_db_t *db)
1354 {
1355 	VERIFY3P(first, <=, last);
1356 	VERIFY3U(first[0], ==, 'i');
1357 	VERIFY3U(first[1], ==, 'x');
1358 
1359 	size_t n = nlen(db);
1360 	const char *t1 = parse_expression(first + 2, last, db);
1361 	if (t1 == first + 2)
1362 		return (first);
1363 
1364 	const char *t2 = parse_expression(t1, last, db);
1365 	if (t2 == t1 || NAMT(db, n) != 2)
1366 		return (first);
1367 
1368 	nfmt(db, "({0})[{1}]", NULL);
1369 	return (t2);
1370 }
1371 
1372 static const char *
1373 parse_ppmm_expr(const char *first, const char *last, const char *fmt,
1374     cpp_db_t *db)
1375 {
1376 	VERIFY3P(first, <=, last);
1377 
1378 	if (last - first < 3)
1379 		return (first);
1380 
1381 	const char *t = NULL;
1382 	size_t n = nlen(db);
1383 
1384 	if (first[2] == '_') {
1385 		t = parse_binary_expr(first + 3, last, "--", db);
1386 		if (t == first + 3)
1387 			return (first);
1388 		return (t);
1389 	}
1390 
1391 	t = parse_expression(first + 2, last, db);
1392 	if (t == first + 2 || NAMT(db, n) < 1)
1393 		return (first);
1394 
1395 	nfmt(db, fmt, NULL);
1396 	return (t);
1397 }
1398 
1399 static const char *
1400 parse_mm_expr(const char *first, const char *last, cpp_db_t *db)
1401 {
1402 	VERIFY3P(first, <=, last);
1403 	VERIFY3U(first[0], ==, 'm');
1404 	VERIFY3U(first[1], ==, 'm');
1405 
1406 	return (parse_ppmm_expr(first, last, "({0})--", db));
1407 }
1408 
1409 static const char *
1410 parse_pp_expr(const char *first, const char *last, cpp_db_t *db)
1411 {
1412 	VERIFY3P(first, <=, last);
1413 
1414 	VERIFY3U(first[0], ==, 'p');
1415 	VERIFY3U(first[0], ==, 'p');
1416 
1417 	return (parse_ppmm_expr(first, last, "({0})++", db));
1418 }
1419 
1420 static const char *
1421 parse_trinary_expr(const char *first, const char *last, cpp_db_t *db)
1422 {
1423 	VERIFY3P(first, <=, last);
1424 
1425 	const char *t1, *t2, *t3;
1426 	size_t n = nlen(db);
1427 
1428 	if (last - first < 2)
1429 		return (first);
1430 
1431 	t1 = parse_expression(first + 2, last, db);
1432 	if (t1 == first + 2)
1433 		return (first);
1434 	t2 = parse_expression(t1, last, db);
1435 	if (t1 == t2)
1436 		return (first);
1437 	t3 = parse_expression(t2, last, db);
1438 	if (t3 == t2)
1439 		return (first);
1440 
1441 	if (NAMT(db, n) != 3)
1442 		return (first);
1443 
1444 	nfmt(db, "({2}) ? ({1}) : ({0})", NULL);
1445 	return (t3);
1446 }
1447 
1448 static const char *
1449 parse_noexcept_expr(const char *first, const char *last, cpp_db_t *db)
1450 {
1451 	VERIFY3P(first, <=, last);
1452 
1453 	if (last - first < 2)
1454 		return (first);
1455 
1456 	size_t n = nlen(db);
1457 	const char *t = parse_expression(first + 2, last, db);
1458 	if (t == first + 2 || NAMT(db, n) != 1)
1459 		return (first);
1460 
1461 	nfmt(db, "noexcept ({0})", NULL);
1462 	return (t);
1463 }
1464 
1465 /*
1466  * cc <type> <expression>	# const_cast<type> (expression)
1467  * dc <type> <expression>	# dynamic_cast<type> (expression)
1468  * rc <type> <expression>	# reinterpret_cast<type> (expression)
1469  * sc <type> <expression>	# static_cast<type> (expression)
1470  */
1471 static const char *
1472 parse_cast_expr(const char *first, const char *last, cpp_db_t *db)
1473 {
1474 	VERIFY3P(first, <=, last);
1475 
1476 	if (last - first < 2)
1477 		return (first);
1478 
1479 	const char *fmt = NULL;
1480 	switch (first[0]) {
1481 	case 'c':
1482 		fmt = "const_cast<{1}> ({0})";
1483 		break;
1484 	case 'd':
1485 		fmt = "dynamic_cast<{1}> ({0})";
1486 		break;
1487 	case 'r':
1488 		fmt = "reinterpret_cast<{1}> ({0})";
1489 		break;
1490 	case 's':
1491 		fmt = "static_cast<{1}> ({0})";
1492 		break;
1493 	default:
1494 		return (first);
1495 	}
1496 
1497 	VERIFY3U(first[1], ==, 'c');
1498 
1499 	const char *t1 = parse_type(first + 2, last, db);
1500 	if (t1 == first + 2)
1501 		return (first);
1502 
1503 	const char *t2 = parse_expression(t1, last, db);
1504 	if (t2 == t1)
1505 		return (first);
1506 
1507 	VERIFY3U(nlen(db), >, 1);
1508 
1509 	nfmt(db, fmt, NULL);
1510 	return (t2);
1511 }
1512 
1513 /* pt <expression> <expression>		# expr->name */
1514 static const char *
1515 parse_arrow_expr(const char *first, const char *last, cpp_db_t *db)
1516 {
1517 	VERIFY3P(first, <=, last);
1518 
1519 	if (last - first < 4)
1520 		return (first);
1521 
1522 	size_t n = nlen(db);
1523 
1524 	const char *t1 = parse_expression(first + 2, last, db);
1525 	if (t1 == first + 2)
1526 		return (first);
1527 
1528 	const char *t2 = parse_expression(t1, last, db);
1529 	if (t2 == t1 || NAMT(db, n) != 2)
1530 		return (first);
1531 
1532 	nfmt(db, "{1}->{0}", NULL);
1533 	return (t2);
1534 }
1535 
1536 /* wrap value in () when necessary */
1537 static void
1538 paren(str_pair_t *sp)
1539 {
1540 	str_t *l = &sp->strp_l;
1541 	str_t *r = &sp->strp_r;
1542 
1543 	if (str_length(r) > 1 &&
1544 	    r->str_s[0] == ' ' && r->str_s[1] == '[') {
1545 		(void) str_append(l, " (", 2);
1546 		(void) str_insert(r, 0, ")", 1);
1547 	} else if (str_length(r) > 0 && r->str_s[0] == '(') {
1548 		(void) str_append(l, "(", 1);
1549 		(void) str_insert(r, 0, ")", 1);
1550 	}
1551 }
1552 
1553 /* BEGIN CSTYLED */
1554 /*
1555  * <type> ::= <builtin-type>
1556  *        ::= <function-type>
1557  *        ::= <class-enum-type>
1558  *        ::= <array-type>
1559  *        ::= <pointer-to-member-type>
1560  *        ::= <template-param>
1561  *        ::= <template-template-param> <template-args>
1562  *        ::= <decltype>
1563  *        ::= <substitution>
1564  *        ::= <CV-qualifiers> <type>
1565  *        ::= P <type>        # pointer-to
1566  *        ::= R <type>        # reference-to
1567  *        ::= O <type>        # rvalue reference-to (C++0x)
1568  *        ::= C <type>        # complex pair (C 2000)
1569  *        ::= G <type>        # imaginary (C 2000)
1570  *        ::= Dp <type>       # pack expansion (C++0x)
1571  *        ::= U <source-name> <type>  # vendor extended type qualifier
1572  * extension := U <objc-name> <objc-type>  # objc-type<identifier>
1573  * extension := <vector-type> # <vector-type> starts with Dv
1574  *
1575  * <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
1576  * <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
1577  */
1578 /* END CSTYLED */
1579 static const char *
1580 parse_type(const char *first, const char *last, cpp_db_t *db)
1581 {
1582 	VERIFY3P(first, <=, last);
1583 
1584 	if (first == last)
1585 		return (first);
1586 
1587 	switch (first[0]) {
1588 	case 'r':
1589 	case 'V':
1590 	case 'K':
1591 		return (parse_qual_type(first, last, db));
1592 	}
1593 
1594 	const char *t = first;
1595 	const char *t1 = NULL;
1596 	str_pair_t *sp = NULL;
1597 	size_t n = nlen(db);
1598 	size_t amt = 0;
1599 
1600 	t = parse_builtin_type(first, last, db);
1601 	if (t != first)
1602 		return (t);
1603 
1604 	switch (first[0]) {
1605 	case 'A':
1606 		t = parse_array_type(first, last, db);
1607 		if (t == first || NAMT(db, n) == 0)
1608 			return (first);
1609 		save_top(db, 1);
1610 		return (t);
1611 
1612 	case 'C':
1613 		t = parse_type(first + 1, last, db);
1614 		if (t == first + 1 || NAMT(db, n) == 0)
1615 			return (first);
1616 
1617 		(void) str_append(TOP_L(db), " complex", 8);
1618 		save_top(db, 1);
1619 		return (t);
1620 
1621 	case 'F':
1622 		t = parse_function_type(first, last, db);
1623 		if (t == first || NAMT(db, n) == 0)
1624 			return (first);
1625 		save_top(db, 1);
1626 		return (t);
1627 
1628 	case 'G':
1629 		t = parse_type(first + 1, last, db);
1630 		if (t == first + 1 || NAMT(db, n) == 0)
1631 			return (first);
1632 
1633 		(void) str_append(TOP_L(db), " imaginary", 10);
1634 		save_top(db, 1);
1635 		return (t);
1636 
1637 	case 'M':
1638 		t = parse_pointer_to_member_type(first, last, db);
1639 		if (t == first || NAMT(db, n) == 0)
1640 			return (first);
1641 		save_top(db, 1);
1642 		return (t);
1643 
1644 	case 'O':
1645 		t = parse_type(first + 1, last, db);
1646 		amt = NAMT(db, n);
1647 		if (t == first + 1 || amt == 0)
1648 			return (first);
1649 
1650 		sp = name_at(&db->cpp_name, amt - 1);
1651 		for (size_t i = 0; i < amt; i++, sp++) {
1652 			paren(sp);
1653 			if (str_pair_len(sp) > 0)
1654 				(void) str_append(&sp->strp_l, "&&", 2);
1655 		}
1656 
1657 		save_top(db, amt);
1658 		return (t);
1659 
1660 	case 'P':
1661 		t = parse_type(first + 1, last, db);
1662 		amt = NAMT(db, n);
1663 		if (t == first + 1 || amt == 0)
1664 			return (first);
1665 
1666 		sp = name_at(&db->cpp_name, amt - 1);
1667 		for (size_t i = 0; i < amt; i++, sp++) {
1668 			str_t *l = &sp->strp_l;
1669 
1670 			if (str_pair_len(sp) == 0)
1671 				continue;
1672 
1673 			paren(sp);
1674 			if (first[1] != 'U' ||
1675 			    strncmp(l->str_s, "objc_object<", 12) != 0) {
1676 				(void) str_append(l, "*", 1);
1677 			} else {
1678 				(void) str_erase(l, 0, 11);
1679 				(void) str_insert(l, 0, "id", 2);
1680 			}
1681 		}
1682 		save_top(db, amt);
1683 		return (t);
1684 
1685 	case 'R':
1686 		t = parse_type(first + 1, last, db);
1687 		amt = NAMT(db, n);
1688 		if (t == first + 1 || amt == 0)
1689 			return (first);
1690 
1691 		sp = name_at(&db->cpp_name, amt - 1);
1692 		for (size_t i = 0; i < amt; i++, sp++) {
1693 			if (str_length(&sp->strp_l) == 0 &&
1694 			    str_length(&sp->strp_r) == 0)
1695 				continue;
1696 
1697 			paren(sp);
1698 			(void) str_append(&sp->strp_l, "&", 1);
1699 		}
1700 
1701 		save_top(db, amt);
1702 		return (t);
1703 
1704 	case 'T':
1705 		t = parse_template_param(first, last, db);
1706 		if (t == first)
1707 			return (first);
1708 
1709 		amt = NAMT(db, n);
1710 		save_top(db, amt);
1711 		if (!db->cpp_try_to_parse_template_args || amt != 1)
1712 			return (t);
1713 
1714 		t1 = parse_template_args(t, last, db);
1715 		if (t1 == t)
1716 			return (t);
1717 
1718 		nfmt(db, "{1:L}{0}", "{1:R}");
1719 		save_top(db, 1);
1720 		return (t1);
1721 
1722 	case 'U':
1723 		if (first + 1 == last)
1724 			return (first);
1725 
1726 		t = parse_source_name(first + 1, last, db);
1727 		if (t == first + 1)
1728 			return (first);
1729 
1730 		nfmt(db, "{0}", NULL);
1731 
1732 		t1 = parse_type(t, last, db);
1733 		if (t1 == t || NAMT(db, n) < 2)
1734 			return (first);
1735 
1736 		const str_t *name = &name_at(&db->cpp_name, 1)->strp_l;
1737 
1738 		if (str_length(name) > 0 &&
1739 		    strncmp(name->str_s, "objcproto", 9) != 0) {
1740 			nfmt(db, "{0} {1}", NULL);
1741 		} else {
1742 			t = parse_source_name(name->str_s + 9,
1743 			    name->str_s + name->str_len, db);
1744 			if (t != name->str_s + 9) {
1745 				nfmt(db, "{1}<{0}>", NULL);
1746 
1747 				str_pair_t save = {0};
1748 
1749 				name_pop(&db->cpp_name, &save);
1750 
1751 				/* get rid of 'objcproto' */
1752 				name_pop(&db->cpp_name, NULL);
1753 				CK(name_add_str(&db->cpp_name, &save.strp_l,
1754 				    &save.strp_r));
1755 			} else {
1756 				nfmt(db, "{1} {0}", NULL);
1757 			}
1758 		}
1759 
1760 		save_top(db, 1);
1761 		return (t1);
1762 
1763 	case 'S':
1764 		if (first + 1 != last && first[1] == 't') {
1765 			t = parse_name(first, last, NULL, db);
1766 			if (t == first || NAMT(db, n) == 0)
1767 				return (first);
1768 
1769 			save_top(db, 1);
1770 			return (t);
1771 		}
1772 
1773 		t = parse_substitution(first, last, db);
1774 		if (t == first)
1775 			return (first);
1776 
1777 		/*
1778 		 * If the substitution is a <template-param>, it might
1779 		 * be followed by <template-args>
1780 		 */
1781 		t1 = parse_template_args(t, last, db);
1782 		if (t1 == t)
1783 			return (t);
1784 
1785 		if (NAMT(db, n) < 2)
1786 			return (t);
1787 
1788 		nfmt(db, "{1:L}{0}", "{1:R}");
1789 		save_top(db, 1);
1790 		return (t1);
1791 
1792 	case 'D':
1793 		if (first + 1 == last)
1794 			return (first);
1795 
1796 		switch (first[1]) {
1797 		case 'p':
1798 			t = parse_type(first + 2, last, db);
1799 			if (t == first + 2)
1800 				break;
1801 
1802 			save_top(db, NAMT(db, n));
1803 			return (t);
1804 
1805 		case 't':
1806 		case 'T':
1807 			t = parse_decltype(first, last, db);
1808 			if (first == t)
1809 				break;
1810 
1811 			save_top(db, 1);
1812 			return (t);
1813 
1814 		case 'v':
1815 			t = parse_vector_type(first, last, db);
1816 			if (first == t)
1817 				break;
1818 
1819 			if (NAMT(db, n) == 0)
1820 				return (first);
1821 
1822 			save_top(db, 1);
1823 			return (t);
1824 		}
1825 		break;
1826 	}
1827 
1828 	/*
1829 	 * must check for builtin-types before class-enum-types to avoid
1830 	 * ambiguities with operator-names
1831 	 */
1832 	t = parse_builtin_type(first, last, db);
1833 	if (t != first)
1834 		return (t);
1835 
1836 	t = parse_name(first, last, NULL, db);
1837 	if (t == first || NAMT(db, n) == 0)
1838 		return (first);
1839 
1840 	save_top(db, 1);
1841 	return (t);
1842 }
1843 
1844 static const char *
1845 parse_qual_type(const char *first, const char *last, cpp_db_t *db)
1846 {
1847 	VERIFY3P(first, <=, last);
1848 
1849 	const char *t = NULL;
1850 	const char *t1 = NULL;
1851 	unsigned cv = 0;
1852 
1853 	t = parse_cv_qualifiers(first, last, &cv);
1854 	if (t == first)
1855 		return (first);
1856 
1857 	size_t n = nlen(db);
1858 	boolean_t is_func = !!(t[0] == 'F');
1859 
1860 	t1 = parse_type(t, last, db);
1861 	size_t amt = NAMT(db, n);
1862 	if (t == t1 || amt == 0)
1863 		return (first);
1864 
1865 	if (is_func)
1866 		sub_pop(&db->cpp_subs);
1867 
1868 	str_pair_t *sp = name_at(&db->cpp_name, amt - 1);
1869 
1870 	for (size_t i = 0; i < amt; i++, sp++) {
1871 		str_t *s = NULL;
1872 
1873 		if (!is_func) {
1874 			s = &sp->strp_l;
1875 
1876 			if (str_length(s) == 0)
1877 				continue;
1878 
1879 			if (cv & 1)
1880 				(void) str_append(s, " const", 6);
1881 			if (cv & 2)
1882 				(void) str_append(s, " volatile", 9);
1883 			if (cv & 4)
1884 				(void) str_append(s, " restrict", 9);
1885 
1886 			continue;
1887 		}
1888 
1889 		s = &sp->strp_r;
1890 		size_t pos = str_length(s);
1891 
1892 		if (pos > 0 && s->str_s[pos - 1] == '&') {
1893 			pos--;
1894 			if (s->str_s[pos - 1] == '&')
1895 				pos--;
1896 		}
1897 
1898 		if (cv & 1) {
1899 			(void) str_insert(s, pos, " const", 6);
1900 			pos += 6;
1901 		}
1902 		if (cv & 2) {
1903 			(void) str_insert(s, pos, " volatile", 9);
1904 			pos += 9;
1905 		}
1906 		if (cv & 4) {
1907 			(void) str_insert(s, pos, " restrict", 9);
1908 		}
1909 	}
1910 
1911 	save_top(db, amt);
1912 	return (t1);
1913 }
1914 
1915 /*
1916  * at <type>		# alignof (a type)
1917  * az <expression>	# alignof (a expression)
1918  */
1919 static const char *
1920 parse_alignof(const char *first, const char *last, cpp_db_t *db)
1921 {
1922 	VERIFY3P(first, <=, last);
1923 
1924 	if (last - first < 2)
1925 		return (first);
1926 
1927 	const char *(*fn)(const char *, const char *, cpp_db_t *);
1928 
1929 	fn = (first[1] == 't') ? parse_type : parse_expression;
1930 
1931 	size_t n = nlen(db);
1932 	const char *t = fn(first + 2, last, db);
1933 	if (t == first + 2 || NAMT(db, n) != 1)
1934 		return (first);
1935 
1936 	nfmt(db, "alignof ({0})", NULL);
1937 	return (t);
1938 }
1939 
1940 /*
1941  * st <type>	# sizeof (a type)
1942  * sz <expr>	# sizeof (a expression)
1943  */
1944 static const char *
1945 parse_sizeof(const char *first, const char *last, cpp_db_t *db)
1946 {
1947 	VERIFY3P(first, <=, last);
1948 
1949 	if (last - first < 2)
1950 		return (first);
1951 
1952 	VERIFY3U(first[0], ==, 's');
1953 
1954 	const char *t = NULL;
1955 	size_t n = nlen(db);
1956 
1957 	switch (first[1]) {
1958 	case 't':
1959 		t = parse_type(first + 2, last, db);
1960 		break;
1961 	case 'z':
1962 		t = parse_expression(first + 2, last, db);
1963 		break;
1964 	default:
1965 		return (first);
1966 	}
1967 	if (t == first + 2 || NAMT(db, n) != 1)
1968 		return (first);
1969 
1970 	nfmt(db, "sizeof ({0})", NULL);
1971 	return (t);
1972 }
1973 
1974 /* BEGIN CSTYLED */
1975 /*
1976  * <function-param> ::= fp <top-level CV-qualifiers> _                                     # L == 0, first parameter
1977  *                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
1978  *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter
1979  *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
1980  */
1981 /* END CSTYLED */
1982 static const char *
1983 parse_function_param(const char *first, const char *last, cpp_db_t *db)
1984 {
1985 	VERIFY3P(first, <=, last);
1986 
1987 	if (last - first < 3 || first[0] != 'f')
1988 		return (first);
1989 
1990 	const char *t1 = first + 2;
1991 	const char *t2 = NULL;
1992 	unsigned cv = 0;
1993 
1994 	if (first[1] == 'L') {
1995 		t2 = parse_number(t1, last, db->cpp_loc);
1996 		if (t2 == last || t2[0] != 'p')
1997 			return (first);
1998 		t1 = t2;
1999 	}
2000 
2001 	if (first[1] != 'p')
2002 		return (first);
2003 
2004 	t1 = parse_cv_qualifiers(t1, last, &cv);
2005 	t2 = parse_number(t1, last, db->cpp_loc);
2006 	if (t2 == last || t2[0] != '_')
2007 		return (first);
2008 
2009 	if (t2 - t1 > 0)
2010 		nadd_l(db, t1, (size_t)(t2 - t1));
2011 	else
2012 		nadd_l(db, "", 0);
2013 
2014 	nfmt(db, "fp{0}", NULL);
2015 	return (t2 + 1);
2016 }
2017 
2018 /*
2019  * sZ <template-param>		# size of a parameter pack
2020  * sZ <function-param>		# size of a function parameter pack
2021  */
2022 static const char *
2023 parse_sizeof_param_pack_expr(const char *first, const char *last, cpp_db_t *db)
2024 {
2025 	VERIFY3P(first, <=, last);
2026 
2027 	if (last - first < 3)
2028 		return (first);
2029 
2030 	VERIFY3U(first[0], ==, 's');
2031 	VERIFY3U(first[1], ==, 'Z');
2032 
2033 	if (first[2] != 'T' && first[2] != 'f')
2034 		return (first);
2035 
2036 	const char *t = NULL;
2037 	size_t n = nlen(db);
2038 
2039 	if (first[2] == 'T')
2040 		t = parse_template_param(first + 2, last, db);
2041 	else
2042 		t = parse_function_param(first + 2, last, db);
2043 
2044 	if (t == first + 2)
2045 		return (first);
2046 
2047 	njoin(db, NAMT(db, n), ", ");
2048 	nfmt(db, "sizeof...({0})", NULL);
2049 	return (t);
2050 }
2051 
2052 /*
2053  * te <expression>                                      # typeid (expression)
2054  * ti <type>                                            # typeid (type)
2055  */
2056 static const char *
2057 parse_typeid_expr(const char *first, const char *last, cpp_db_t *db)
2058 {
2059 	VERIFY3P(first, <=, last);
2060 
2061 	if (last - first < 3)
2062 		return (first);
2063 
2064 	VERIFY3U(first[0], ==, 't');
2065 	VERIFY(first[1] == 'e' || first[1] == 'i');
2066 
2067 	const char *t = NULL;
2068 	size_t n = nlen(db);
2069 
2070 	if (first[1] == 'e')
2071 		t = parse_expression(first + 2, last, db);
2072 	else
2073 		t = parse_type(first + 2, last, db);
2074 
2075 	if (t == first + 2 || NAMT(db, n) != 1)
2076 		return (first);
2077 
2078 	nfmt(db, "typeid ({0})", NULL);
2079 	return (t);
2080 }
2081 
2082 /*
2083  * tr							# throw
2084  * tw <expression>					# throw expression
2085  */
2086 static const char *
2087 parse_throw_expr(const char *first, const char *last, cpp_db_t *db)
2088 {
2089 	VERIFY3P(first, <=, last);
2090 
2091 	if (last - first < 3)
2092 		return (first);
2093 
2094 	VERIFY3U(first[0], ==, 't');
2095 	VERIFY(first[1] == 'w' || first[1] == 'r');
2096 
2097 	if (first[1] == 'r') {
2098 		nadd_l(db, "throw", 0);
2099 		return (first + 2);
2100 	}
2101 
2102 	size_t n = nlen(db);
2103 	const char *t = parse_expression(first + 2, last, db);
2104 	if (t == first + 2 || NAMT(db, n) != 1)
2105 		return (first);
2106 
2107 	nfmt(db, "throw {0}", NULL);
2108 	return (t);
2109 }
2110 
2111 /* ds <expression> <expression>		# expr.*expr */
2112 static const char *
2113 parse_dot_star_expr(const char *first, const char *last, cpp_db_t *db)
2114 {
2115 	VERIFY3P(first, <=, last);
2116 
2117 	if (last - first < 3)
2118 		return (first);
2119 
2120 	VERIFY3U(first[0], ==, 'd');
2121 	VERIFY3U(first[1], ==, 's');
2122 
2123 	size_t n = nlen(db);
2124 	const char *t = parse_expression(first + 2, last, db);
2125 	if (t == first + 2)
2126 		return (first);
2127 
2128 	const char *t2 = parse_expression(t, last, db);
2129 	if (t == t2 || NAMT(db, n) != 2)
2130 		return (first);
2131 
2132 	nfmt(db, "{1}.*{0}", NULL);
2133 	return (t2);
2134 }
2135 
2136 /* dt <expression> <unresolved-name>		# expr.name */
2137 static const char *
2138 parse_dot_expr(const char *first, const char *last, cpp_db_t *db)
2139 {
2140 	VERIFY3P(first, <=, last);
2141 
2142 	if (last - first < 3)
2143 		return (first);
2144 
2145 	VERIFY3U(first[0], ==, 'd');
2146 	VERIFY3U(first[1], ==, 't');
2147 
2148 	const char *t = parse_expression(first + 2, last, db);
2149 	if (t == first + 2)
2150 		return (first);
2151 
2152 	const char *t1 = parse_unresolved_name(t, last, db);
2153 	if (t1 == t)
2154 		return (first);
2155 
2156 	nfmt(db, "{1}.{0}", NULL);
2157 	return (t1);
2158 }
2159 
2160 /* cl <expression>+ E		# call */
2161 static const char *
2162 parse_call_expr(const char *first, const char *last, cpp_db_t *db)
2163 {
2164 	VERIFY3P(first, <=, last);
2165 
2166 	if (last - first < 4)
2167 		return (first);
2168 
2169 	VERIFY3U(first[0], ==, 'c');
2170 	VERIFY3U(first[1], ==, 'l');
2171 
2172 	const char *t = first + 2;
2173 	const char *t1 = NULL;
2174 	size_t n = nlen(db);
2175 
2176 	for (t = first + 2; t != last && t[0] != 'E'; t = t1) {
2177 		t1 = parse_expression(t, last, db);
2178 		if (t1 == t)
2179 			return (first);
2180 	}
2181 
2182 	size_t amt = NAMT(db, n);
2183 
2184 	if (t == last || amt == 0)
2185 		return (first);
2186 
2187 	njoin(db, amt - 1, ", ");
2188 	nfmt(db, "{1}({0})", NULL);
2189 
2190 	VERIFY3U(t[0], ==, 'E');
2191 	return (t + 1);
2192 }
2193 
2194 /* BEGIN CSTYLED */
2195 /*
2196  * cv <type> <expression>	# conversion with one argument
2197  * cv <type> _ <expression>* E	# conversion with a different number of arguments
2198  */
2199 /* END CSTYLED */
2200 static const char *
2201 parse_conv_expr(const char *first, const char *last, cpp_db_t *db)
2202 {
2203 	VERIFY3P(first, <=, last);
2204 
2205 	if (last - first < 3)
2206 		return (first);
2207 
2208 	VERIFY3U(first[0], ==, 'c');
2209 	VERIFY3U(first[1], ==, 'v');
2210 
2211 	const char *t = NULL;
2212 	const char *t1 = NULL;
2213 	size_t n = nlen(db);
2214 
2215 	boolean_t try_to_parse_template_args =
2216 	    db->cpp_try_to_parse_template_args;
2217 
2218 	db->cpp_try_to_parse_template_args = B_FALSE;
2219 	t = parse_type(first + 2, last, db);
2220 	db->cpp_try_to_parse_template_args = try_to_parse_template_args;
2221 
2222 	if (t == first + 2)
2223 		return (first);
2224 
2225 	if (t[0] != '_') {
2226 		t1 = parse_expression(t, last, db);
2227 		if (t1 == t)
2228 			return (first);
2229 
2230 		t = t1;
2231 	} else {
2232 		size_t n1 = nlen(db);
2233 
2234 		/* skip _ */
2235 		t++;
2236 		while (t[0] != 'E' && t != last) {
2237 			t1 = parse_expression(t, last, db);
2238 			if (t1 == t)
2239 				return (first);
2240 			t1 = t;
2241 		}
2242 
2243 		/* E */
2244 		t++;
2245 
2246 		njoin(db, NAMT(db, n1), ", ");
2247 	}
2248 
2249 	if (NAMT(db, n) < 2)
2250 		return (first);
2251 
2252 	nfmt(db, "({1})({0})", NULL);
2253 	return (t);
2254 }
2255 
2256 /* <simple-id> ::= <source-name> [ <template-args> ] */
2257 static const char *
2258 parse_simple_id(const char *first, const char *last, cpp_db_t *db)
2259 {
2260 	VERIFY3P(first, <=, last);
2261 
2262 	const char *t = parse_source_name(first, last, db);
2263 	if (t == first)
2264 		return (t);
2265 
2266 	const char *t1 = parse_template_args(t, last, db);
2267 	if (t == t1)
2268 		return (t);
2269 
2270 	nfmt(db, "{1}{0}", NULL);
2271 	return (t1);
2272 }
2273 
2274 /*
2275  * <unresolved-type> ::= <template-param>
2276  *                   ::= <decltype>
2277  *                   ::= <substitution>
2278  */
2279 static const char *
2280 parse_unresolved_type(const char *first, const char *last, cpp_db_t *db)
2281 {
2282 	VERIFY3P(first, <=, last);
2283 
2284 	if (first == last)
2285 		return (first);
2286 
2287 	const char *t = first;
2288 	size_t n = nlen(db);
2289 
2290 	switch (first[0]) {
2291 	case 'T':
2292 		t = parse_template_param(first, last, db);
2293 		if (t == first || NAMT(db, n) != 1) {
2294 			for (size_t i = 0; i < NAMT(db, n); i++)
2295 				name_pop(&db->cpp_name, NULL);
2296 			return (first);
2297 		}
2298 		save_top(db, 1);
2299 		return (t);
2300 
2301 	case 'D':
2302 		t = parse_decltype(first, last, db);
2303 		if (t == first || NAMT(db, n) == 0)
2304 			return (first);
2305 		save_top(db, 1);
2306 		return (t);
2307 
2308 	case 'S':
2309 		t = parse_substitution(first, last, db);
2310 		if (t != first)
2311 			return (t);
2312 
2313 		if (last - first < 2 || first[1] != 't')
2314 			return (first);
2315 
2316 		t = parse_unqualified_name(first + 2, last, db);
2317 		if (t == first + 2 || NAMT(db, n) == 0)
2318 			return (first);
2319 
2320 		nfmt(db, "std::{0:L}", "{0:R}");
2321 		save_top(db, 1);
2322 		return (t);
2323 	}
2324 
2325 	return (first);
2326 }
2327 
2328 /* sp <expression>		# pack expansion */
2329 static const char *
2330 parse_pack_expansion(const char *first, const char *last, cpp_db_t *db)
2331 {
2332 	VERIFY3P(first, <=, last);
2333 
2334 	if (last - first < 3)
2335 		return (first);
2336 
2337 	VERIFY3U(first[0], ==, 's');
2338 	VERIFY3U(first[1], ==, 'p');
2339 
2340 	const char *t = parse_expression(first + 2, last, db);
2341 	if (t == first +2)
2342 		return (first);
2343 
2344 	return (t);
2345 }
2346 
2347 /*
2348  * <unscoped-name> ::= <unqualified-name>
2349  *                 ::= St <unqualified-name>   # ::std::
2350  * extension       ::= StL<unqualified-name>
2351  */
2352 static const char *
2353 parse_unscoped_name(const char *first, const char *last, cpp_db_t *db)
2354 {
2355 	VERIFY3P(first, <=, last);
2356 
2357 	if (last - first < 2)
2358 		return (first);
2359 
2360 	const char *t = first;
2361 	const char *t1 = NULL;
2362 	boolean_t st = B_FALSE;
2363 
2364 	if (first[0] == 'S' && first[1] == 't') {
2365 		st = B_TRUE;
2366 		t = first + 2;
2367 
2368 		if (first + 3 != last && first[2] == 'L')
2369 			t++;
2370 	}
2371 
2372 	t1 = parse_unqualified_name(t, last, db);
2373 	if (t == t1)
2374 		return (first);
2375 
2376 	if (st)
2377 		nfmt(db, "std::{0}", NULL);
2378 
2379 	return (t1);
2380 }
2381 
2382 /*
2383  * <unqualified-name> ::= <operator-name>
2384  *                    ::= <ctor-dtor-name>
2385  *                    ::= <source-name>
2386  *                    ::= <unnamed-type-name>
2387  */
2388 const char *
2389 parse_unqualified_name(const char *first, const char *last, cpp_db_t *db)
2390 {
2391 	VERIFY3P(first, <=, last);
2392 
2393 	if (first == last)
2394 		return (first);
2395 
2396 	switch (*first) {
2397 	case 'C':
2398 	case 'D':
2399 		return (parse_ctor_dtor_name(first, last, db));
2400 	case 'U':
2401 		return (parse_unnamed_type_name(first, last, db));
2402 
2403 	case '1':
2404 	case '2':
2405 	case '3':
2406 	case '4':
2407 	case '5':
2408 	case '6':
2409 	case '7':
2410 	case '8':
2411 	case '9':
2412 		return (parse_source_name(first, last, db));
2413 	default:
2414 		return (parse_operator_name(first, last, db));
2415 	}
2416 }
2417 
2418 /*
2419  * <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
2420  *                     ::= <closure-type-name>
2421  *
2422  * <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2423  *
2424  * <lambda-sig> ::= <parameter type>+
2425  *			# Parameter types or "v" if the lambda has no parameters
2426  */
2427 static const char *
2428 parse_unnamed_type_name(const char *first, const char *last, cpp_db_t *db)
2429 {
2430 	VERIFY3P(first, <=, last);
2431 
2432 	if (last - first < 2 || first[0] != 'U')
2433 		return (first);
2434 
2435 	if (first[1] != 't' && first[1] != 'l')
2436 		return (first);
2437 
2438 	const char *t1 = first + 2;
2439 	const char *t2 = NULL;
2440 
2441 	if (first[1] == 't') {
2442 		while (t1 != last && t1[0] != '_' &&
2443 		    isdigit_l(t1[0], db->cpp_loc))
2444 			t1++;
2445 
2446 		if (t1[0] != '_')
2447 			return (first);
2448 
2449 		if (t1 == first + 2)
2450 			nadd_l(db, "", 0);
2451 		else
2452 			nadd_l(db, first + 2, (size_t)(t1 - first - 2));
2453 
2454 		nfmt(db, "'unnamed{0}'", NULL);
2455 		return (t1 + 1);
2456 	}
2457 
2458 	size_t n = nlen(db);
2459 
2460 	if (first[2] != 'v') {
2461 		do {
2462 			t2 = parse_type(t1, last, db);
2463 			if (t1 == t2)
2464 				return (first);
2465 			t1 = t2;
2466 		} while (t1 != last && t1[0] != 'E');
2467 
2468 		if (t1 == last || NAMT(db, n) < 1)
2469 			return (first);
2470 
2471 		if (NAMT(db, n) < 1)
2472 			return (first);
2473 	} else {
2474 		t1++;
2475 		if (t1[0] != 'E')
2476 			return (first);
2477 	}
2478 
2479 	njoin(db, NAMT(db, n), ", ");
2480 
2481 	/* E */
2482 	t1++;
2483 
2484 	t2 = t1;
2485 	while (t2 != last && t2[0] != '_') {
2486 		if (!isdigit_l(*t2++, db->cpp_loc))
2487 			return (first);
2488 	}
2489 
2490 	if (t2[0] != '_')
2491 		return (first);
2492 
2493 	if (t2 - t1 > 0)
2494 		nadd_l(db, t1, (size_t)(t2 - t1));
2495 	else
2496 		nadd_l(db, "", 0);
2497 
2498 	nfmt(db, "'lambda{0}'({1})", NULL);
2499 
2500 	/* _ */
2501 	return (t2 + 1);
2502 }
2503 
2504 static struct {
2505 	const char *alias;
2506 	const char *fullname;
2507 	const char *basename;
2508 } aliases[] = {
2509 	{
2510 		"std::string",
2511 		"std::basic_string<char, std::char_traits<char>, "
2512 		    "std::allocator<char> >",
2513 		"basic_string"
2514 	},
2515 	{
2516 		"std::istream",
2517 		"std::basic_istream<char, std::char_traits<char> >",
2518 		"basic_istream"
2519 	},
2520 	{
2521 		"std::ostream",
2522 		"std::basic_ostream<char, std::char_traits<char> >",
2523 		"basic_ostream"
2524 	},
2525 	{
2526 		"std::iostream",
2527 		"std::basic_iostream<char, std::char_traits<char> >",
2528 		"basic_iostream"
2529 	}
2530 };
2531 
2532 static void
2533 basename(cpp_db_t *db)
2534 {
2535 	str_t *s = TOP_L(db);
2536 
2537 	for (size_t i = 0; i < ARRAY_SIZE(aliases); i++) {
2538 		if (str_length(s) != strlen(aliases[i].alias))
2539 			continue;
2540 		if (strncmp(aliases[i].alias, s->str_s, str_length(s)) != 0)
2541 			continue;
2542 
2543 		/* swap out alias for full name */
2544 		sysdem_ops_t *ops = s->str_ops;
2545 		str_fini(s);
2546 		str_init(s, ops);
2547 		str_set(s, aliases[i].fullname, 0);
2548 
2549 		nadd_l(db, aliases[i].basename, 0);
2550 		return;
2551 	}
2552 
2553 	const char *start = s->str_s;
2554 	const char *end = s->str_s + s->str_len;
2555 
2556 	/*
2557 	 * if name ends with a template i.e. <.....> back up to start
2558 	 * of outermost template
2559 	 */
2560 	unsigned c = 0;
2561 
2562 	if (end[-1] == '>') {
2563 		for (; end > start; end--) {
2564 			switch (end[-1]) {
2565 			case '<':
2566 				if (--c == 0) {
2567 					end--;
2568 					goto out;
2569 				}
2570 				break;
2571 			case '>':
2572 				c++;
2573 				break;
2574 			}
2575 		}
2576 	}
2577 
2578 out:
2579 	VERIFY3P(end, >=, start);
2580 
2581 	if (end - start < 2) {
2582 		nadd_l(db, "", 0);
2583 		return;
2584 	}
2585 
2586 	for (start = end - 1; start > s->str_s; start--) {
2587 		if (start[0] == ':') {
2588 			start++;
2589 			break;
2590 		}
2591 	}
2592 
2593 	VERIFY3P(end, >=, start);
2594 
2595 	nadd_l(db, start, (size_t)(end - start));
2596 }
2597 
2598 /*
2599  * <ctor-dtor-name> ::= C1    # complete object constructor
2600  *                  ::= C2    # base object constructor
2601  *                  ::= C3    # complete object allocating constructor
2602  *   extension      ::= C5    # ?
2603  *                  ::= D0    # deleting destructor
2604  *                  ::= D1    # complete object destructor
2605  *                  ::= D2    # base object destructor
2606  *   extension      ::= D5    # ?
2607  */
2608 static const char *
2609 parse_ctor_dtor_name(const char *first, const char *last, cpp_db_t *db)
2610 {
2611 	VERIFY3P(first, <=, last);
2612 
2613 	if (last - first < 2 || nempty(db) || str_length(TOP_L(db)) == 0)
2614 		return (first);
2615 
2616 	switch (first[0]) {
2617 	case 'C':
2618 		switch (first[1]) {
2619 		case '1':
2620 		case '2':
2621 		case '3':
2622 		case '5':
2623 			basename(db);
2624 			break;
2625 		default:
2626 			return (first);
2627 		}
2628 		break;
2629 	case 'D':
2630 		switch (first[1]) {
2631 		case '0':
2632 		case '1':
2633 		case '2':
2634 		case '5':
2635 			basename(db);
2636 			(void) str_insert(TOP_L(db), 0, "~", 1);
2637 			break;
2638 		default:
2639 			return (first);
2640 		}
2641 		break;
2642 	default:
2643 		return (first);
2644 	}
2645 
2646 	db->cpp_parsed_ctor_dtor_cv = B_TRUE;
2647 	return (first + 2);
2648 }
2649 
2650 static const char *
2651 parse_integer_literal(const char *first, const char *last, const char *fmt,
2652     cpp_db_t *db)
2653 {
2654 	VERIFY3P(first, <=, last);
2655 
2656 	const char *t = parse_number(first, last, db->cpp_loc);
2657 	const char *start = first;
2658 
2659 	if (t == first || t == last || t[0] != 'E')
2660 		return (first);
2661 
2662 	if (first[0] == 'n')
2663 		start++;
2664 
2665 	nadd_l(db, start, (size_t)(t - start));
2666 	if (start != first)
2667 		nfmt(db, "-{0}", NULL);
2668 
2669 	nfmt(db, fmt, NULL);
2670 	return (t + 1);
2671 }
2672 
2673 static struct float_data_s {
2674 	const char *spec;
2675 	size_t mangled_size;
2676 	size_t max_demangled_size;
2677 	char type;
2678 } float_info[] = {
2679 	{ "%af", 8, 24, 'f' },		/* float */
2680 	{ "%a", 16, 32, 'd' },		/* double */
2681 	{ "%LaL", 20, 40, 'e' }		/* long double */
2682 };
2683 
2684 static const char *
2685 parse_floating_literal(const char *first, const char *last, cpp_db_t *db)
2686 {
2687 	VERIFY3P(first, <=, last);
2688 	VERIFY(first[0] == 'f' || first[0] == 'd' || first[0] == 'e');
2689 
2690 	const struct float_data_s *fd = NULL;
2691 
2692 	for (size_t i = 0; i < ARRAY_SIZE(float_info); i++) {
2693 		if (float_info[i].type != first[0])
2694 			continue;
2695 
2696 		fd = &float_info[i];
2697 		break;
2698 	}
2699 
2700 	if (fd == NULL || (size_t)(last - first) < fd->mangled_size)
2701 		return (first);
2702 
2703 	union {
2704 		union {
2705 			float v;
2706 			char buf[sizeof (float)];
2707 		} f;
2708 		union {
2709 			double v;
2710 			char buf[sizeof (double)];
2711 		} d;
2712 		union {
2713 			long double v;
2714 			char buf[sizeof (long double)];
2715 		} ld;
2716 	} conv;
2717 
2718 	const char *t = NULL;
2719 	char *e = NULL;
2720 
2721 	switch (first[0]) {
2722 	case 'f':
2723 		e = conv.f.buf;
2724 		break;
2725 	case 'd':
2726 		e = conv.d.buf;
2727 		break;
2728 	case 'e':
2729 		e = conv.ld.buf;
2730 		break;
2731 	}
2732 	last = first + fd->mangled_size + 1;
2733 
2734 #if defined(_BIG_ENDIAN)
2735 	for (t = first + 1; t != last; t++, e++) {
2736 		if (!is_xdigit(t[0]))
2737 			return (first);
2738 
2739 		unsigned d1 = isdigit_l(t[0], db->cpp_loc) ?
2740 		    t[0] - '0' : t[0] - 'a' + 10;
2741 		t++;
2742 		unsigned d0 = isdigit_l(t[0], db->cpp_loc) ?
2743 		    t[0] - '0' : t[0] - 'a' + 10;
2744 
2745 		*e = (d1 << 4) + d0;
2746 	}
2747 #elif defined(_LITTLE_ENDIAN)
2748 	for (t = last - 1; t > first; t--, e++) {
2749 		if (!is_xdigit(t[0]))
2750 			return (first);
2751 
2752 		unsigned d0 = isdigit_l(t[0], db->cpp_loc) ?
2753 		    t[0] - '0' : t[0] - 'a' + 10;
2754 		t--;
2755 		unsigned d1 = isdigit_l(t[0], db->cpp_loc) ?
2756 		    t[0] - '0' : t[0] - 'a' + 10;
2757 
2758 		*e = (d1 << 4) + d0;
2759 	}
2760 	t = last;
2761 #else
2762 #error One of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined
2763 #endif
2764 
2765 	if (t[0] != 'E')
2766 		return (first);
2767 
2768 	str_t num = { 0 };
2769 	str_init(&num, db->cpp_ops);
2770 
2771 	num.str_size = fd->max_demangled_size + 1;
2772 	num.str_s = zalloc(db->cpp_ops, num.str_size);
2773 	CK(num.str_s != NULL);
2774 
2775 	int n = 0;
2776 
2777 	switch (first[0]) {
2778 	case 'f':
2779 		n = snprintf(num.str_s, fd->max_demangled_size, fd->spec,
2780 		    conv.f.v);
2781 		break;
2782 	case 'd':
2783 		n = snprintf(num.str_s, fd->max_demangled_size, fd->spec,
2784 		    conv.d.v);
2785 		break;
2786 	case 'e':
2787 		n = snprintf(num.str_s, fd->max_demangled_size, fd->spec,
2788 		    conv.ld.v);
2789 	}
2790 
2791 	if (n >= fd->max_demangled_size || n <= 0) {
2792 		str_fini(&num);
2793 		return (first);
2794 	}
2795 
2796 	num.str_len = n;
2797 	(void) name_add_str(&db->cpp_name, &num, NULL);
2798 
2799 	return (t + 1);
2800 }
2801 
2802 /*
2803  * <expr-primary> ::= L <type> <value number> E	# integer literal
2804  *                ::= L <type> <value float> E	# floating literal
2805  *                ::= L <string type> E		# string literal
2806  *                ::= L <nullptr type> E	# nullptr literal (i.e., "LDnE")
2807  *
2808  *                ::= L <type> <real-part float> _ <imag-part float> E
2809  *						# complex floating point
2810  *						# literal (C 2000)
2811  *
2812  *                ::= L <mangled-name> E	# external name
2813  */
2814 static struct {
2815 	int		c;
2816 	const char	*fmt;
2817 } int_lits[] = {
2818 	{ 'a', "(signed char){0}" },
2819 	{ 'c', "(char){0}" },
2820 	{ 'h', "(unsigned char){0}" },
2821 	{ 'i', "{0}" },
2822 	{ 'j', "{0}u" },
2823 	{ 'l', "{0}l" },
2824 	{ 'm', "{0}ul" },
2825 	{ 'n', "(__int128){0}" },
2826 	{ 'o', "(unsigned __int128){0}" },
2827 	{ 's', "(short){0}" },
2828 	{ 't', "(unsigned short){0}" },
2829 	{ 'w', "(wchar_t){0}" },
2830 	{ 'x', "{0}ll" },
2831 	{ 'y', "{0}ull" }
2832 };
2833 
2834 static const char *
2835 parse_expr_primary(const char *first, const char *last, cpp_db_t *db)
2836 {
2837 	VERIFY3P(first, <=, last);
2838 
2839 	if (last - first < 4 || first[0] != 'L')
2840 		return (first);
2841 
2842 	const char *t = NULL;
2843 
2844 	for (size_t i = 0; i < ARRAY_SIZE(int_lits); i++) {
2845 		if (first[1] == int_lits[i].c) {
2846 			t = parse_integer_literal(first + 2, last,
2847 			    int_lits[i].fmt, db);
2848 			return ((t == first + 2) ? first : t);
2849 		}
2850 	}
2851 
2852 	switch (first[1]) {
2853 	case 'b':
2854 		if (first[3] != 'E')
2855 			return (first);
2856 
2857 		switch (first[2]) {
2858 		case '0':
2859 			nadd_l(db, "false", 5);
2860 			break;
2861 		case '1':
2862 			nadd_l(db, "true", 4);
2863 			break;
2864 		default:
2865 			return (first);
2866 		}
2867 		return (first + 4);
2868 	case 'd':	/* double */
2869 	case 'e':	/* long double */
2870 	case 'f':	/* float */
2871 		t = parse_floating_literal(first + 1, last, db);
2872 		return ((t == first + 1) ? first : t);
2873 	case 'T':
2874 /* BEGIN CSTYLED */
2875 		/*
2876 		 * Invalid mangled name per
2877 		 *   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2878 		 *
2879 		 */
2880 /* END CSTYLED */
2881 		return (first);
2882 	case '_':
2883 		if (first[2] != 'Z')
2884 			return (first);
2885 
2886 		t = parse_encoding(first + 3, last, db);
2887 		if (t == first + 3 || t == last || t[0] != 'E')
2888 			return (first);
2889 
2890 		/* skip E */
2891 		return (t + 1);
2892 	default:
2893 		t = parse_type(first + 1, last, db);
2894 		if (t == first + 1 || t == last)
2895 			return (first);
2896 
2897 		if (t[0] == 'E')
2898 			return (t + 1);
2899 
2900 		const char *n;
2901 		for (n = t; n != last && isdigit_l(n[0], db->cpp_loc); n++)
2902 			;
2903 		if (n == last || nempty(db) || n[0] != 'E')
2904 			return (first);
2905 		if (n == t)
2906 			return (t);
2907 
2908 		nadd_l(db, t, (size_t)(n - t));
2909 		nfmt(db, "({1}){0}", NULL);
2910 
2911 		return (n + 1);
2912 	}
2913 }
2914 
2915 /*
2916  *   <operator-name>
2917  *                   ::= aa    # &&
2918  *                   ::= ad    # & (unary)
2919  *                   ::= an    # &
2920  *                   ::= aN    # &=
2921  *                   ::= aS    # =
2922  *                   ::= cl    # ()
2923  *                   ::= cm    # ,
2924  *                   ::= co    # ~
2925  *                   ::= cv <type>    # (cast)
2926  *                   ::= da    # delete[]
2927  *                   ::= de    # * (unary)
2928  *                   ::= dl    # delete
2929  *                   ::= dv    # /
2930  *                   ::= dV    # /=
2931  *                   ::= eo    # ^
2932  *                   ::= eO    # ^=
2933  *                   ::= eq    # ==
2934  *                   ::= ge    # >=
2935  *                   ::= gt    # >
2936  *                   ::= ix    # []
2937  *                   ::= le    # <=
2938  *                   ::= li <source-name>	# operator ""
2939  *                   ::= ls    # <<
2940  *                   ::= lS    # <<=
2941  *                   ::= lt    # <
2942  *                   ::= mi    # -
2943  *                   ::= mI    # -=
2944  *                   ::= ml    # *
2945  *                   ::= mL    # *=
2946  *                   ::= mm    # -- (postfix in <expression> context)
2947  *                   ::= na    # new[]
2948  *                   ::= ne    # !=
2949  *                   ::= ng    # - (unary)
2950  *                   ::= nt    # !
2951  *                   ::= nw    # new
2952  *                   ::= oo    # ||
2953  *                   ::= or    # |
2954  *                   ::= oR    # |=
2955  *                   ::= pm    # ->*
2956  *                   ::= pl    # +
2957  *                   ::= pL    # +=
2958  *                   ::= pp    # ++ (postfix in <expression> context)
2959  *                   ::= ps    # + (unary)
2960  *                   ::= pt    # ->
2961  *                   ::= qu    # ?
2962  *                   ::= rm    # %
2963  *                   ::= rM    # %=
2964  *                   ::= rs    # >>
2965  *                   ::= rS    # >>=
2966  *                   ::= v <digit> <source-name> # vendor extended operator
2967  */
2968 static struct {
2969 	const char code[3];
2970 	const char *op;
2971 } op_tbl[] = {
2972 	{ "aa", "operator&&" },
2973 	{ "ad", "operator&" },
2974 	{ "an", "operator&" },
2975 	{ "aN", "operator&=" },
2976 	{ "aS", "operator=" },
2977 	{ "cl", "operator()" },
2978 	{ "cm", "operator," },
2979 	{ "co", "operator~" },
2980 	{ "da", "operator delete[]" },
2981 	{ "de", "operator*" },
2982 	{ "dl", "operator delete" },
2983 	{ "dv", "operator/" },
2984 	{ "dV", "operator/=" },
2985 	{ "eo", "operator^" },
2986 	{ "eO", "operator^=" },
2987 	{ "eq", "operator==" },
2988 	{ "ge", "operator>=" },
2989 	{ "gt", "operator>" },
2990 	{ "ix", "operator[]" },
2991 	{ "le", "operator<=" },
2992 	{ "ls", "operator<<" },
2993 	{ "lS", "operator<<=" },
2994 	{ "lt", "operator<" },
2995 	{ "mi", "operator-" },
2996 	{ "mI", "operator-=" },
2997 	{ "ml", "operator*" },
2998 	{ "mL", "operator*=" },
2999 	{ "mm", "operator--" },
3000 	{ "na", "operator new[]" },
3001 	{ "ne", "operator!=" },
3002 	{ "ng", "operator-" },
3003 	{ "nt", "operator!" },
3004 	{ "nw", "operator new" },
3005 	{ "oo", "operator||" },
3006 	{ "or", "operator|" },
3007 	{ "oR", "operator|=" },
3008 	{ "pm", "operator->*" },
3009 	{ "pl", "operator+" },
3010 	{ "pL", "operator+=" },
3011 	{ "pp", "operator++" },
3012 	{ "ps", "operator+" },
3013 	{ "pt", "operator->" },
3014 	{ "qu", "operator?" },
3015 	{ "rm", "operator%" },
3016 	{ "rM", "operator%=" },
3017 	{ "rs", "operator>>" },
3018 	{ "rS", "operator>>=" }
3019 };
3020 
3021 static const char *
3022 parse_operator_name(const char *first, const char *last, cpp_db_t *db)
3023 {
3024 	VERIFY3P(first, <=, last);
3025 
3026 	if (last - first < 2)
3027 		return (first);
3028 
3029 	for (size_t i = 0; i < ARRAY_SIZE(op_tbl); i++) {
3030 		if (strncmp(first, op_tbl[i].code, 2) != 0)
3031 			continue;
3032 
3033 		nadd_l(db, op_tbl[i].op, 0);
3034 		return (first + 2);
3035 	}
3036 
3037 	const char *t = NULL;
3038 
3039 	if (first[0] == 'l' && first[1] == 'i') {
3040 		t = parse_source_name(first + 2, last, db);
3041 		if (t == first + 2 || nempty(db))
3042 			return (first);
3043 
3044 		nfmt(db, "operator\"\" {0}", NULL);
3045 		return (t);
3046 	}
3047 
3048 	if (first[0] == 'v') {
3049 		if (!isdigit_l(first[1], db->cpp_loc))
3050 			return (first);
3051 
3052 		t = parse_source_name(first + 2, last, db);
3053 		if (t == first + 2)
3054 			return (first);
3055 
3056 		nfmt(db, "operator {0}", NULL);
3057 		return (t);
3058 	}
3059 
3060 	if (first[0] != 'c' && first[1] != 'v')
3061 		return (first);
3062 
3063 	boolean_t try_to_parse_template_args =
3064 	    db->cpp_try_to_parse_template_args;
3065 
3066 	db->cpp_try_to_parse_template_args = B_FALSE;
3067 	t = parse_type(first + 2, last, db);
3068 	db->cpp_try_to_parse_template_args = try_to_parse_template_args;
3069 
3070 	if (t == first + 2 || nempty(db))
3071 		return (first);
3072 
3073 	nfmt(db, "operator {0}", NULL);
3074 	db->cpp_parsed_ctor_dtor_cv = B_TRUE;
3075 	return (t);
3076 }
3077 
3078 struct type_tbl_s {
3079 	int code;
3080 	const char *name;
3081 };
3082 
3083 static struct type_tbl_s type_tbl1[] = {
3084 	{ 'a', "signed char" },
3085 	{ 'b', "bool" },
3086 	{ 'c', "char" },
3087 	{ 'd', "double" },
3088 	{ 'e', "long double" },
3089 	{ 'f', "float" },
3090 	{ 'g', "__float128" },
3091 	{ 'h', "unsigned char" },
3092 	{ 'i', "int" },
3093 	{ 'j', "unsigned int" },
3094 	{ 'l', "long" },
3095 	{ 'm', "unsigned long" },
3096 	{ 'n', "__int128" },
3097 	{ 'o', "unsigned __int128" },
3098 	{ 's', "short" },
3099 	{ 't', "unsigned short" },
3100 	{ 'v', "void" },
3101 	{ 'w', "wchar_t" },
3102 	{ 'x', "long long" },
3103 	{ 'y', "unsigned long long" },
3104 	{ 'z', "..." }
3105 };
3106 
3107 static struct type_tbl_s type_tbl2[] = {
3108 	{ 'a', "auto" },
3109 	{ 'c', "decltype(auto)" },
3110 	{ 'd', "decimal64" },
3111 	{ 'e', "decimal128" },
3112 	{ 'f', "decimal32" },
3113 	{ 'h', "decimal16" },
3114 	{ 'i', "char32_t" },
3115 	{ 'n', "std::nullptr_t" },
3116 	{ 's', "char16_t" }
3117 };
3118 
3119 static const char *
3120 parse_builtin_type(const char *first, const char *last, cpp_db_t *db)
3121 {
3122 	VERIFY3P(first, <=, last);
3123 
3124 	if (first == last)
3125 		return (first);
3126 
3127 	size_t i;
3128 
3129 	for (i = 0; i < ARRAY_SIZE(type_tbl1); i++) {
3130 		if (first[0] == type_tbl1[i].code) {
3131 			nadd_l(db, type_tbl1[i].name, 0);
3132 			return (first + 1);
3133 		}
3134 	}
3135 
3136 	if (first[0] == 'D') {
3137 		if (first + 1 == last)
3138 			return (first);
3139 		for (i = 0; i < ARRAY_SIZE(type_tbl2); i++) {
3140 			if (first[1] == type_tbl2[i].code) {
3141 				nadd_l(db, type_tbl2[i].name, 0);
3142 				return (first + 2);
3143 			}
3144 		}
3145 	}
3146 
3147 	if (first[0] == 'u') {
3148 		const char *t = parse_source_name(first + 1, last, db);
3149 		if (t == first + 1)
3150 			return (first);
3151 		return (t);
3152 	}
3153 
3154 	return (first);
3155 }
3156 
3157 static const char *
3158 parse_base36(const char *first, const char *last, size_t *val, locale_t loc)
3159 {
3160 	VERIFY3P(first, <=, last);
3161 
3162 	const char *t;
3163 
3164 	for (t = first, *val = 0; t != last; t++) {
3165 		if (!isdigit_l(t[0], loc) && !isupper_l(t[0], loc))
3166 			return (t);
3167 
3168 		*val *= 36;
3169 
3170 		if (isdigit_l(t[0], loc))
3171 			*val += t[0] - '0';
3172 		else
3173 			*val += t[0] - 'A' + 10;
3174 	}
3175 	return (t);
3176 }
3177 
3178 static struct type_tbl_s sub_tbl[] = {
3179 	{ 'a', "std::allocator" },
3180 	{ 'b', "std::basic_string" },
3181 	{ 's', "std::string" },
3182 	{ 'i', "std::istream" },
3183 	{ 'o', "std::ostream" },
3184 	{ 'd', "std::iostream" }
3185 };
3186 
3187 static const char *
3188 parse_substitution(const char *first, const char *last, cpp_db_t *db)
3189 {
3190 	VERIFY3P(first, <=, last);
3191 
3192 	if (first == last || last - first < 2)
3193 		return (first);
3194 
3195 	if (first[0] != 'S')
3196 		return (first);
3197 
3198 	for (size_t i = 0; i < ARRAY_SIZE(sub_tbl); i++) {
3199 		if (first[1] == sub_tbl[i].code) {
3200 			nadd_l(db, sub_tbl[i].name, 0);
3201 			return (first + 2);
3202 		}
3203 	}
3204 
3205 	const char *t = first + 1;
3206 	size_t n = 0;
3207 
3208 	if (t[0] != '_') {
3209 		t = parse_base36(first + 1, last, &n, db->cpp_loc);
3210 		if (t == first + 1 || t[0] != '_')
3211 			return (first);
3212 
3213 		/*
3214 		 * S_ == substitution 0,
3215 		 * S0_ == substituion 1,
3216 		 * ...
3217 		 */
3218 		n++;
3219 	}
3220 
3221 	if (n >= sub_len(&db->cpp_subs))
3222 		return (first);
3223 
3224 	sub(db, n);
3225 
3226 	/* skip _ */
3227 	VERIFY3U(t[0], ==, '_');
3228 
3229 	return (t + 1);
3230 }
3231 
3232 static const char *
3233 parse_source_name(const char *first, const char *last, cpp_db_t *db)
3234 {
3235 	VERIFY3P(first, <=, last);
3236 
3237 	if (first == last)
3238 		return (first);
3239 
3240 	const char *t = NULL;
3241 	size_t n = 0;
3242 
3243 	for (t = first; t != last && isdigit_l(t[0], db->cpp_loc); t++) {
3244 		/* make sure we don't overflow */
3245 		size_t nn = n * 10;
3246 		if (nn < n)
3247 			return (first);
3248 
3249 		nn += t[0] - '0';
3250 		if (nn < n)
3251 			return (first);
3252 
3253 		n = nn;
3254 	}
3255 
3256 	if (n == 0 || t == last || t + n > last ||
3257 	    (uintptr_t)t + n < (uintptr_t)t)
3258 		return (first);
3259 
3260 	if (strncmp(t, "_GLOBAL__N", 10) == 0)
3261 		nadd_l(db, "(anonymous namespace)", 0);
3262 	else
3263 		nadd_l(db, t, n);
3264 
3265 	return (t + n);
3266 }
3267 
3268 /*
3269  * extension:
3270  * <vector-type>           ::= Dv <positive dimension number> _
3271  *                                    <extended element type>
3272  *                         ::= Dv [<dimension expression>] _ <element type>
3273  * <extended element type> ::= <element type>
3274  *                         ::= p # AltiVec vector pixel
3275  */
3276 static const char *
3277 parse_vector_type(const char *first, const char *last, cpp_db_t *db)
3278 {
3279 	VERIFY3P(first, <=, last);
3280 
3281 	if (last - first < 3)
3282 		return (first);
3283 
3284 	VERIFY3U(first[0], ==, 'D');
3285 	VERIFY3U(first[1], ==, 'v');
3286 
3287 	const char *t = first + 2;
3288 	const char *t1 = NULL;
3289 
3290 	if (isdigit_l(first[2], db->cpp_loc) && first[2] != '0') {
3291 		t1 = parse_number(t, last, db->cpp_loc);
3292 		if (t1 == last || t1 + 1 == last || t1[0] != '_')
3293 			return (first);
3294 
3295 		nadd_l(db, t, (size_t)(t1 - t));
3296 
3297 		/* skip _ */
3298 		t = t1 + 1;
3299 
3300 		if (t[0] != 'p') {
3301 			t1 = parse_type(t, last, db);
3302 			if (t1 == t)
3303 				return (first);
3304 
3305 			nfmt(db, "{0} vector[{1}]", NULL);
3306 			return (t1);
3307 		}
3308 		nfmt(db, "{0} pixel vector[{1}]", NULL);
3309 		return (t1);
3310 	}
3311 
3312 	if (first[2] != '_') {
3313 		t1 = parse_expression(first + 2, last, db);
3314 		if (first == last || t1 == first + 2 || t1[0] != '_')
3315 			return (first);
3316 
3317 		/* skip _ */
3318 		t = t1 + 1;
3319 	} else {
3320 		nadd_l(db, "", 0);
3321 	}
3322 
3323 	t1 = parse_type(t, last, db);
3324 	if (t == t1)
3325 		return (first);
3326 
3327 	nfmt(db, "{1:L} vector[{0}]", "{1:R}");
3328 	return (t1);
3329 }
3330 
3331 /* BEGIN CSTYLED */
3332 /*
3333  * <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
3334  *             ::= DT <expression> E  # decltype of an expression (C++0x)
3335  */
3336 /* END CSTYLED */
3337 static const char *
3338 parse_decltype(const char *first, const char *last, cpp_db_t *db)
3339 {
3340 	VERIFY3P(first, <=, last);
3341 
3342 	if (last - first < 4)
3343 		return (first);
3344 
3345 	VERIFY3U(first[0], ==, 'D');
3346 
3347 	if (first[1] != 't' && first[1] != 'T')
3348 		return (first);
3349 
3350 	size_t n = nlen(db);
3351 	const char *t = parse_expression(first + 2, last, db);
3352 	if (NAMT(db, n) != 1 || t == first + 2 || t == last || t[0] != 'E')
3353 		return (first);
3354 
3355 	nfmt(db, "decltype({0})", NULL);
3356 
3357 	/* skip E */
3358 	return (t + 1);
3359 }
3360 
3361 /*
3362  * <array-type> ::= A <positive dimension number> _ <element type>
3363  *              ::= A [<dimension expression>] _ <element type>
3364  */
3365 static const char *
3366 parse_array_type(const char *first, const char *last, cpp_db_t *db)
3367 {
3368 	VERIFY3P(first, <=, last);
3369 	VERIFY3U(first[0], ==, 'A');
3370 
3371 	if (last - first < 3)
3372 		return (first);
3373 
3374 	const char *t = first + 1;
3375 	const char *t1 = NULL;
3376 	size_t n = nlen(db);
3377 
3378 	if (t[0] != '_') {
3379 		if (isdigit_l(t[0], db->cpp_loc) && t[0] != '0') {
3380 			t1 = parse_number(t, last, db->cpp_loc);
3381 			if (t1 == last)
3382 				return (first);
3383 
3384 			nadd_l(db, t, (size_t)(t1 - t));
3385 		} else {
3386 			t1 = parse_expression(t, last, db);
3387 			if (t1 == last || t == t1)
3388 				return (first);
3389 		}
3390 
3391 		if (t1[0] != '_')
3392 			return (first);
3393 
3394 		t = t1;
3395 	} else {
3396 		nadd_l(db, "", 0);
3397 	}
3398 
3399 	VERIFY3U(t[0], ==, '_');
3400 
3401 	t1 = parse_type(t + 1, last, db);
3402 	if (t1 == t + 1 || NAMT(db, n) != 2)
3403 		return (first);
3404 
3405 	/*
3406 	 * if we have  " [xxx]" already, want new result to be
3407 	 * " [yyy][xxx]"
3408 	 */
3409 	str_t *r = &name_top(&db->cpp_name)->strp_r;
3410 	if (r->str_len > 1 && r->str_s[0] == ' ' && r->str_s[1] == '[')
3411 		(void) str_erase(r, 0, 1);
3412 
3413 	nfmt(db, "{0:L}", " [{1}]{0:R}");
3414 	return (t1);
3415 }
3416 
3417 /* <pointer-to-member-type> ::= M <class type> <member type> */
3418 static const char *
3419 parse_pointer_to_member_type(const char *first, const char *last, cpp_db_t *db)
3420 {
3421 	VERIFY3P(first, <=, last);
3422 
3423 	if (last - first < 3)
3424 		return (first);
3425 
3426 	VERIFY3U(first[0], ==, 'M');
3427 
3428 	const char *t1 = first + 1;
3429 	const char *t2 = NULL;
3430 	size_t n = nlen(db);
3431 
3432 	t2 = parse_type(t1, last, db);
3433 	if (t1 == t2)
3434 		return (first);
3435 
3436 	t1 = t2;
3437 	t2 = parse_type(t1, last, db);
3438 	if (t1 == t2)
3439 		return (first);
3440 
3441 	if (NAMT(db, n) != 2)
3442 		return (first);
3443 
3444 	str_pair_t *func = name_top(&db->cpp_name);
3445 
3446 	if (str_length(&func->strp_r) > 0 && func->strp_r.str_s[0] == '(')
3447 		nfmt(db, "{0:L}({1}::*", "){0:R}");
3448 	else
3449 		nfmt(db, "{0:L} {1}::*", "{0:R}");
3450 
3451 	return (t2);
3452 }
3453 
3454 /* BEGIN CSTYLED */
3455 /*
3456  * <unresolved-name>
3457  *  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3458  *                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3459  *                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3460  *                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3461  *                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3462  *  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3463  *                                                                       # T::N::x /decltype(p)::N::x
3464  *  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3465  */
3466 /* END CSTYLED */
3467 static const char *
3468 parse_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3469 {
3470 	VERIFY3P(first, <=, last);
3471 
3472 	if (last - first < 2)
3473 		return (first);
3474 
3475 	const char *t = first;
3476 	const char *t2 = NULL;
3477 	boolean_t global = B_FALSE;
3478 	size_t n;
3479 
3480 	if (t[0] == 'g' && t[1] == 's') {
3481 		global = B_TRUE;
3482 		t += 2;
3483 	}
3484 	if (t == last)
3485 		return (first);
3486 
3487 	t2 = parse_base_unresolved_name(t, last, db);
3488 	if (t != t2) {
3489 		if (global) {
3490 			if (nempty(db))
3491 				return (first);
3492 
3493 			(void) str_insert(TOP_L(db), 0, "::", 2);
3494 		}
3495 		return (t2);
3496 	}
3497 
3498 	if (t[0] != 's' || t[1] != 'r' || last - t < 2)
3499 		return (first);
3500 
3501 	n = nlen(db);
3502 	if (t[2] == 'N') {
3503 		t += 3;
3504 		t2 = parse_unresolved_type(t, last, db);
3505 		if (t2 == t || t2 == last)
3506 			return (first);
3507 		t = t2;
3508 
3509 		t2 = parse_template_args(t, last, db);
3510 		if (t2 != t) {
3511 			if (NAMT(db, n) < 2 || t2 == last)
3512 				return (first);
3513 
3514 			nfmt(db, "{1:L}{0}", "{1:R}");
3515 			t = t2;
3516 		}
3517 
3518 		VERIFY3U(NAMT(db, n), ==, 1);
3519 
3520 		while (t[0] != 'E') {
3521 			size_t nn = nlen(db);
3522 			t2 = parse_unresolved_qualifier_level(t, last, db);
3523 			if (t == t2 || t == last || NAMT(db, nn) != 1)
3524 				return (first);
3525 
3526 			t = t2;
3527 		}
3528 
3529 		/* skip E */
3530 		t++;
3531 
3532 		t2 = parse_base_unresolved_name(t, last, db);
3533 		if (t == t2 || NAMT(db, n) < 2)
3534 			return (first);
3535 
3536 		njoin(db, NAMT(db, n), "::");
3537 		return (t2);
3538 	}
3539 
3540 	t += 2;
3541 
3542 	t2 = parse_unresolved_type(t, last, db);
3543 	if (t != t2) {
3544 		t = t2;
3545 		t2 = parse_template_args(t, last, db);
3546 		if (t2 != t)
3547 			nfmt(db, "{1:L}{0}", "{1:R}");
3548 		t = t2;
3549 
3550 		t2 = parse_base_unresolved_name(t, last, db);
3551 		if (t == t2 || nlen(db) < 2)
3552 			return (first);
3553 
3554 		nfmt(db, "{1:L}::{0}", "{1:R}");
3555 		return (t2);
3556 	}
3557 
3558 	t2 = parse_unresolved_qualifier_level(t, last, db);
3559 	if (t2 == t || t2 == last)
3560 		return (first);
3561 
3562 	t = t2;
3563 	if (global && nlen(db) > 0)
3564 		nfmt(db, "::{0:L}", "{0:R}");
3565 
3566 	while (t[0] != 'E') {
3567 		t2 = parse_unresolved_qualifier_level(t, last, db);
3568 		if (t == t2 || t == last || nlen(db) < 2)
3569 			return (first);
3570 
3571 		t = t2;
3572 	}
3573 
3574 	/* skip E */
3575 	t++;
3576 
3577 	t2 = parse_base_unresolved_name(t, last, db);
3578 	if (t == t2 || nlen(db) < 2)
3579 		return (first);
3580 
3581 	njoin(db, NAMT(db, n), "::");
3582 	return (t2);
3583 }
3584 
3585 /* <unresolved-qualifier-level> ::= <simple-id> */
3586 static const char *
3587 parse_unresolved_qualifier_level(const char *first, const char *last,
3588     cpp_db_t *db)
3589 {
3590 	VERIFY3P(first, <=, last);
3591 	return (parse_simple_id(first, last, db));
3592 }
3593 
3594 /* BEGIN CSTYLED */
3595 /*
3596  * <base-unresolved-name> ::= <simple-id>                                # unresolved name
3597  *          extension     ::= <operator-name>                            # unresolved operator-function-id
3598  *          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3599  *                        ::= on <operator-name>                         # unresolved operator-function-id
3600  *                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3601  *                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3602  *                                                                       # e.g. ~X or ~X<N-1>
3603  */
3604 /* END CSTYLED */
3605 static const char *
3606 parse_base_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3607 {
3608 	VERIFY3P(first, <=, last);
3609 
3610 	if (last - first < 2)
3611 		return (first);
3612 
3613 	const char *t = NULL;
3614 	const char *t1 = NULL;
3615 
3616 	if ((first[0] != 'o' && first[0] != 'd') || first[1] != 'n') {
3617 		t = parse_simple_id(first, last, db);
3618 		if (t != first)
3619 			return (t);
3620 
3621 		t = parse_operator_name(first, last, db);
3622 		if (t == first)
3623 			return (first);
3624 
3625 		t1 = parse_template_args(t, last, db);
3626 		if (t1 != t) {
3627 			if (nlen(db) < 2)
3628 				return (first);
3629 			nfmt(db, "{1:L}{0}", "{1:R}");
3630 		}
3631 
3632 		return (t1);
3633 	}
3634 
3635 	if (first[0] == 'd') {
3636 		t = parse_destructor_name(first + 2, last, db);
3637 		return ((t != first + 2) ? t : first);
3638 	}
3639 
3640 	t = parse_operator_name(first + 2, last, db);
3641 	if (t == first + 2)
3642 		return (first);
3643 
3644 	t1 = parse_template_args(t, last, db);
3645 	if (t1 != t)
3646 		nfmt(db, "{1:L}{0}", "{1:R}");
3647 	return (t1);
3648 }
3649 
3650 /*
3651  * <destructor-name> ::= <unresolved-type>	# e.g., ~T or ~decltype(f())
3652  *                   ::= <simple-id>		# e.g., ~A<2*N>
3653  */
3654 static const char *
3655 parse_destructor_name(const char *first, const char *last, cpp_db_t *db)
3656 {
3657 	VERIFY3P(first, <=, last);
3658 
3659 	if (first == last)
3660 		return (first);
3661 
3662 	const char *t = parse_unresolved_type(first, last, db);
3663 
3664 	if (t == first)
3665 		t = parse_simple_id(first, last, db);
3666 
3667 	if (t == first)
3668 		return (first);
3669 
3670 	nfmt(db, "~{0:L}", "{0:R}");
3671 	return (t);
3672 }
3673 
3674 /*
3675  *  <ref-qualifier> ::= R                   # & ref-qualifier
3676  *  <ref-qualifier> ::= O                   # && ref-qualifier
3677  *
3678  * <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
3679  */
3680 static const char *
3681 parse_function_type(const char *first, const char *last, cpp_db_t *db)
3682 {
3683 	VERIFY3P(first, <=, last);
3684 
3685 	if (last - first < 2)
3686 		return (first);
3687 
3688 	VERIFY3U(first[0], ==, 'F');
3689 
3690 	const char *t = first + 1;
3691 
3692 	/* extern "C" */
3693 	if (t[0] == 'Y')
3694 		t++;
3695 
3696 	const char *t1 = parse_type(t, last, db);
3697 	if (t1 == t)
3698 		return (first);
3699 
3700 	size_t n = nlen(db);
3701 	int ref_qual = 0;
3702 
3703 	t = t1;
3704 
3705 	while (t != last && t[0] != 'E') {
3706 		if (t[0] == 'v') {
3707 			t++;
3708 			continue;
3709 		}
3710 
3711 		if (t[0] == 'R' && t + 1 != last && t[1] == 'E') {
3712 			ref_qual = 1;
3713 			t++;
3714 			continue;
3715 		}
3716 
3717 		if (t[0] == 'O' && t + 1 != last && t[1] == 'E') {
3718 			ref_qual = 2;
3719 			t++;
3720 			continue;
3721 		}
3722 
3723 
3724 		t1 = parse_type(t, last, db);
3725 		if (t1 == t || t == last)
3726 			return (first);
3727 
3728 		t = t1;
3729 	}
3730 
3731 	if (t == last)
3732 		return (first);
3733 
3734 	njoin(db, NAMT(db, n), ", ");
3735 	nfmt(db, "({0})", NULL);
3736 
3737 	switch (ref_qual) {
3738 	case 1:
3739 		nfmt(db, "{0} &", NULL);
3740 		break;
3741 	case 2:
3742 		nfmt(db, "{0} &&", NULL);
3743 		break;
3744 	}
3745 
3746 	nfmt(db, "{1:L} ", "{0}{1:R}");
3747 
3748 	/* skip E */
3749 	return (t + 1);
3750 }
3751 
3752 /*
3753  * <template-param> ::= T_    # first template parameter
3754  *                  ::= T <parameter-2 non-negative number> _
3755  */
3756 static const char *
3757 parse_template_param(const char *first, const char *last, cpp_db_t *db)
3758 {
3759 	VERIFY3P(first, <=, last);
3760 
3761 	if (last - first < 2 || first[0] != 'T')
3762 		return (first);
3763 
3764 	const char *t = first + 1;
3765 	size_t idx = 0;
3766 
3767 	while (t != last && t[0] != '_') {
3768 		if (!isdigit_l(t[0], db->cpp_loc))
3769 			return (first);
3770 
3771 		idx *= 10;
3772 		idx += t[0] - '0';
3773 		t++;
3774 	}
3775 
3776 	if (t == last)
3777 		return (first);
3778 
3779 	VERIFY3U(t[0], ==, '_');
3780 
3781 	/*
3782 	 * T_ -> idx 0
3783 	 * T0 -> idx 1
3784 	 * T1 -> idx 2
3785 	 * ...
3786 	 */
3787 	if (first[1] != '_')
3788 		idx++;
3789 
3790 	/* skip _ */
3791 	t++;
3792 
3793 	if (tempty(db))
3794 		return (first);
3795 
3796 	if (idx >= ttlen(db)) {
3797 		nadd_l(db, first, (size_t)(t - first));
3798 		db->cpp_fix_forward_references = B_TRUE;
3799 		return (t);
3800 	}
3801 
3802 	tsub(db, idx);
3803 	return (t);
3804 }
3805 
3806 /*
3807  * <template-args> ::= I <template-arg>* E
3808  *     extension, the abi says <template-arg>+
3809  */
3810 static const char *
3811 parse_template_args(const char *first, const char *last, cpp_db_t *db)
3812 {
3813 	VERIFY3P(first, <=, last);
3814 
3815 	if (last - first < 2 || first[0] != 'I')
3816 		return (first);
3817 
3818 	if (db->cpp_tag_templates)
3819 		sub_clear(templ_top(&db->cpp_templ));
3820 
3821 	const char *t = first + 1;
3822 	size_t n = nlen(db);
3823 
3824 	while (t[0] != 'E') {
3825 		if (db->cpp_tag_templates)
3826 			tpush(db);
3827 
3828 		size_t n1 = nlen(db);
3829 		const char *t1 = parse_template_arg(t, last, db);
3830 
3831 		if (db->cpp_tag_templates)
3832 			tpop(db);
3833 
3834 		if (t1 == t || t == last)
3835 			return (first);
3836 
3837 		if (db->cpp_tag_templates)
3838 			tsave(db, NAMT(db, n1));
3839 
3840 		t = t1;
3841 	}
3842 
3843 	/*
3844 	 * ugly, but if the last thing pushed was an empty string,
3845 	 * get rid of it so we dont get "<..., >"
3846 	 */
3847 	if (NAMT(db, n) > 1 &&
3848 	    str_pair_len(name_top(&db->cpp_name)) == 0)
3849 		name_pop(&db->cpp_name, NULL);
3850 
3851 	njoin(db, NAMT(db, n), ", ");
3852 
3853 	VERIFY3U(nlen(db), >, 0);
3854 
3855 	/* make sure we don't bitshift ourselves into oblivion */
3856 	str_t *top = TOP_L(db);
3857 	if (str_length(top) > 0 &&
3858 	    top->str_s[top->str_len - 1] == '>')
3859 		nfmt(db, "<{0} >", NULL);
3860 	else
3861 		nfmt(db, "<{0}>", NULL);
3862 
3863 	/* skip E */
3864 	return (t + 1);
3865 }
3866 
3867 /*
3868  * <discriminator> := _ <non-negative number>      # when number < 10
3869  *                 := __ <non-negative number> _   # when number >= 10
3870  *  extension      := decimal-digit+               # at the end of string
3871  */
3872 static const char *
3873 parse_discriminator(const char *first, const char *last, locale_t loc)
3874 {
3875 	VERIFY3P(first, <=, last);
3876 
3877 	const char *t = NULL;
3878 
3879 	if (first == last)
3880 		return (first);
3881 
3882 	if (isdigit_l(first[0], loc)) {
3883 		for (t = first; t != last && isdigit_l(t[0], loc); t++)
3884 			;
3885 
3886 		/* not at the end of the string */
3887 		if (t != last)
3888 			return (first);
3889 
3890 		return (t);
3891 	} else if (first[0] != '_' || first + 1 == last) {
3892 		return (first);
3893 	}
3894 
3895 	t = first + 1;
3896 	if (isdigit_l(t[0], loc))
3897 		return (t + 1);
3898 
3899 	if (t[0] != '_' || t + 1 == last)
3900 		return (first);
3901 
3902 	for (t++; t != last && isdigit_l(t[0], loc); t++)
3903 		;
3904 	if (t == last || t[0] != '_')
3905 		return (first);
3906 
3907 	return (t);
3908 }
3909 
3910 /* <CV-qualifiers> ::= [r] [V] [K] */
3911 const char *
3912 parse_cv_qualifiers(const char *first, const char *last, unsigned *cv)
3913 {
3914 	VERIFY3P(first, <=, last);
3915 
3916 	if (first == last)
3917 		return (first);
3918 
3919 	*cv = 0;
3920 	if (first[0] == 'r') {
3921 		*cv |= CPP_QUAL_RESTRICT;
3922 		first++;
3923 	}
3924 	if (first != last && first[0] == 'V') {
3925 		*cv |= CPP_QUAL_VOLATILE;
3926 		first++;
3927 	}
3928 	if (first != last && first[0] == 'K') {
3929 		*cv |= CPP_QUAL_CONST;
3930 		first++;
3931 	}
3932 
3933 	return (first);
3934 }
3935 
3936 /*
3937  * <number> ::= [n] <non-negative decimal integer>
3938  */
3939 static const char *
3940 parse_number(const char *first, const char *last, locale_t loc)
3941 {
3942 	VERIFY3P(first, <=, last);
3943 
3944 	const char *t = first;
3945 
3946 	if (first == last || (first[0] != 'n' && !isdigit_l(first[0], loc)))
3947 		return (first);
3948 
3949 	if (t[0] == 'n')
3950 		t++;
3951 
3952 	if (t[0] == '0')
3953 		return (t + 1);
3954 
3955 	while (isdigit_l(t[0], loc))
3956 		t++;
3957 
3958 	return (t);
3959 }
3960 
3961 /*
3962  * Like isxdigit(3C), except we can only accept lower case letters as
3963  * that's only what is allowed when [de]mangling floating point constants into
3964  * their hex representation.
3965  */
3966 static inline boolean_t
3967 is_xdigit(int c)
3968 {
3969 	if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
3970 		return (B_TRUE);
3971 	return (B_FALSE);
3972 }
3973 
3974 static boolean_t
3975 nempty(cpp_db_t *db)
3976 {
3977 	return (name_empty(&db->cpp_name));
3978 }
3979 
3980 static size_t
3981 nlen(cpp_db_t *db)
3982 {
3983 	return (name_len(&db->cpp_name));
3984 }
3985 
3986 static void
3987 nadd_l(cpp_db_t *db, const char *s, size_t len)
3988 {
3989 	CK(name_add(&db->cpp_name, s, len, NULL, 0));
3990 }
3991 
3992 static void
3993 njoin(cpp_db_t *db, size_t amt, const char *sep)
3994 {
3995 	name_t *nm = &db->cpp_name;
3996 
3997 	CK(name_join(nm, amt, sep));
3998 }
3999 
4000 static void
4001 nfmt(cpp_db_t *db, const char *fmt_l, const char *fmt_r)
4002 {
4003 	CK(name_fmt(&db->cpp_name, fmt_l, fmt_r));
4004 }
4005 
4006 static void
4007 save_top(cpp_db_t *db, size_t amt)
4008 {
4009 	CK(sub_save(&db->cpp_subs, &db->cpp_name, amt));
4010 }
4011 
4012 static void
4013 sub(cpp_db_t *db, size_t n)
4014 {
4015 	CK(sub_substitute(&db->cpp_subs, n, &db->cpp_name));
4016 }
4017 
4018 static boolean_t
4019 tempty(const cpp_db_t *db)
4020 {
4021 	return (templ_empty(&db->cpp_templ) ? B_TRUE : B_FALSE);
4022 }
4023 
4024 static size_t
4025 ttlen(const cpp_db_t *db)
4026 {
4027 	return (templ_top_len(&db->cpp_templ));
4028 }
4029 
4030 static void
4031 tsub(cpp_db_t *db, size_t n)
4032 {
4033 	CK(templ_sub(&db->cpp_templ, n, &db->cpp_name));
4034 }
4035 
4036 static void
4037 tpush(cpp_db_t *db)
4038 {
4039 	CK(templ_push(&db->cpp_templ));
4040 }
4041 
4042 static void
4043 tpop(cpp_db_t *db)
4044 {
4045 	templ_pop(&db->cpp_templ);
4046 }
4047 
4048 static void
4049 tsave(cpp_db_t *db, size_t amt)
4050 {
4051 	CK(templ_save(&db->cpp_name, amt, &db->cpp_templ));
4052 }
4053 
4054 static boolean_t
4055 db_init(cpp_db_t *db, sysdem_ops_t *ops)
4056 {
4057 	(void) memset(db, 0, sizeof (*db));
4058 	db->cpp_ops = ops;
4059 	name_init(&db->cpp_name, ops);
4060 	sub_init(&db->cpp_subs, ops);
4061 	templ_init(&db->cpp_templ, ops);
4062 	db->cpp_tag_templates = B_TRUE;
4063 	db->cpp_try_to_parse_template_args = B_TRUE;
4064 	tpush(db);
4065 	db->cpp_loc = newlocale(LC_CTYPE_MASK, "C", 0);
4066 	return ((db->cpp_loc != NULL) ? B_TRUE : B_FALSE);
4067 }
4068 
4069 static void
4070 db_fini(cpp_db_t *db)
4071 {
4072 	name_fini(&db->cpp_name);
4073 	sub_fini(&db->cpp_subs);
4074 	templ_fini(&db->cpp_templ);
4075 	freelocale(db->cpp_loc);
4076 	(void) memset(db, 0, sizeof (*db));
4077 }
4078 
4079 static void
4080 print_sp(const str_pair_t *sp, FILE *out)
4081 {
4082 	(void) fprintf(out, "{%.*s#%.*s}",
4083 	    (int)sp->strp_l.str_len, sp->strp_l.str_s,
4084 	    (int)sp->strp_r.str_len, sp->strp_r.str_s);
4085 }
4086 
4087 static void
4088 print_name(const name_t *n, FILE *out)
4089 {
4090 	const str_pair_t *sp = name_top((name_t *)n);
4091 	size_t i;
4092 
4093 	(void) fprintf(out, "Name:\n");
4094 
4095 	if (name_len(n) == 0)
4096 		return;
4097 
4098 	for (i = 0; i < n->nm_len; i++, sp--) {
4099 		(void) fprintf(out, "  [%02zu] ", i);
4100 		print_sp(sp, out);
4101 		(void) fputc('\n', out);
4102 	}
4103 
4104 	(void) fputc('\n', out);
4105 }
4106 
4107 /* Print a base-36 number (for substitutions) */
4108 static char *
4109 base36(char *buf, size_t val)
4110 {
4111 	char tmp[16] = { 0 };
4112 	char *p = tmp;
4113 
4114 	if (val == 0) {
4115 		buf[0] = '0';
4116 		buf[1] = '\0';
4117 		return (buf);
4118 	}
4119 
4120 	while (val > 0) {
4121 		size_t r = val % 36;
4122 
4123 		if (r < 10)
4124 			*p++ = r + '0';
4125 		else
4126 			*p++ = r - 10 + 'A';
4127 
4128 		val /= 36;
4129 	}
4130 
4131 	char *q = buf;
4132 	while (--p >= tmp)
4133 		*q++ = *p;
4134 
4135 	return (buf);
4136 }
4137 
4138 static void
4139 print_sub(const sub_t *sub, FILE *out)
4140 {
4141 	const name_t *n = sub->sub_items;
4142 
4143 	(void) fprintf(out, "Substitutions:\n");
4144 
4145 	if (sub->sub_len == 0)
4146 		return;
4147 
4148 	for (size_t i = 0; i < sub->sub_len; i++, n++) {
4149 		(void) printf("  ");
4150 		if (i == 0) {
4151 			(void) fprintf(out, "%-4s", "S_");
4152 		} else {
4153 			char buf[16] = { 0 };
4154 			char buf2[16] = { 0 };
4155 
4156 			(void) snprintf(buf, sizeof (buf), "S%s_",
4157 			    base36(buf2, i));
4158 			(void) fprintf(out, "%-4s", buf);
4159 		}
4160 		(void) fprintf(out, " = ");
4161 
4162 		(void) fputc('{', out);
4163 		for (size_t j = 0; j < n->nm_len; j++) {
4164 			if (j > 0)
4165 				(void) fputc(' ', out);
4166 			print_sp(&n->nm_items[j], out);
4167 		}
4168 		(void) fputc('}', out);
4169 
4170 		(void) fputc('\n', out);
4171 	}
4172 	(void) fputc('\n', out);
4173 }
4174 
4175 static void
4176 print_templ(const templ_t *tpl, FILE *out)
4177 {
4178 
4179 	(void) fprintf(out, "Template\n");
4180 
4181 	const sub_t *s = templ_top((templ_t *)tpl);
4182 
4183 	for (size_t i = 0; i < s->sub_len; i++) {
4184 		char buf[16] = { 0 };
4185 
4186 		if (i == 0)
4187 			(void) snprintf(buf, sizeof (buf), "%s", "T_");
4188 		else
4189 			(void) snprintf(buf, sizeof (buf), "T%zu_", i - 1);
4190 
4191 		(void) fprintf(out, "  %-4s = ", buf);
4192 
4193 		(void) fputc('{', out);
4194 
4195 		const name_t *n = &s->sub_items[i];
4196 		for (size_t j = 0; j < n->nm_len; j++) {
4197 			const str_pair_t *sp = &n->nm_items[j];
4198 
4199 			if (j > 0)
4200 				(void) fputc(' ', out);
4201 
4202 			(void) fprintf(out, "{%.*s#%.*s}",
4203 			    (int)sp->strp_l.str_len, sp->strp_l.str_s,
4204 			    (int)sp->strp_r.str_len, sp->strp_r.str_s);
4205 		}
4206 		(void) fprintf(out, "}\n");
4207 	}
4208 	(void) fprintf(out, "\n");
4209 }
4210 
4211 static void
4212 dump(cpp_db_t *db, FILE *out)
4213 {
4214 	print_name(&db->cpp_name, out);
4215 	print_sub(&db->cpp_subs, out);
4216 	print_templ(&db->cpp_templ, out);
4217 }
4218