Rich's feedback

   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 2017 Jason King.
  14  */
  15 #include <ctype.h>
  16 #include <errno.h>
  17 #include <locale.h>

  18 #include <string.h>
  19 #include <setjmp.h>
  20 #include <stdio.h>
  21 #include <stdlib.h>
  22 #include <sys/isa_defs.h>
  23 #include <sys/debug.h>
  24 #include "sysdemangle.h"
  25 #include "sysdemangle_int.h"
  26 #include "cxx.h"
  27 
  28 #ifndef ARRAY_SIZE
  29 #define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
  30 #endif
  31 
  32 #define CPP_QUAL_CONST          (1U)
  33 #define CPP_QUAL_VOLATILE       (2U)
  34 #define CPP_QUAL_RESTRICT       (4U)
  35 
  36 typedef struct cpp_db_s {
  37         sysdem_ops_t    *cpp_ops;
  38         jmp_buf         cpp_jmp;
  39         name_t          cpp_name;
  40         sub_t           cpp_subs;
  41         templ_t         cpp_templ;
  42         unsigned        cpp_cv;
  43         unsigned        cpp_ref;
  44         unsigned        cpp_depth;
  45         boolean_t       cpp_parsed_ctor_dtor_cv;
  46         boolean_t       cpp_tag_templates;
  47         boolean_t       cpp_fix_forward_references;
  48         boolean_t       cpp_try_to_parse_template_args;
  49         locale_t        cpp_loc;
  50 } cpp_db_t;
  51 
  52 #define CK(x)                                           \
  53         do {                                            \
  54                 if (!(x))                               \
  55                         longjmp(db->cpp_jmp, 1);     \


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