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