Print this page
Address Robert'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 
  16 #include <errno.h>

  17 #include <string.h>
  18 #include <setjmp.h>
  19 #include <stdio.h>
  20 #include <stdlib.h>
  21 #include <sys/isa_defs.h>
  22 #include <sys/debug.h>
  23 #include "sysdemangle.h"
  24 #include "sysdemangle_int.h"
  25 #include "cpp.h"
  26 

  27 #define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))

  28 
  29 #define CPP_QUAL_CONST          (1U)
  30 #define CPP_QUAL_VOLATILE       (2U)
  31 #define CPP_QUAL_RESTRICT       (4U)
  32 
  33 typedef struct cpp_db_s {
  34         sysdem_ops_t    *cpp_ops;
  35         jmp_buf         cpp_jmp;
  36         name_t          cpp_name;
  37         sub_t           cpp_subs;
  38         templ_t         cpp_templ;
  39         unsigned        cpp_cv;
  40         unsigned        cpp_ref;
  41         unsigned        cpp_depth;
  42         boolean_t       cpp_parsed_ctor_dtor_cv;
  43         boolean_t       cpp_tag_templates;
  44         boolean_t       cpp_fix_forward_references;
  45         boolean_t       cpp_try_to_parse_template_args;

  46 } cpp_db_t;
  47 
  48 #define CK(x)                                           \
  49         do {                                            \
  50                 if (!(x))                               \
  51                         longjmp(db->cpp_jmp, 1);     \
  52         } while (0)
  53 
  54 #define TOP_L(db) (&(name_top(&(db)->cpp_name)->strp_l))
  55 #define RLEN(f, l) ((size_t)((l) - (f)))
  56 #define NAMT(db, n) (nlen(db) - n)
  57 
  58 static inline boolean_t is_digit(int);
  59 static inline boolean_t is_upper(int);
  60 static inline boolean_t is_xdigit(int);
  61 
  62 static boolean_t nempty(cpp_db_t *);
  63 static size_t nlen(cpp_db_t *);
  64 static void nadd_l(cpp_db_t *, const char *, size_t);
  65 static void njoin(cpp_db_t *, size_t, const char *);
  66 static void nfmt(cpp_db_t *, const char *, const char *);
  67 
  68 static void save_top(cpp_db_t *, size_t);
  69 static void sub(cpp_db_t *, size_t);
  70 
  71 static boolean_t tempty(const cpp_db_t *);
  72 static size_t ttlen(const cpp_db_t *);
  73 
  74 static void tsub(cpp_db_t *, size_t);
  75 static void tpush(cpp_db_t *);
  76 static void tpop(cpp_db_t *);
  77 static void tsave(cpp_db_t *, size_t);
  78 
  79 static void db_init(cpp_db_t *, sysdem_ops_t *);
  80 static void db_fini(cpp_db_t *);
  81 static void dump(cpp_db_t *, FILE *);
  82 
  83 static void demangle(const char *, const char *, cpp_db_t *);
  84 
  85 static const char *parse_type(const char *, const char *, cpp_db_t *);
  86 static const char *parse_builtin_type(const char *, const char *, cpp_db_t *);
  87 static const char *parse_qual_type(const char *, const char *, cpp_db_t *);
  88 static const char *parse_encoding(const char *, const char *, cpp_db_t *);
  89 static const char *parse_dot_suffix(const char *, const char *, cpp_db_t *);
  90 static const char *parse_block_invoke(const char *, const char *, cpp_db_t *);
  91 static const char *parse_special_name(const char *, const char *, cpp_db_t *);
  92 static const char *parse_name(const char *, const char *, boolean_t *,
  93     cpp_db_t *);
  94 static const char *parse_call_offset(const char *, const char *);
  95 static const char *parse_number(const char *, const char *);
  96 static const char *parse_nested_name(const char *, const char *, boolean_t *,
  97     cpp_db_t *);
  98 static const char *parse_local_name(const char *, const char *, boolean_t *,
  99     cpp_db_t *);
 100 static const char *parse_unscoped_name(const char *, const char *, cpp_db_t *);
 101 static const char *parse_template_args(const char *, const char *, cpp_db_t *);
 102 static const char *parse_substitution(const char *, const char *, cpp_db_t *);
 103 static const char *parse_discriminator(const char *, const char *);
 104 static const char *parse_cv_qualifiers(const char *, const char *, unsigned *);
 105 static const char *parse_template_param(const char *, const char *, cpp_db_t *);
 106 static const char *parse_decltype(const char *, const char *, cpp_db_t *);
 107 static const char *parse_template_args(const char *, const char *, cpp_db_t *);
 108 static const char *parse_unqualified_name(const char *, const char *,
 109     cpp_db_t *);
 110 static const char *parse_template_arg(const char *, const char *, cpp_db_t *);
 111 static const char *parse_expression(const char *, const char *, cpp_db_t *);
 112 static const char *parse_expr_primary(const char *, const char *, cpp_db_t *);
 113 static const char *parse_binary_expr(const char *, const char *,
 114     const char *, cpp_db_t *);
 115 static const char *parse_prefix_expr(const char *, const char *,
 116     const char *, cpp_db_t *);
 117 static const char *parse_gs(const char *, const char *, cpp_db_t *);
 118 static const char *parse_idx_expr(const char *, const char *, cpp_db_t *);
 119 static const char *parse_mm_expr(const char *, const char *, cpp_db_t *);
 120 static const char *parse_pp_expr(const char *, const char *, cpp_db_t *);
 121 static const char *parse_trinary_expr(const char *, const char *, cpp_db_t *);
 122 static const char *parse_new_expr(const char *, const char *, cpp_db_t *);
 123 static const char *parse_del_expr(const char *, const char *, cpp_db_t *);


 149     cpp_db_t *);
 150 static const char *parse_unresolved_qualifier_level(const char *, const char *,
 151     cpp_db_t *);
 152 static const char *parse_destructor_name(const char *, const char *,
 153     cpp_db_t *);
 154 static const char *parse_function_type(const char *, const char *, cpp_db_t *);
 155 static const char *parse_array_type(const char *, const char *, cpp_db_t *);
 156 static const char *parse_pointer_to_member_type(const char *, const char *,
 157     cpp_db_t *);
 158 static const char *parse_vector_type(const char *, const char *, cpp_db_t *);
 159 
 160 size_t cpp_name_max_depth = 1024;       /* max depth of name stack */
 161 
 162 char *
 163 cpp_demangle(const char *src, sysdem_ops_t *ops)
 164 {
 165         char *result = NULL;
 166         cpp_db_t db;
 167         size_t srclen = strlen(src);
 168 
 169         db_init(&db, ops);
 170 
 171         if (setjmp(db.cpp_jmp) != 0)
 172                 goto done;
 173 
 174         errno = 0;
 175         demangle(src, src + srclen, &db);
 176 
 177         if (errno == 0 && db.cpp_fix_forward_references &&
 178             !templ_empty(&db.cpp_templ) &&
 179             !sub_empty(&db.cpp_templ.tpl_items[0])) {
 180                 db.cpp_fix_forward_references = B_FALSE;
 181                 db.cpp_tag_templates = B_FALSE;
 182                 name_clear(&db.cpp_name);
 183                 sub_clear(&db.cpp_subs);
 184 
 185                 if (setjmp(db.cpp_jmp) != 0)
 186                         goto done;
 187 
 188                 demangle(src, src + srclen, &db);
 189 
 190                 if (db.cpp_fix_forward_references) {


 254                 }
 255 
 256                 goto done;
 257         }
 258 
 259         if (first[1] != '_' || first[2] != '_' || first[3] != 'Z')
 260                 goto done;
 261 
 262         t = parse_encoding(first + 4, last, db);
 263         if (t != first + 4 && t != last)
 264                 t = parse_block_invoke(t, last, db);
 265 
 266 done:
 267         if (t != last)
 268                 errno = EINVAL;
 269 }
 270 
 271 static const char *
 272 parse_dot_suffix(const char *first, const char *last, cpp_db_t *db)
 273 {
 274         ASSERT3P(first, <=, last);
 275 
 276         if (first == last || first[0] != '.')
 277                 return (first);
 278 
 279         if (nempty(db))
 280                 return (first);
 281 
 282         nadd_l(db, first, RLEN(first, last));
 283         nfmt(db, " ({0})", NULL);
 284 
 285         return (last);
 286 }
 287 
 288 /*
 289  * _block_invoke
 290  * _block_invoke<digit>+  XXX: should it be <digit>* ?
 291  * _block_invoke_<digit>+
 292  */
 293 static const char *
 294 parse_block_invoke(const char *first, const char *last, cpp_db_t *db)
 295 {
 296         ASSERT3P(first, <=, last);
 297 
 298         if (last - first < 13)
 299                 return (first);
 300 
 301         const char test[] = "_block_invoke";
 302         const char *t = first;
 303 
 304         if (strncmp(first, test, sizeof (test) - 1) != 0)
 305                 return (first);
 306 
 307         t += sizeof (test);
 308         if (t == last)
 309                 goto done;
 310 
 311         if (t[0] == '_') {
 312                 /* need at least one digit */
 313                 if (t + 1 == last || !is_digit(t[1]))
 314                         return (first);
 315                 t += 2;
 316         }
 317 
 318         while (t < last && is_digit(t[0]))
 319                 t++;
 320 
 321 done:
 322         if (nempty(db))
 323                 return (first);
 324 
 325         nfmt(db, "invocation function for block in {0}", NULL);
 326         return (t);
 327 }
 328 
 329 /*
 330  * <encoding> ::= <function name><bare-function-type>
 331  *            ::= <data name>
 332  *            ::= <special name>
 333  */
 334 static const char *
 335 parse_encoding(const char *first, const char *last, cpp_db_t *db)
 336 {
 337         ASSERT3P(first, <=, last);
 338 
 339         if (first == last)
 340                 return (first);
 341 
 342         const char *t = NULL;
 343         const char *t2 = NULL;
 344         unsigned cv = 0;
 345         unsigned ref = 0;
 346         boolean_t tag_templ_save = db->cpp_tag_templates;
 347 
 348         if (++db->cpp_depth > 1)
 349                 db->cpp_tag_templates = B_TRUE;
 350 
 351         if (first[0] == 'G' || first[0] == 'T') {
 352                 t = parse_special_name(first, last, db);
 353                 goto done;
 354         }
 355 
 356         boolean_t ends_with_template_args = B_FALSE;
 357         t = parse_name(first, last, &ends_with_template_args, db);


 390         if (t[0] == 'v') {
 391                 t++;
 392         } else {
 393 
 394                 /*CONSTCOND*/
 395                 while (1) {
 396                         t2 = parse_type(t, last, db);
 397                         if (t2 == t || t == last)
 398                                 break;
 399 
 400                         t = t2;
 401                 }
 402         }
 403 
 404         /*
 405          * a bit of a hack, but a template substitution can apparently be
 406          * an empty string at the end of an argument list, so avoid
 407          * <...., >
 408          */
 409         if (NAMT(db, n) > 1 && str_pair_len(name_top(&db->cpp_name)) == 0)
 410                 (void) name_pop(&db->cpp_name, NULL);
 411 
 412         njoin(db, NAMT(db, n), ", ");
 413         nfmt(db, "({0})", NULL);
 414 
 415         str_t *s = TOP_L(db);
 416 
 417         if (cv & CPP_QUAL_CONST) {
 418                 CK(str_append(s, " const", 0));
 419         }
 420         if (cv & CPP_QUAL_VOLATILE) {
 421                 CK(str_append(s, " volatile", 0));
 422         }
 423         if (cv & CPP_QUAL_RESTRICT) {
 424                 CK(str_append(s, " restrict", 0));
 425         }
 426         if (ref == 1) {
 427                 CK(str_append(s, " &", 0));
 428         }
 429         if (ref == 2) {
 430                 CK(str_append(s, " &&", 0));


 448  *                ::= TT <type>    # VTT structure (construction vtable index)
 449  *                ::= TI <type>    # typeinfo structure
 450  *                ::= TS <type>    # typeinfo name (null-terminated byte string)
 451  *                ::= Tc <call-offset> <call-offset> <base encoding>
 452  *                    # base is the nominal target function of thunk
 453  *                    # first call-offset is 'this' adjustment
 454  *                    # second call-offset is result adjustment
 455  *                ::= T <call-offset> <base encoding>
 456  *                    # base is the nominal target function of thunk
 457  *                ::= GV <object name> # Guard variable for one-time init
 458  *                                     # No <type>
 459  *                ::= TW <object name> # Thread-local wrapper
 460  *                ::= TH <object name> # Thread-local initialization
 461  *      extension ::= TC <first type> <number> _ <second type>
 462  *                                     # construction vtable for second-in-first
 463  *      extension ::= GR <object name> # reference temporary for object
 464  */
 465 static const char *
 466 parse_special_name(const char *first, const char *last, cpp_db_t *db)
 467 {
 468         ASSERT3P(first, <=, last);
 469 
 470         const char *t = first;
 471         const char *t1 = NULL;
 472         size_t n = nlen(db);
 473 
 474         if (last - first < 2)
 475                 return (first);
 476 
 477         switch (t[0]) {
 478         case 'T':
 479                 switch (t[1]) {
 480                 case 'V':
 481                         nadd_l(db, "vtable for", 0);
 482                         t = parse_type(first + 2, last, db);
 483                         break;
 484                 case 'T':
 485                         nadd_l(db, "VTT for", 0);
 486                         t = parse_type(first + 2, last, db);
 487                         break;
 488                 case 'I':
 489                         nadd_l(db, "typeinfo for", 0);
 490                         t = parse_type(first + 2, last, db);
 491                         break;
 492                 case 'S':
 493                         nadd_l(db, "typeinfo name for", 0);
 494                         t = parse_type(first + 2, last, db);
 495                         break;
 496                 case 'c':
 497                         nadd_l(db, "covariant return thunk to", 0);
 498                         t1 = parse_call_offset(first + 2, last);
 499                         if (t1 == t)
 500                                 return (first);
 501                         t = parse_call_offset(t1, last);
 502                         if (t == t1)
 503                                 return (first);
 504                         t1 = parse_encoding(t, last, db);
 505                         if (t1 == t)
 506                                 return (first);
 507                         break;
 508                 case 'C':
 509                         t = parse_type(first + 2, last, db);
 510                         if (t == first + 2)
 511                                 return (first);
 512                         t1 = parse_number(t, last);
 513                         if (*t1 != '_')
 514                                 return (first);
 515                         t = parse_type(t1 + 1, last, db);
 516                         if (t == t1 + 1 || nlen(db) < 2)
 517                                 return (first);
 518                         nfmt(db, "construction vtable for {0}-in-{1}", NULL);
 519                         return (t);
 520                 case 'W':
 521                         nadd_l(db, "thread-local wrapper routine for", 0);
 522                         t = parse_name(first + 2, last, NULL, db);
 523                         break;
 524                 case 'H':
 525                         nadd_l(db, "thread-local initialization routine for",
 526                             0);
 527                         t = parse_name(first + 2, last, NULL, db);
 528                         break;
 529                 default:
 530                         if (first[1] == 'v') {
 531                                 nadd_l(db, "virtual thunk to", 0);
 532                         } else {
 533                                 nadd_l(db, "non-virtual thunk to", 0);
 534                         }
 535 
 536                         t = parse_call_offset(first + 1, last);
 537                         if (t == first + 1)
 538                                 return (first);
 539                         t1 = parse_encoding(t, last, db);
 540                         if (t == t1)
 541                                 return (first);
 542                         t = t1;
 543                         break;
 544                 }
 545                 break;
 546         case 'G':
 547                 switch (first[1]) {
 548                 case 'V':
 549                         nadd_l(db, "guard variable for", 0);
 550                         t = parse_name(first + 2, last, NULL, db);
 551                         break;
 552                 case 'R':
 553                         nadd_l(db, "reference temporary for", 0);
 554                         t = parse_name(first + 2, last, NULL, db);
 555                         break;
 556                 default:


 563 
 564         size_t amt = NAMT(db, n);
 565         if (t == first + 2 || amt < 2)
 566                 return (first);
 567 
 568         njoin(db, amt, " ");
 569         return (t);
 570 }
 571 
 572 /*
 573  * <call-offset> ::= h <nv-offset> _
 574  *               ::= v <v-offset> _
 575  *
 576  * <nv-offset> ::= <offset number>
 577  *               # non-virtual base override
 578  *
 579  * <v-offset>  ::= <offset number> _ <virtual offset number>
 580  *               # virtual base override, with vcall offset
 581  */
 582 static const char *
 583 parse_call_offset(const char *first, const char *last)
 584 {
 585         ASSERT3P(first, <=, last);
 586 
 587         const char *t = NULL;
 588         const char *t1 = NULL;
 589 
 590         if (first == last)
 591                 return (first);
 592 
 593         if (first[0] != 'h' && first[0] != 'v')
 594                 return (first);
 595 
 596         t = parse_number(first + 1, last);
 597         if (t == first + 1 || t == last || t[0] != '_')
 598                 return (first);
 599 
 600         /* skip _ */
 601         t++;
 602 
 603         if (first[0] == 'h')
 604                 return (t);
 605 
 606         t1 = parse_number(t, last);
 607         if (t == t1 || t1 == last || t1[0] != '_')
 608                 return (first);
 609 
 610         /* skip _ */
 611         t1++;
 612 
 613         return (t1);
 614 }
 615 
 616 /*
 617  * <name> ::= <nested-name> // N
 618  *        ::= <local-name> # See Scope Encoding below  // Z
 619  *        ::= <unscoped-template-name> <template-args>
 620  *        ::= <unscoped-name>
 621  *
 622  * <unscoped-template-name> ::= <unscoped-name>
 623  *                          ::= <substitution>
 624  */
 625 static const char *
 626 parse_name(const char *first, const char *last,
 627     boolean_t *ends_with_template_args, cpp_db_t *db)
 628 {
 629         ASSERT3P(first, <=, last);
 630 
 631         const char *t = first;
 632         const char *t1 = NULL;
 633 
 634         if (last - first < 2)
 635                 return (first);
 636 
 637         /* extension: ignore L here */
 638         if (t[0] == 'L')
 639                 t++;
 640 
 641         switch (t[0]) {
 642         case 'N':
 643                 t1 = parse_nested_name(t, last, ends_with_template_args, db);
 644                 return ((t == t1) ? first : t1);
 645         case 'Z':
 646                 t1 = parse_local_name(t, last, ends_with_template_args, db);
 647                 return ((t == t1) ? first : t1);
 648         }
 649 


 672 
 673         nfmt(db, "{1:L}{0}", "{1:R}");
 674 
 675         if (ends_with_template_args != NULL)
 676                 *ends_with_template_args = B_TRUE;
 677 
 678         return (t);
 679 }
 680 
 681 /* BEGIN CSTYLED */
 682 /*
 683  * <local-name> := Z <function encoding> E <entity name> [<discriminator>]
 684  *              := Z <function encoding> E s [<discriminator>]
 685  *              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
 686  */
 687 /* END CSTYLED */
 688 const char *
 689 parse_local_name(const char *first, const char *last,
 690     boolean_t *ends_with_template_args, cpp_db_t *db)
 691 {
 692         ASSERT3P(first, <=, last);
 693 
 694         const char *t = NULL;
 695         const char *t1 = NULL;
 696         const char *t2 = NULL;
 697 
 698         if (first == last || first[0] != 'Z')
 699                 return (first);
 700 
 701         t = parse_encoding(first + 1, last, db);
 702         if (t == first + 1 || t == last || t[0] != 'E')
 703                 return (first);
 704 
 705         ASSERT(!nempty(db));
 706 
 707         /* skip E */
 708         t++;
 709 
 710         if (t[0] == 's') {
 711                 nfmt(db, "{0:L}::string literal", "{0:R}");
 712                 return (parse_discriminator(t, last));
 713         }
 714 
 715         if (t[0] == 'd') {
 716                 t1 = parse_number(t + 1, last);
 717                 if (t1[0] != '_')
 718                         return (first);
 719                 t1++;
 720         } else {
 721                 t1 = t;
 722         }
 723 
 724         t2 = parse_name(t1, last, ends_with_template_args, db);
 725         if (t2 == t1)
 726                 return (first);
 727 
 728         nfmt(db, "{1:L}::{0}", "{1:R}");
 729 
 730         /* parsed, but ignored */
 731         if (t[0] != 'd')
 732                 t2 = parse_discriminator(t2, last);
 733 
 734         return (t2);
 735 }
 736 
 737 /* BEGIN CSTYLED */
 738 /*
 739  * <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
 740  *               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
 741  *
 742  * <prefix> ::= <prefix> <unqualified-name>
 743  *          ::= <template-prefix> <template-args>
 744  *          ::= <template-param>
 745  *          ::= <decltype>
 746  *          ::= # empty
 747  *          ::= <substitution>
 748  *          ::= <prefix> <data-member-prefix>
 749  *  extension ::= L
 750  *
 751  * <template-prefix> ::= <prefix> <template unqualified-name>
 752  *                   ::= <template-param>
 753  *                   ::= <substitution>
 754  */
 755 /* END CSTYLED */
 756 static const char *
 757 parse_nested_name(const char *first, const char *last,
 758     boolean_t *ends_with_template_args, cpp_db_t *db)
 759 {
 760         ASSERT3P(first, <=, last);
 761 
 762         if (first == last || first[0] != 'N')
 763                 return (first);
 764 
 765         unsigned cv = 0;
 766         const char *t = parse_cv_qualifiers(first + 1, last, &cv);
 767 
 768         if (t == last)
 769                 return (first);
 770 
 771         boolean_t more = B_FALSE;
 772 
 773         switch (t[0]) {
 774         case 'R':
 775                 db->cpp_ref = 1;
 776                 t++;
 777                 break;
 778         case 'O':
 779                 db->cpp_ref = 2;
 780                 t++;


 793         boolean_t pop_subs = B_FALSE;
 794         boolean_t component_ends_with_template_args = B_FALSE;
 795 
 796         while (t[0] != 'E' && t != last) {
 797                 const char *t1 = NULL;
 798                 size_t n = nlen(db);
 799                 component_ends_with_template_args = B_FALSE;
 800 
 801                 switch (t[0]) {
 802                 case 'S':
 803                         if (t + 1 != last && t[1] == 't')
 804                                 break;
 805 
 806                         t1 = parse_substitution(t, last, db);
 807                         if (t1 == t || t1 == last || NAMT(db, n) != 1)
 808                                 return (first);
 809 
 810                         if (!more) {
 811                                 nfmt(db, "{0}", NULL);
 812                         } else {
 813                                 ASSERT3U(nlen(db), >, 1);
 814                                 nfmt(db, "{1:L}::{0}", "{1:R}");
 815                                 save_top(db, 1);
 816                         }
 817 
 818                         more = B_TRUE;
 819                         pop_subs = B_TRUE;
 820                         t = t1;
 821                         continue;
 822 
 823                 case 'T':
 824                         t1 = parse_template_param(t, last, db);
 825                         if (t1 == t || t1 == last || NAMT(db, n) != 1)
 826                                 return (first);
 827 
 828                         if (!more) {
 829                                 nfmt(db, "{0}", NULL);
 830                         } else {
 831                                 ASSERT3U(nlen(db), >, 1);
 832                                 nfmt(db, "{1:L}::{0}", "{1:R}");
 833                         }
 834 
 835                         save_top(db, 1);
 836                         more = B_TRUE;
 837                         pop_subs = B_TRUE;
 838                         t = t1;
 839                         continue;
 840 
 841                 case 'D':
 842                         if (t + 1 != last && t[1] != 't' && t[1] != 'T')
 843                                 break;
 844                         t1 = parse_decltype(t, last, db);
 845                         if (t1 == t || t1 == last || NAMT(db, n) != 1)
 846                                 return (first);
 847 
 848                         if (!more) {
 849                                 nfmt(db, "{0}", NULL);
 850                         } else {
 851                                 ASSERT3U(nlen(db), >, 1);
 852                                 nfmt(db, "{1:L}::{0}", "{1:R}");
 853                         }
 854 
 855                         save_top(db, 1);
 856                         more = B_TRUE;
 857                         pop_subs = B_TRUE;
 858                         t = t1;
 859                         continue;
 860 
 861                 case 'I':
 862                         /*
 863                          * Must have at least one component before
 864                          * <template-args>
 865                          */
 866                         if (!more)
 867                                 return (first);
 868 
 869                         t1 = parse_template_args(t, last, db);
 870                         if (t1 == t || t1 == last)
 871                                 return (first);
 872 
 873                         ASSERT3U(nlen(db), >, 1);
 874                         nfmt(db, "{1:L}{0}", "{1:R}");
 875                         save_top(db, 1);
 876                         t = t1;
 877                         component_ends_with_template_args = B_TRUE;
 878                         continue;
 879 
 880                 case 'L':
 881                         if (t + 1 == last)
 882                                 return (first);
 883                         t++;
 884                         continue;
 885 
 886                 default:
 887                         break;
 888                 }
 889 
 890                 t1 = parse_unqualified_name(t, last, db);
 891                 if (t1 == t || t1 == last || NAMT(db, n) != 1)
 892                         return (first);
 893 
 894                 if (!more) {
 895                         nfmt(db, "{0}", NULL);
 896                 } else {
 897                         ASSERT3U(nlen(db), >, 1);
 898                         nfmt(db, "{1:L}::{0}", "{1:R}");
 899                 }
 900 
 901                 save_top(db, 1);
 902                 more = B_TRUE;
 903                 pop_subs = B_TRUE;
 904                 t = t1;
 905         }
 906 
 907         /* need to parse at least one thing */
 908         if (!more)
 909                 return (first);
 910 
 911         db->cpp_cv = cv;
 912         if (pop_subs && !sub_empty(&db->cpp_subs))
 913                 sub_pop(&db->cpp_subs);
 914 
 915         if (ends_with_template_args != NULL)
 916                 *ends_with_template_args = component_ends_with_template_args;
 917 
 918         if (t[0] != 'E')
 919                 return (first);
 920 
 921         return (t + 1);
 922 }
 923 
 924 /*
 925  * <template-arg> ::= <type>                   # type or template
 926  *                ::= X <expression> E         # expression
 927  *                ::= <expr-primary>           # simple expressions
 928  *                ::= J <template-arg>* E      # argument pack
 929  *                ::= LZ <encoding> E          # extension
 930  */
 931 static const char *
 932 parse_template_arg(const char *first, const char *last, cpp_db_t *db)
 933 {
 934         ASSERT3P(first, <=, last);
 935 
 936         const char *t = NULL;
 937         const char *t1 = NULL;
 938 
 939         if (first == last)
 940                 return (first);
 941 
 942         switch (first[0]) {
 943         case 'X':
 944                 t = parse_expression(first + 1, last, db);
 945                 if (t == first + 1 || t[0] != 'E')
 946                         return (first);
 947 
 948                 /* E */
 949                 t++;
 950                 break;
 951 
 952         case 'J':
 953                 t = first + 1;
 954                 if (t == last)


1114         PA("rS", ">>=", parse_binary_expr),
1115         PN("rc", parse_cast_expr),
1116         PA("rm", "%", parse_binary_expr),
1117         PA("rs", ">>", parse_binary_expr),
1118         PN("sc", parse_cast_expr),
1119         PN("sp", parse_pack_expansion),
1120         PN("sr", parse_unresolved_name),
1121         PN("st", parse_sizeof),
1122         PN("sz", parse_sizeof),
1123         PN("sZ", parse_sizeof_param_pack_expr),
1124         PN("te", parse_typeid_expr),
1125         PN("tr", parse_throw_expr),
1126         PN("tw", parse_throw_expr)
1127 };
1128 #undef PA
1129 #undef PN
1130 
1131 static const char *
1132 parse_expression(const char *first, const char *last, cpp_db_t *db)
1133 {
1134         ASSERT3P(first, <=, last);
1135 
1136         if (last - first < 2)
1137                 return (first);
1138 
1139         for (size_t i = 0; i < ARRAY_SIZE(expr_tbl); i++) {
1140                 if (strncmp(expr_tbl[i].code, first, 2) != 0)
1141                         continue;
1142                 switch (expr_tbl[i].fntype) {
1143                 case EXPR_ARG:
1144                         return (expr_tbl[i].p.parse_expr_arg(first, last,
1145                             expr_tbl[i].val, db));
1146                 case EXPR_NOARG:
1147                         return (expr_tbl[i].p.parse_expr_noarg(first, last,
1148                             db));
1149                 }
1150         }
1151 
1152         switch (first[0]) {
1153         case 'L':
1154                 return (parse_expr_primary(first, last, db));


1158                 return (parse_function_param(first, last, db));
1159         case '1':
1160         case '2':
1161         case '3':
1162         case '4':
1163         case '5':
1164         case '6':
1165         case '7':
1166         case '8':
1167         case '9':
1168                 return (parse_unresolved_name(first, last, db));
1169         }
1170 
1171         return (first);
1172 }
1173 
1174 static const char *
1175 parse_binary_expr(const char *first, const char *last, const char *op,
1176     cpp_db_t *db)
1177 {
1178         ASSERT3P(first, <=, last);
1179 
1180         if (last - first < 2)
1181                 return (first);
1182 
1183         size_t n = nlen(db);
1184 
1185         const char *t1 = parse_expression(first + 2, last, db);
1186         if (t1 == first + 2)
1187                 return (first);
1188 
1189         nadd_l(db, op, 0);
1190 
1191         const char *t2 = parse_expression(t1, last, db);
1192         if (t2 == t1)
1193                 return (first);
1194 
1195         if (NAMT(db, n) != 3)
1196                 return (first);
1197 
1198         ASSERT3U(nlen(db), >, 2);
1199 
1200         nfmt(db, "({2}) {1} ({0})", NULL);
1201         if (strcmp(op, ">") == 0)
1202                 nfmt(db, "({0})", NULL);
1203 
1204         return (t2);
1205 }
1206 
1207 static const char *
1208 parse_prefix_expr(const char *first, const char *last, const char *op,
1209     cpp_db_t *db)
1210 {
1211         ASSERT3P(first, <=, last);
1212 
1213         if (last - first < 2)
1214                 return (first);
1215 
1216         nadd_l(db, op, 0);
1217 
1218         const char *t = parse_expression(first + 2, last, db);
1219         if (t == first + 2) {
1220                 return (first);
1221         }
1222 
1223         ASSERT3U(nlen(db), >, 1);
1224 
1225         nfmt(db, "{1}({0})", NULL);
1226         return (t);
1227 }
1228 
1229 static const char *
1230 parse_gs(const char *first, const char *last, cpp_db_t *db)
1231 {
1232         ASSERT3P(first, <=, last);
1233 
1234         const char *t = NULL;
1235 
1236         if (last - first < 4)
1237                 return (first);
1238 
1239         if (first[2] == 'n' && (first[3] == 'a' || first[3] == 'w'))
1240                 t = parse_new_expr(first + 2, last, db);
1241         else if (first[2] == 'd' && (first[3] == 'l' || first[3] == 'a'))
1242                 t = parse_del_expr(first + 2, last, db);
1243         else
1244                 return (first);
1245 
1246         if (t == first + 2)
1247                 return (first);
1248 
1249         ASSERT3U(nlen(db), >, 0);
1250 
1251         nfmt(db, "::{0}", NULL);
1252         return (t);
1253 }
1254 
1255 /*
1256  * [gs] nw <expression>* _ <type> E         # new (expr-list) type
1257  * [gs] nw <expression>* _ <type> <initializer>       # new (expr-list) type (init)
1258  * [gs] na <expression>* _ <type> E         # new[] (expr-list) type
1259  * [gs] na <expression>* _ <type> <initializer>       # new[] (expr-list) type (init)
1260  * <initializer> ::= pi <expression>* E             # parenthesized initialization
1261  */
1262 static const char *
1263 parse_new_expr(const char *first, const char *last, cpp_db_t *db)
1264 {
1265         ASSERT3P(first, <=, last);
1266 
1267         /* note [gs] is already handled by parse_gs() */
1268         if (last - first < 3)
1269                 return (first);
1270 
1271         ASSERT3U(first[0], ==, 'n');
1272         ASSERT(first[1] == 'a' || first[1] == 'w');
1273 
1274         const char *t1 = first + 2;
1275         const char *t2 = NULL;
1276         size_t n = nlen(db);
1277 
1278         nadd_l(db, (first[1] == 'w') ? "new" : "new[]", 0);
1279 
1280         while (t1 != last && t1[0] != '_') {
1281                 t2 = parse_expression(t1, last, db);
1282                 ASSERT3P(t2, !=, NULL);
1283                 if (t2 == t1)
1284                         return (first);
1285                 t1 = t2;
1286         }
1287         if (t1 == last)
1288                 return (first);
1289 
1290         if (NAMT(db, n) > 1) {
1291                 njoin(db, NAMT(db, n) - 1, ", ");
1292                 nfmt(db, "({0})", NULL);
1293         }
1294 
1295         t2 = parse_type(t1 + 1, last, db);
1296         if (t1 + 1 == t2)
1297                 return (first);
1298 
1299         if (t2[0] != 'E') {
1300                 if (last - t2 < 3)
1301                         return (first);
1302                 if (t2[0] != 'p' && t2[1] != 'i')


1312                         if (t2 == t3)
1313                                 return (first);
1314                         t2 = t3;
1315                 }
1316                 if (t3 == last || t3[0] != 'E')
1317                         return (first);
1318 
1319                 if (NAMT(db, n1) > 0) {
1320                         njoin(db, NAMT(db, n1), ", ");
1321                         nfmt(db, "({0})", NULL);
1322                 }
1323         }
1324 
1325         njoin(db, NAMT(db, n), " ");
1326         return (t2 + 1);
1327 }
1328 
1329 static const char *
1330 parse_del_expr(const char *first, const char *last, cpp_db_t *db)
1331 {
1332         ASSERT3P(first, <=, last);
1333 
1334         if (last - first < 3)
1335                 return (first);
1336 
1337         ASSERT3U(first[0], ==, 'd');
1338         ASSERT(first[1] == 'l' || first[1] == 'a');
1339 
1340         size_t n = nlen(db);
1341         const char *t = parse_expression(first + 2, last, db);
1342         if (t == first + 2 || NAMT(db, n) != 1)
1343                 return (first);
1344 
1345         nfmt(db, (first[1] == 'a') ? "delete[] {0}" : "delete {0}", NULL);
1346         return (t);
1347 }
1348 
1349 static const char *
1350 parse_idx_expr(const char *first, const char *last, cpp_db_t *db)
1351 {
1352         ASSERT3P(first, <=, last);
1353         ASSERT3U(first[0], ==, 'i');
1354         ASSERT3U(first[1], ==, 'x');
1355 
1356         size_t n = nlen(db);
1357         const char *t1 = parse_expression(first + 2, last, db);
1358         if (t1 == first + 2)
1359                 return (first);
1360 
1361         const char *t2 = parse_expression(t1, last, db);
1362         if (t2 == t1 || NAMT(db, n) != 2)
1363                 return (first);
1364 
1365         nfmt(db, "({0})[{1}]", NULL);
1366         return (t2);
1367 }
1368 
1369 static const char *
1370 parse_ppmm_expr(const char *first, const char *last, const char *fmt,
1371     cpp_db_t *db)
1372 {
1373         ASSERT3P(first, <=, last);
1374 
1375         if (last - first < 3)
1376                 return (first);
1377 
1378         const char *t = NULL;
1379         size_t n = nlen(db);
1380 
1381         if (first[2] == '_') {
1382                 t = parse_binary_expr(first + 3, last, "--", db);
1383                 if (t == first + 3)
1384                         return (first);
1385                 return (t);
1386         }
1387 
1388         t = parse_expression(first + 2, last, db);
1389         if (t == first + 2 || NAMT(db, n) < 1)
1390                 return (first);
1391 
1392         nfmt(db, fmt, NULL);
1393         return (t);
1394 }
1395 
1396 static const char *
1397 parse_mm_expr(const char *first, const char *last, cpp_db_t *db)
1398 {
1399         ASSERT3P(first, <=, last);
1400         ASSERT3U(first[0], ==, 'm');
1401         ASSERT3U(first[1], ==, 'm');
1402 
1403         return (parse_ppmm_expr(first, last, "({0})--", db));
1404 }
1405 
1406 static const char *
1407 parse_pp_expr(const char *first, const char *last, cpp_db_t *db)
1408 {
1409         ASSERT3P(first, <=, last);
1410 
1411         ASSERT3U(first[0], ==, 'p');
1412         ASSERT3U(first[0], ==, 'p');
1413 
1414         return (parse_ppmm_expr(first, last, "({0})++", db));
1415 }
1416 
1417 static const char *
1418 parse_trinary_expr(const char *first, const char *last, cpp_db_t *db)
1419 {
1420         ASSERT3P(first, <=, last);
1421 
1422         const char *t1, *t2, *t3;
1423         size_t n = nlen(db);
1424 
1425         if (last - first < 2)
1426                 return (first);
1427 
1428         t1 = parse_expression(first + 2, last, db);
1429         if (t1 == first + 2)
1430                 return (first);
1431         t2 = parse_expression(t1, last, db);
1432         if (t1 == t2)
1433                 return (first);
1434         t3 = parse_expression(t2, last, db);
1435         if (t3 == t2)
1436                 return (first);
1437 
1438         if (NAMT(db, n) != 3)
1439                 return (first);
1440 
1441         nfmt(db, "({2}) ? ({1}) : ({0})", NULL);
1442         return (t3);
1443 }
1444 
1445 static const char *
1446 parse_noexcept_expr(const char *first, const char *last, cpp_db_t *db)
1447 {
1448         ASSERT3P(first, <=, last);
1449 
1450         if (last - first < 2)
1451                 return (first);
1452 
1453         size_t n = nlen(db);
1454         const char *t = parse_expression(first + 2, last, db);
1455         if (t == first + 2 || NAMT(db, n) != 1)
1456                 return (first);
1457 
1458         nfmt(db, "noexcept ({0})", NULL);
1459         return (t);
1460 }
1461 
1462 /*
1463  * cc <type> <expression>   # const_cast<type> (expression)
1464  * dc <type> <expression>   # dynamic_cast<type> (expression)
1465  * rc <type> <expression>   # reinterpret_cast<type> (expression)
1466  * sc <type> <expression>   # static_cast<type> (expression)
1467  */
1468 static const char *
1469 parse_cast_expr(const char *first, const char *last, cpp_db_t *db)
1470 {
1471         ASSERT3P(first, <=, last);
1472 
1473         if (last - first < 2)
1474                 return (first);
1475 
1476         const char *fmt = NULL;
1477         switch (first[0]) {
1478         case 'c':
1479                 fmt = "const_cast<{1}> ({0})";
1480                 break;
1481         case 'd':
1482                 fmt = "dynamic_cast<{1}> ({0})";
1483                 break;
1484         case 'r':
1485                 fmt = "reinterpret_cast<{1}> ({0})";
1486                 break;
1487         case 's':
1488                 fmt = "static_cast<{1}> ({0})";
1489                 break;
1490         default:
1491                 return (first);
1492         }
1493 
1494         ASSERT3U(first[1], ==, 'c');
1495 
1496         const char *t1 = parse_type(first + 2, last, db);
1497         if (t1 == first + 2)
1498                 return (first);
1499 
1500         const char *t2 = parse_expression(t1, last, db);
1501         if (t2 == t1)
1502                 return (first);
1503 
1504         ASSERT3U(nlen(db), >, 1);
1505 
1506         nfmt(db, fmt, NULL);
1507         return (t2);
1508 }
1509 
1510 /* pt <expression> <expression>             # expr->name */
1511 static const char *
1512 parse_arrow_expr(const char *first, const char *last, cpp_db_t *db)
1513 {
1514         ASSERT3P(first, <=, last);
1515 
1516         if (last - first < 4)
1517                 return (first);
1518 
1519         size_t n = nlen(db);
1520 
1521         const char *t1 = parse_expression(first + 2, last, db);
1522         if (t1 == first + 2)
1523                 return (first);
1524 
1525         const char *t2 = parse_expression(t1, last, db);
1526         if (t2 == t1 || NAMT(db, n) != 2)
1527                 return (first);
1528 
1529         nfmt(db, "{1}->{0}", NULL);
1530         return (t2);
1531 }
1532 
1533 /* wrap value in () when necessary */
1534 static void


1559  *        ::= <decltype>
1560  *        ::= <substitution>
1561  *        ::= <CV-qualifiers> <type>
1562  *        ::= P <type>        # pointer-to
1563  *        ::= R <type>        # reference-to
1564  *        ::= O <type>        # rvalue reference-to (C++0x)
1565  *        ::= C <type>        # complex pair (C 2000)
1566  *        ::= G <type>        # imaginary (C 2000)
1567  *        ::= Dp <type>       # pack expansion (C++0x)
1568  *        ::= U <source-name> <type>  # vendor extended type qualifier
1569  * extension := U <objc-name> <objc-type>  # objc-type<identifier>
1570  * extension := <vector-type> # <vector-type> starts with Dv
1571  *
1572  * <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
1573  * <objc-type> := <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
1574  */
1575 /* END CSTYLED */
1576 static const char *
1577 parse_type(const char *first, const char *last, cpp_db_t *db)
1578 {
1579         ASSERT3P(first, <=, last);
1580 
1581         if (first == last)
1582                 return (first);
1583 
1584         switch (first[0]) {
1585         case 'r':
1586         case 'V':
1587         case 'K':
1588                 return (parse_qual_type(first, last, db));
1589         }
1590 
1591         const char *t = first;
1592         const char *t1 = NULL;
1593         str_pair_t *sp = NULL;
1594         size_t n = nlen(db);
1595         size_t amt = 0;
1596 
1597         t = parse_builtin_type(first, last, db);
1598         if (t != first)
1599                 return (t);


1726 
1727                 nfmt(db, "{0}", NULL);
1728 
1729                 t1 = parse_type(t, last, db);
1730                 if (t1 == t || NAMT(db, n) < 2)
1731                         return (first);
1732 
1733                 const str_t *name = &name_at(&db->cpp_name, 1)->strp_l;
1734 
1735                 if (str_length(name) > 0 &&
1736                     strncmp(name->str_s, "objcproto", 9) != 0) {
1737                         nfmt(db, "{0} {1}", NULL);
1738                 } else {
1739                         t = parse_source_name(name->str_s + 9,
1740                             name->str_s + name->str_len, db);
1741                         if (t != name->str_s + 9) {
1742                                 nfmt(db, "{1}<{0}>", NULL);
1743 
1744                                 str_pair_t save = {0};
1745 
1746                                 (void) name_pop(&db->cpp_name, &save);
1747 
1748                                 /* get rid of 'objcproto' */
1749                                 (void) name_pop(&db->cpp_name, NULL);
1750                                 CK(name_add_str(&db->cpp_name, &save.strp_l,
1751                                     &save.strp_r));
1752                         } else {
1753                                 nfmt(db, "{1} {0}", NULL);
1754                         }
1755                 }
1756 
1757                 save_top(db, 1);
1758                 return (t1);
1759 
1760         case 'S':
1761                 if (first + 1 != last && first[1] == 't') {
1762                         t = parse_name(first, last, NULL, db);
1763                         if (t == first || NAMT(db, n) == 0)
1764                                 return (first);
1765 
1766                         save_top(db, 1);
1767                         return (t);
1768                 }
1769 


1824 
1825         /*
1826          * must check for builtin-types before class-enum-types to avoid
1827          * ambiguities with operator-names
1828          */
1829         t = parse_builtin_type(first, last, db);
1830         if (t != first)
1831                 return (t);
1832 
1833         t = parse_name(first, last, NULL, db);
1834         if (t == first || NAMT(db, n) == 0)
1835                 return (first);
1836 
1837         save_top(db, 1);
1838         return (t);
1839 }
1840 
1841 static const char *
1842 parse_qual_type(const char *first, const char *last, cpp_db_t *db)
1843 {
1844         ASSERT3P(first, <=, last);
1845 
1846         const char *t = NULL;
1847         const char *t1 = NULL;
1848         unsigned cv = 0;
1849 
1850         t = parse_cv_qualifiers(first, last, &cv);
1851         if (t == first)
1852                 return (first);
1853 
1854         size_t n = nlen(db);
1855         boolean_t is_func = !!(t[0] == 'F');
1856 
1857         t1 = parse_type(t, last, db);
1858         size_t amt = NAMT(db, n);
1859         if (t == t1 || amt == 0)
1860                 return (first);
1861 
1862         if (is_func)
1863                 sub_pop(&db->cpp_subs);
1864 


1899                 if (cv & 2) {
1900                         str_insert(s, pos, " volatile", 9);
1901                         pos += 9;
1902                 }
1903                 if (cv & 4) {
1904                         str_insert(s, pos, " restrict", 9);
1905                 }
1906         }
1907 
1908         save_top(db, amt);
1909         return (t1);
1910 }
1911 
1912 /*
1913  * at <type>              # alignof (a type)
1914  * az <expression>        # alignof (a expression)
1915  */
1916 static const char *
1917 parse_alignof(const char *first, const char *last, cpp_db_t *db)
1918 {
1919         ASSERT3P(first, <=, last);
1920 
1921         if (last - first < 2)
1922                 return (first);
1923 
1924         const char *(*fn)(const char *, const char *, cpp_db_t *);
1925 
1926         fn = (first[1] == 't') ? parse_type : parse_expression;
1927 
1928         size_t n = nlen(db);
1929         const char *t = fn(first + 2, last, db);
1930         if (t == first + 2 || NAMT(db, n) != 1)
1931                 return (first);
1932 
1933         nfmt(db, "alignof ({0})", NULL);
1934         return (t);
1935 }
1936 
1937 /*
1938  * st <type>      # sizeof (a type)
1939  * sz <expr>      # sizeof (a expression)
1940  */
1941 static const char *
1942 parse_sizeof(const char *first, const char *last, cpp_db_t *db)
1943 {
1944         ASSERT3P(first, <=, last);
1945 
1946         if (last - first < 2)
1947                 return (first);
1948 
1949         ASSERT3U(first[0], ==, 's');
1950 
1951         const char *t = NULL;
1952         size_t n = nlen(db);
1953 
1954         switch (first[1]) {
1955         case 't':
1956                 t = parse_type(first + 2, last, db);
1957                 break;
1958         case 'z':
1959                 t = parse_expression(first + 2, last, db);
1960                 break;
1961         default:
1962                 return (first);
1963         }
1964         if (t == first + 2 || NAMT(db, n) != 1)
1965                 return (first);
1966 
1967         nfmt(db, "sizeof ({0})", NULL);
1968         return (t);
1969 }
1970 
1971 /* BEGIN CSTYLED */
1972 /*
1973  * <function-param> ::= fp <top-level CV-qualifiers> _                                     # L == 0, first parameter
1974  *                  ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
1975  *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _         # L > 0, first parameter
1976  *                  ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
1977  */
1978 /* END CSTYLED */
1979 static const char *
1980 parse_function_param(const char *first, const char *last, cpp_db_t *db)
1981 {
1982         ASSERT3P(first, <=, last);
1983 
1984         if (last - first < 3 || first[0] != 'f')
1985                 return (first);
1986 
1987         const char *t1 = first + 2;
1988         const char *t2 = NULL;
1989         unsigned cv = 0;
1990 
1991         if (first[1] == 'L') {
1992                 t2 = parse_number(t1, last);
1993                 if (t2 == last || t2[0] != 'p')
1994                         return (first);
1995                 t1 = t2;
1996         }
1997 
1998         if (first[1] != 'p')
1999                 return (first);
2000 
2001         t1 = parse_cv_qualifiers(t1, last, &cv);
2002         t2 = parse_number(t1, last);
2003         if (t2 == last || t2[0] != '_')
2004                 return (first);
2005 
2006         if (t2 - t1 > 0)
2007                 nadd_l(db, t1, (size_t)(t2 - t1));
2008         else
2009                 nadd_l(db, "", 0);
2010 
2011         nfmt(db, "fp{0}", NULL);
2012         return (t2 + 1);
2013 }
2014 
2015 /*
2016  * sZ <template-param>            # size of a parameter pack
2017  * sZ <function-param>            # size of a function parameter pack
2018  */
2019 static const char *
2020 parse_sizeof_param_pack_expr(const char *first, const char *last, cpp_db_t *db)
2021 {
2022         ASSERT3P(first, <=, last);
2023 
2024         if (last - first < 3)
2025                 return (first);
2026 
2027         ASSERT3U(first[0], ==, 's');
2028         ASSERT3U(first[1], ==, 'Z');
2029 
2030         if (first[2] != 'T' && first[2] != 'f')
2031                 return (first);
2032 
2033         const char *t = NULL;
2034         size_t n = nlen(db);
2035 
2036         if (first[2] == 'T')
2037                 t = parse_template_param(first + 2, last, db);
2038         else
2039                 t = parse_function_param(first + 2, last, db);
2040 
2041         if (t == first + 2)
2042                 return (first);
2043 
2044         njoin(db, NAMT(db, n), ", ");
2045         nfmt(db, "sizeof...({0})", NULL);
2046         return (t);
2047 }
2048 
2049 /*
2050  * te <expression>                                      # typeid (expression)
2051  * ti <type>                                            # typeid (type)
2052  */
2053 static const char *
2054 parse_typeid_expr(const char *first, const char *last, cpp_db_t *db)
2055 {
2056         ASSERT3P(first, <=, last);
2057 
2058         if (last - first < 3)
2059                 return (first);
2060 
2061         ASSERT3U(first[0], ==, 't');
2062         ASSERT(first[1] == 'e' || first[1] == 'i');
2063 
2064         const char *t = NULL;
2065         size_t n = nlen(db);
2066 
2067         if (first[1] == 'e')
2068                 t = parse_expression(first + 2, last, db);
2069         else
2070                 t = parse_type(first + 2, last, db);
2071 
2072         if (t == first + 2 || NAMT(db, n) != 1)
2073                 return (first);
2074 
2075         nfmt(db, "typeid ({0})", NULL);
2076         return (t);
2077 }
2078 
2079 /*
2080  * tr                                                   # throw
2081  * tw <expression>                                      # throw expression
2082  */
2083 static const char *
2084 parse_throw_expr(const char *first, const char *last, cpp_db_t *db)
2085 {
2086         ASSERT3P(first, <=, last);
2087 
2088         if (last - first < 3)
2089                 return (first);
2090 
2091         ASSERT3U(first[0], ==, 't');
2092         ASSERT(first[1] == 'w' || first[1] == 'r');
2093 
2094         if (first[1] == 'r') {
2095                 nadd_l(db, "throw", 0);
2096                 return (first + 2);
2097         }
2098 
2099         size_t n = nlen(db);
2100         const char *t = parse_expression(first + 2, last, db);
2101         if (t == first + 2 || NAMT(db, n) != 1)
2102                 return (first);
2103 
2104         nfmt(db, "throw {0}", NULL);
2105         return (t);
2106 }
2107 
2108 /* ds <expression> <expression>             # expr.*expr */
2109 static const char *
2110 parse_dot_star_expr(const char *first, const char *last, cpp_db_t *db)
2111 {
2112         ASSERT3P(first, <=, last);
2113 
2114         if (last - first < 3)
2115                 return (first);
2116 
2117         ASSERT3U(first[0], ==, 'd');
2118         ASSERT3U(first[1], ==, 's');
2119 
2120         size_t n = nlen(db);
2121         const char *t = parse_expression(first + 2, last, db);
2122         if (t == first + 2)
2123                 return (first);
2124 
2125         const char *t2 = parse_expression(t, last, db);
2126         if (t == t2 || NAMT(db, n) != 2)
2127                 return (first);
2128 
2129         nfmt(db, "{1}.*{0}", NULL);
2130         return (t2);
2131 }
2132 
2133 /* dt <expression> <unresolved-name>                # expr.name */
2134 static const char *
2135 parse_dot_expr(const char *first, const char *last, cpp_db_t *db)
2136 {
2137         ASSERT3P(first, <=, last);
2138 
2139         if (last - first < 3)
2140                 return (first);
2141 
2142         ASSERT3U(first[0], ==, 'd');
2143         ASSERT3U(first[1], ==, 't');
2144 
2145         const char *t = parse_expression(first + 2, last, db);
2146         if (t == first + 2)
2147                 return (first);
2148 
2149         const char *t1 = parse_unresolved_name(t, last, db);
2150         if (t1 == t)
2151                 return (first);
2152 
2153         nfmt(db, "{1}.{0}", NULL);
2154         return (t1);
2155 }
2156 
2157 /* cl <expression>+ E             # call */
2158 static const char *
2159 parse_call_expr(const char *first, const char *last, cpp_db_t *db)
2160 {
2161         ASSERT3P(first, <=, last);
2162 
2163         if (last - first < 4)
2164                 return (first);
2165 
2166         ASSERT3U(first[0], ==, 'c');
2167         ASSERT3U(first[1], ==, 'l');
2168 
2169         const char *t = first + 2;
2170         const char *t1 = NULL;
2171         size_t n = nlen(db);
2172 
2173         for (t = first + 2; t != last && t[0] != 'E'; t = t1) {
2174                 t1 = parse_expression(t, last, db);
2175                 if (t1 == t)
2176                         return (first);
2177         }
2178 
2179         size_t amt = NAMT(db, n);
2180 
2181         if (t == last || amt == 0)
2182                 return (first);
2183 
2184         njoin(db, amt - 1, ", ");
2185         nfmt(db, "{1}({0})", NULL);
2186 
2187         ASSERT3U(t[0], ==, 'E');
2188         return (t + 1);
2189 }
2190 
2191 /* BEGIN CSTYLED */
2192 /*
2193  * cv <type> <expression>   # conversion with one argument
2194  * cv <type> _ <expression>* E      # conversion with a different number of arguments
2195  */
2196 /* END CSTYLED */
2197 static const char *
2198 parse_conv_expr(const char *first, const char *last, cpp_db_t *db)
2199 {
2200         ASSERT3P(first, <=, last);
2201 
2202         if (last - first < 3)
2203                 return (first);
2204 
2205         ASSERT3U(first[0], ==, 'c');
2206         ASSERT3U(first[1], ==, 'v');
2207 
2208         const char *t = NULL;
2209         const char *t1 = NULL;
2210         size_t n = nlen(db);
2211 
2212         boolean_t try_to_parse_template_args =
2213             db->cpp_try_to_parse_template_args;
2214 
2215         db->cpp_try_to_parse_template_args = B_FALSE;
2216         t = parse_type(first + 2, last, db);
2217         db->cpp_try_to_parse_template_args = try_to_parse_template_args;
2218 
2219         if (t == first + 2)
2220                 return (first);
2221 
2222         if (t[0] != '_') {
2223                 t1 = parse_expression(t, last, db);
2224                 if (t1 == t)
2225                         return (first);
2226 


2237                         t1 = t;
2238                 }
2239 
2240                 /* E */
2241                 t++;
2242 
2243                 njoin(db, NAMT(db, n1), ", ");
2244         }
2245 
2246         if (NAMT(db, n) < 2)
2247                 return (first);
2248 
2249         nfmt(db, "({1})({0})", NULL);
2250         return (t);
2251 }
2252 
2253 /* <simple-id> ::= <source-name> [ <template-args> ] */
2254 static const char *
2255 parse_simple_id(const char *first, const char *last, cpp_db_t *db)
2256 {
2257         ASSERT3P(first, <=, last);
2258 
2259         const char *t = parse_source_name(first, last, db);
2260         if (t == first)
2261                 return (t);
2262 
2263         const char *t1 = parse_template_args(t, last, db);
2264         if (t == t1)
2265                 return (t);
2266 
2267         nfmt(db, "{1}{0}", NULL);
2268         return (t1);
2269 }
2270 
2271 /*
2272  * <unresolved-type> ::= <template-param>
2273  *                   ::= <decltype>
2274  *                   ::= <substitution>
2275  */
2276 static const char *
2277 parse_unresolved_type(const char *first, const char *last, cpp_db_t *db)
2278 {
2279         ASSERT3P(first, <=, last);
2280 
2281         if (first == last)
2282                 return (first);
2283 
2284         const char *t = first;
2285         size_t n = nlen(db);
2286 
2287         switch (first[0]) {
2288         case 'T':
2289                 t = parse_template_param(first, last, db);
2290                 if (t == first || NAMT(db, n) != 1) {
2291                         for (size_t i = 0; i < NAMT(db, n); i++)
2292                                 (void) name_pop(&db->cpp_name, NULL);
2293                         return (first);
2294                 }
2295                 save_top(db, 1);
2296                 return (t);
2297 
2298         case 'D':
2299                 t = parse_decltype(first, last, db);
2300                 if (t == first || NAMT(db, n) == 0)
2301                         return (first);
2302                 save_top(db, 1);
2303                 return (t);
2304 
2305         case 'S':
2306                 t = parse_substitution(first, last, db);
2307                 if (t != first)
2308                         return (t);
2309 
2310                 if (last - first < 2 || first[1] != 't')
2311                         return (first);
2312 
2313                 t = parse_unqualified_name(first + 2, last, db);
2314                 if (t == first + 2 || NAMT(db, n) == 0)
2315                         return (first);
2316 
2317                 nfmt(db, "std::{0:L}", "{0:R}");
2318                 save_top(db, 1);
2319                 return (t);
2320         }
2321 
2322         return (first);
2323 }
2324 
2325 /* sp <expression>                # pack expansion */
2326 static const char *
2327 parse_pack_expansion(const char *first, const char *last, cpp_db_t *db)
2328 {
2329         ASSERT3P(first, <=, last);
2330 
2331         if (last - first < 3)
2332                 return (first);
2333 
2334         ASSERT3U(first[0], ==, 's');
2335         ASSERT3U(first[1], ==, 'p');
2336 
2337         const char *t = parse_expression(first + 2, last, db);
2338         if (t == first +2)
2339                 return (first);
2340 
2341         return (t);
2342 }
2343 
2344 /*
2345  * <unscoped-name> ::= <unqualified-name>
2346  *                 ::= St <unqualified-name>   # ::std::
2347  * extension       ::= StL<unqualified-name>
2348  */
2349 static const char *
2350 parse_unscoped_name(const char *first, const char *last, cpp_db_t *db)
2351 {
2352         ASSERT3P(first, <=, last);
2353 
2354         if (last - first < 2)
2355                 return (first);
2356 
2357         const char *t = first;
2358         const char *t1 = NULL;
2359         boolean_t st = B_FALSE;
2360 
2361         if (first[0] == 'S' && first[1] == 't') {
2362                 st = B_TRUE;
2363                 t = first + 2;
2364 
2365                 if (first + 3 != last && first[2] == 'L')
2366                         t++;
2367         }
2368 
2369         t1 = parse_unqualified_name(t, last, db);
2370         if (t == t1)
2371                 return (first);
2372 
2373         if (st)
2374                 nfmt(db, "std::{0}", NULL);
2375 
2376         return (t1);
2377 }
2378 
2379 /*
2380  * <unqualified-name> ::= <operator-name>
2381  *                    ::= <ctor-dtor-name>
2382  *                    ::= <source-name>
2383  *                    ::= <unnamed-type-name>
2384  */
2385 const char *
2386 parse_unqualified_name(const char *first, const char *last, cpp_db_t *db)
2387 {
2388         ASSERT3P(first, <=, last);
2389 
2390         if (first == last)
2391                 return (first);
2392 
2393         switch (*first) {
2394         case 'C':
2395         case 'D':
2396                 return (parse_ctor_dtor_name(first, last, db));
2397         case 'U':
2398                 return (parse_unnamed_type_name(first, last, db));
2399 
2400         case '1':
2401         case '2':
2402         case '3':
2403         case '4':
2404         case '5':
2405         case '6':
2406         case '7':
2407         case '8':
2408         case '9':
2409                 return (parse_source_name(first, last, db));
2410         default:
2411                 return (parse_operator_name(first, last, db));
2412         }
2413 }
2414 
2415 /*
2416  * <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
2417  *                     ::= <closure-type-name>
2418  *
2419  * <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
2420  *
2421  * <lambda-sig> ::= <parameter type>+
2422  *                      # Parameter types or "v" if the lambda has no parameters
2423  */
2424 static const char *
2425 parse_unnamed_type_name(const char *first, const char *last, cpp_db_t *db)
2426 {
2427         ASSERT3P(first, <=, last);
2428 
2429         if (last - first < 2 || first[0] != 'U')
2430                 return (first);
2431 
2432         if (first[1] != 't' && first[1] != 'l')
2433                 return (first);
2434 
2435         const char *t1 = first + 2;
2436         const char *t2 = NULL;
2437 
2438         if (first[1] == 't') {
2439                 while (t1 != last && t1[0] != '_' && is_digit(t1[0]))

2440                         t1++;
2441 
2442                 if (t1[0] != '_')
2443                         return (first);
2444 
2445                 if (t1 == first + 2)
2446                         nadd_l(db, "", 0);
2447                 else
2448                         nadd_l(db, first + 2, (size_t)(t1 - first - 2));
2449 
2450                 nfmt(db, "'unnamed{0}'", NULL);
2451                 return (t1 + 1);
2452         }
2453 
2454         size_t n = nlen(db);
2455 
2456         if (first[2] != 'v') {
2457                 do {
2458                         t2 = parse_type(t1, last, db);
2459                         if (t1 == t2)


2462                 } while (t1 != last && t1[0] != 'E');
2463 
2464                 if (t1 == last || NAMT(db, n) < 1)
2465                         return (first);
2466 
2467                 if (NAMT(db, n) < 1)
2468                         return (first);
2469         } else {
2470                 t1++;
2471                 if (t1[0] != 'E')
2472                         return (first);
2473         }
2474 
2475         njoin(db, NAMT(db, n), ", ");
2476 
2477         /* E */
2478         t1++;
2479 
2480         t2 = t1;
2481         while (t2 != last && t2[0] != '_') {
2482                 if (!is_digit(*t2++))
2483                         return (first);
2484         }
2485 
2486         if (t2[0] != '_')
2487                 return (first);
2488 
2489         if (t2 - t1 > 0)
2490                 nadd_l(db, t1, (size_t)(t2 - t1));
2491         else
2492                 nadd_l(db, "", 0);
2493 
2494         nfmt(db, "'lambda{0}'({1})", NULL);
2495 
2496         /* _ */
2497         return (t2 + 1);
2498 }
2499 
2500 static struct {
2501         const char *alias;
2502         const char *fullname;


2555          */
2556         unsigned c = 0;
2557 
2558         if (end[-1] == '>') {
2559                 for (; end > start; end--) {
2560                         switch (end[-1]) {
2561                         case '<':
2562                                 if (--c == 0) {
2563                                         end--;
2564                                         goto out;
2565                                 }
2566                                 break;
2567                         case '>':
2568                                 c++;
2569                                 break;
2570                         }
2571                 }
2572         }
2573 
2574 out:
2575         ASSERT3P(end, >=, start);
2576 
2577         if (end - start < 2) {
2578                 nadd_l(db, "", 0);
2579                 return;
2580         }
2581 
2582         for (start = end - 1; start > s->str_s; start--) {
2583                 if (start[0] == ':') {
2584                         start++;
2585                         break;
2586                 }
2587         }
2588 
2589         ASSERT3P(end, >=, start);
2590 
2591         nadd_l(db, start, (size_t)(end - start));
2592 }
2593 
2594 /*
2595  * <ctor-dtor-name> ::= C1    # complete object constructor
2596  *                  ::= C2    # base object constructor
2597  *                  ::= C3    # complete object allocating constructor
2598  *   extension      ::= C5    # ?
2599  *                  ::= D0    # deleting destructor
2600  *                  ::= D1    # complete object destructor
2601  *                  ::= D2    # base object destructor
2602  *   extension      ::= D5    # ?
2603  */
2604 static const char *
2605 parse_ctor_dtor_name(const char *first, const char *last, cpp_db_t *db)
2606 {
2607         ASSERT3P(first, <=, last);
2608 
2609         if (last - first < 2 || nempty(db) || str_length(TOP_L(db)) == 0)
2610                 return (first);
2611 
2612         switch (first[0]) {
2613         case 'C':
2614                 switch (first[1]) {
2615                 case '1':
2616                 case '2':
2617                 case '3':
2618                 case '5':
2619                         basename(db);
2620                         break;
2621                 default:
2622                         return (first);
2623                 }
2624                 break;
2625         case 'D':
2626                 switch (first[1]) {
2627                 case '0':


2630                 case '5':
2631                         basename(db);
2632                         str_insert(TOP_L(db), 0, "~", 1);
2633                         break;
2634                 default:
2635                         return (first);
2636                 }
2637                 break;
2638         default:
2639                 return (first);
2640         }
2641 
2642         db->cpp_parsed_ctor_dtor_cv = B_TRUE;
2643         return (first + 2);
2644 }
2645 
2646 static const char *
2647 parse_integer_literal(const char *first, const char *last, const char *fmt,
2648     cpp_db_t *db)
2649 {
2650         ASSERT3P(first, <=, last);
2651 
2652         const char *t = parse_number(first, last);
2653         const char *start = first;
2654 
2655         if (t == first || t == last || t[0] != 'E')
2656                 return (first);
2657 
2658         if (first[0] == 'n')
2659                 start++;
2660 
2661         nadd_l(db, start, (size_t)(t - start));
2662         if (start != first)
2663                 nfmt(db, "-{0}", NULL);
2664 
2665         nfmt(db, fmt, NULL);
2666         return (t + 1);
2667 }
2668 
2669 static struct float_data_s {
2670         const char *spec;
2671         size_t mangled_size;
2672         size_t max_demangled_size;
2673         char type;
2674 } float_info[] = {
2675         { "%af", 8, 24, 'f' },          /* float */
2676         { "%a", 16, 32, 'd' },          /* double */
2677         { "%LaL", 20, 40, 'e' }         /* long double */
2678 };
2679 
2680 static const char *
2681 parse_floating_literal(const char *first, const char *last, cpp_db_t *db)
2682 {
2683         ASSERT3P(first, <=, last);
2684         ASSERT(first[0] == 'f' || first[0] == 'd' || first[0] == 'e');
2685 
2686         const struct float_data_s *fd = NULL;
2687 
2688         for (size_t i = 0; i < ARRAY_SIZE(float_info); i++) {
2689                 if (float_info[i].type != first[0])
2690                         continue;
2691 
2692                 fd = &float_info[i];
2693                 break;
2694         }
2695 
2696         if (fd == NULL || (size_t)(last - first) < fd->mangled_size)
2697                 return (first);
2698 
2699         union {
2700                 union {
2701                         float v;
2702                         char buf[sizeof (float)];
2703                 } f;
2704                 union {


2715         char *e = NULL;
2716 
2717         switch (first[0]) {
2718         case 'f':
2719                 e = conv.f.buf;
2720                 break;
2721         case 'd':
2722                 e = conv.d.buf;
2723                 break;
2724         case 'e':
2725                 e = conv.ld.buf;
2726                 break;
2727         }
2728         last = first + fd->mangled_size + 1;
2729 
2730 #if defined(_BIG_ENDIAN)
2731         for (t = first + 1; t != last; t++, e++) {
2732                 if (!is_xdigit(t[0]))
2733                         return (first);
2734 
2735                 unsigned d1 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
2736                 t++;
2737                 unsigned d0 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
2738 
2739                 *e = (d1 << 4) + d0;
2740         }
2741 #elif defined(_LITTLE_ENDIAN)
2742         for (t = last - 1; t > first; t--, e++) {
2743                 if (!is_xdigit(t[0]))
2744                         return (first);
2745 
2746                 unsigned d0 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
2747                 t--;
2748                 unsigned d1 = is_digit(t[0]) ? t[0] - '0' : t[0] - 'a' + 10;
2749 
2750                 *e = (d1 << 4) + d0;
2751         }
2752         t = last;
2753 #else
2754 #error One of _BIG_ENDIAN or _LITTLE_ENDIAN must be defined
2755 #endif
2756 
2757         if (t[0] != 'E')
2758                 return (first);
2759 
2760         str_t num = { 0 };
2761         str_init(&num, db->cpp_ops);
2762 
2763         num.str_size = fd->max_demangled_size + 1;
2764         num.str_s = zalloc(db->cpp_ops, num.str_size);
2765         CK(num.str_s != NULL);
2766 
2767         int n = 0;
2768 


2809 } int_lits[] = {
2810         { 'a', "(signed char){0}" },
2811         { 'c', "(char){0}" },
2812         { 'h', "(unsigned char){0}" },
2813         { 'i', "{0}" },
2814         { 'j', "{0}u" },
2815         { 'l', "{0}l" },
2816         { 'm', "{0}ul" },
2817         { 'n', "(__int128){0}" },
2818         { 'o', "(unsigned __int128){0}" },
2819         { 's', "(short){0}" },
2820         { 't', "(unsigned short){0}" },
2821         { 'w', "(wchar_t){0}" },
2822         { 'x', "{0}ll" },
2823         { 'y', "{0}ull" }
2824 };
2825 
2826 static const char *
2827 parse_expr_primary(const char *first, const char *last, cpp_db_t *db)
2828 {
2829         ASSERT3P(first, <=, last);
2830 
2831         if (last - first < 4 || first[0] != 'L')
2832                 return (first);
2833 
2834         const char *t = NULL;
2835 
2836         for (size_t i = 0; i < ARRAY_SIZE(int_lits); i++) {
2837                 if (first[1] == int_lits[i].c) {
2838                         t = parse_integer_literal(first + 2, last,
2839                             int_lits[i].fmt, db);
2840                         return ((t == first + 2) ? first : t);
2841                 }
2842         }
2843 
2844         switch (first[1]) {
2845         case 'b':
2846                 if (first[3] != 'E')
2847                         return (first);
2848 
2849                 switch (first[2]) {


2873                 return (first);
2874         case '_':
2875                 if (first[2] != 'Z')
2876                         return (first);
2877 
2878                 t = parse_encoding(first + 3, last, db);
2879                 if (t == first + 3 || t == last || t[0] != 'E')
2880                         return (first);
2881 
2882                 /* skip E */
2883                 return (t + 1);
2884         default:
2885                 t = parse_type(first + 1, last, db);
2886                 if (t == first + 1 || t == last)
2887                         return (first);
2888 
2889                 if (t[0] == 'E')
2890                         return (t + 1);
2891 
2892                 const char *n;
2893                 for (n = t; n != last && is_digit(n[0]); n++)
2894                         ;
2895                 if (n == last || nempty(db) || n[0] != 'E')
2896                         return (first);
2897                 if (n == t)
2898                         return (t);
2899 
2900                 nadd_l(db, t, (size_t)(n - t));
2901                 nfmt(db, "({1}){0}", NULL);
2902 
2903                 return (n + 1);
2904         }
2905 }
2906 
2907 /*
2908  *   <operator-name>
2909  *                   ::= aa    # &&
2910  *                   ::= ad    # & (unary)
2911  *                   ::= an    # &
2912  *                   ::= aN    # &=
2913  *                   ::= aS    # =


2996         { "nw", "operator new" },
2997         { "oo", "operator||" },
2998         { "or", "operator|" },
2999         { "oR", "operator|=" },
3000         { "pm", "operator->*" },
3001         { "pl", "operator+" },
3002         { "pL", "operator+=" },
3003         { "pp", "operator++" },
3004         { "ps", "operator+" },
3005         { "pt", "operator->" },
3006         { "qu", "operator?" },
3007         { "rm", "operator%" },
3008         { "rM", "operator%=" },
3009         { "rs", "operator>>" },
3010         { "rS", "operator>>=" }
3011 };
3012 
3013 static const char *
3014 parse_operator_name(const char *first, const char *last, cpp_db_t *db)
3015 {
3016         ASSERT3P(first, <=, last);
3017 
3018         if (last - first < 2)
3019                 return (first);
3020 
3021         for (size_t i = 0; i < ARRAY_SIZE(op_tbl); i++) {
3022                 if (strncmp(first, op_tbl[i].code, 2) != 0)
3023                         continue;
3024 
3025                 nadd_l(db, op_tbl[i].op, 0);
3026                 return (first + 2);
3027         }
3028 
3029         const char *t = NULL;
3030 
3031         if (first[0] == 'l' && first[1] == 'i') {
3032                 t = parse_source_name(first + 2, last, db);
3033                 if (t == first + 2 || nempty(db))
3034                         return (first);
3035 
3036                 nfmt(db, "operator\"\" {0}", NULL);
3037                 return (t);
3038         }
3039 
3040         if (first[0] == 'v') {
3041                 if (!is_digit(first[1]))
3042                         return (first);
3043 
3044                 t = parse_source_name(first + 2, last, db);
3045                 if (t == first + 2)
3046                         return (first);
3047 
3048                 nfmt(db, "operator {0}", NULL);
3049                 return (t);
3050         }
3051 
3052         if (first[0] != 'c' && first[1] != 'v')
3053                 return (first);
3054 
3055         boolean_t try_to_parse_template_args =
3056             db->cpp_try_to_parse_template_args;
3057 
3058         db->cpp_try_to_parse_template_args = B_FALSE;
3059         t = parse_type(first + 2, last, db);
3060         db->cpp_try_to_parse_template_args = try_to_parse_template_args;
3061 


3094         { 'x', "long long" },
3095         { 'y', "unsigned long long" },
3096         { 'z', "..." }
3097 };
3098 
3099 static struct type_tbl_s type_tbl2[] = {
3100         { 'a', "auto" },
3101         { 'c', "decltype(auto)" },
3102         { 'd', "decimal64" },
3103         { 'e', "decimal128" },
3104         { 'f', "decimal32" },
3105         { 'h', "decimal16" },
3106         { 'i', "char32_t" },
3107         { 'n', "std::nullptr_t" },
3108         { 's', "char16_t" }
3109 };
3110 
3111 static const char *
3112 parse_builtin_type(const char *first, const char *last, cpp_db_t *db)
3113 {
3114         ASSERT3P(first, <=, last);
3115 
3116         if (first == last)
3117                 return (first);
3118 
3119         size_t i;
3120 
3121         for (i = 0; i < ARRAY_SIZE(type_tbl1); i++) {
3122                 if (first[0] == type_tbl1[i].code) {
3123                         nadd_l(db, type_tbl1[i].name, 0);
3124                         return (first + 1);
3125                 }
3126         }
3127 
3128         if (first[0] == 'D') {
3129                 if (first + 1 == last)
3130                         return (first);
3131                 for (i = 0; i < ARRAY_SIZE(type_tbl2); i++) {
3132                         if (first[1] == type_tbl2[i].code) {
3133                                 nadd_l(db, type_tbl2[i].name, 0);
3134                                 return (first + 2);
3135                         }
3136                 }
3137         }
3138 
3139         if (first[0] == 'u') {
3140                 const char *t = parse_source_name(first + 1, last, db);
3141                 if (t == first + 1)
3142                         return (first);
3143                 return (t);
3144         }
3145 
3146         return (first);
3147 }
3148 
3149 static const char *
3150 parse_base36(const char *first, const char *last, size_t *val)
3151 {
3152         ASSERT3P(first, <=, last);
3153 
3154         const char *t;
3155 
3156         for (t = first, *val = 0; t != last; t++) {
3157                 if (!is_digit(t[0]) && !is_upper(t[0]))
3158                         return (t);
3159 
3160                 *val *= 36;
3161 
3162                 if (is_digit(t[0]))
3163                         *val += t[0] - '0';
3164                 else
3165                         *val += t[0] - 'A' + 10;
3166         }
3167         return (t);
3168 }
3169 
3170 static struct type_tbl_s sub_tbl[] = {
3171         { 'a', "std::allocator" },
3172         { 'b', "std::basic_string" },
3173         { 's', "std::string" },
3174         { 'i', "std::istream" },
3175         { 'o', "std::ostream" },
3176         { 'd', "std::iostream" }
3177 };
3178 
3179 static const char *
3180 parse_substitution(const char *first, const char *last, cpp_db_t *db)
3181 {
3182         ASSERT3P(first, <=, last);
3183 
3184         if (first == last || last - first < 2)
3185                 return (first);
3186 
3187         if (first[0] != 'S')
3188                 return (first);
3189 
3190         for (size_t i = 0; i < ARRAY_SIZE(sub_tbl); i++) {
3191                 if (first[1] == sub_tbl[i].code) {
3192                         nadd_l(db, sub_tbl[i].name, 0);
3193                         return (first + 2);
3194                 }
3195         }
3196 
3197         const char *t = first + 1;
3198         size_t n = 0;
3199 
3200         if (t[0] != '_') {
3201                 t = parse_base36(first + 1, last, &n);
3202                 if (t == first + 1 || t[0] != '_')
3203                         return (first);
3204 
3205                 /*
3206                  * S_ == substitution 0,
3207                  * S0_ == substituion 1,
3208                  * ...
3209                  */
3210                 n++;
3211         }
3212 
3213         if (n >= sub_len(&db->cpp_subs))
3214                 return (first);
3215 
3216         sub(db, n);
3217 
3218         /* skip _ */
3219         ASSERT3U(t[0], ==, '_');
3220 
3221         return (t + 1);
3222 }
3223 
3224 static const char *
3225 parse_source_name(const char *first, const char *last, cpp_db_t *db)
3226 {
3227         ASSERT3P(first, <=, last);
3228 
3229         if (first == last)
3230                 return (first);
3231 
3232         const char *t = NULL;
3233         size_t n = 0;
3234 
3235         for (t = first; t != last && is_digit(t[0]); t++) {
3236                 /* make sure we don't overflow */
3237                 size_t nn = n * 10;
3238                 if (nn < n)
3239                         return (first);
3240 
3241                 nn += t[0] - '0';
3242                 if (nn < n)
3243                         return (first);
3244 
3245                 n = nn;
3246         }
3247 
3248         if (n == 0 || t == last || t + n > last ||
3249             (uintptr_t)t + n < (uintptr_t)t)
3250                 return (first);
3251 
3252         if (strncmp(t, "_GLOBAL__N", 10) == 0)
3253                 nadd_l(db, "(anonymous namespace)", 0);
3254         else
3255                 nadd_l(db, t, n);
3256 
3257         return (t + n);
3258 }
3259 
3260 /*
3261  * extension:
3262  * <vector-type>           ::= Dv <positive dimension number> _
3263  *                                    <extended element type>
3264  *                         ::= Dv [<dimension expression>] _ <element type>
3265  * <extended element type> ::= <element type>
3266  *                         ::= p # AltiVec vector pixel
3267  */
3268 static const char *
3269 parse_vector_type(const char *first, const char *last, cpp_db_t *db)
3270 {
3271         ASSERT3P(first, <=, last);
3272 
3273         if (last - first < 3)
3274                 return (first);
3275 
3276         ASSERT3U(first[0], ==, 'D');
3277         ASSERT3U(first[1], ==, 'v');
3278 
3279         const char *t = first + 2;
3280         const char *t1 = NULL;
3281 
3282         if (is_digit(first[2]) && first[2] != '0') {
3283                 t1 = parse_number(t, last);
3284                 if (t1 == last || t1 + 1 == last || t1[0] != '_')
3285                         return (first);
3286 
3287                 nadd_l(db, t, (size_t)(t1 - t));
3288 
3289                 /* skip _ */
3290                 t = t1 + 1;
3291 
3292                 if (t[0] != 'p') {
3293                         t1 = parse_type(t, last, db);
3294                         if (t1 == t)
3295                                 return (first);
3296 
3297                         nfmt(db, "{0} vector[{1}]", NULL);
3298                         return (t1);
3299                 }
3300                 nfmt(db, "{0} pixel vector[{1}]", NULL);
3301                 return (t1);
3302         }
3303 


3312                 nadd_l(db, "", 0);
3313         }
3314 
3315         t1 = parse_type(t, last, db);
3316         if (t == t1)
3317                 return (first);
3318 
3319         nfmt(db, "{1:L} vector[{0}]", "{1:R}");
3320         return (t1);
3321 }
3322 
3323 /* BEGIN CSTYLED */
3324 /*
3325  * <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
3326  *             ::= DT <expression> E  # decltype of an expression (C++0x)
3327  */
3328 /* END CSTYLED */
3329 static const char *
3330 parse_decltype(const char *first, const char *last, cpp_db_t *db)
3331 {
3332         ASSERT3P(first, <=, last);
3333 
3334         if (last - first < 4)
3335                 return (first);
3336 
3337         ASSERT3U(first[0], ==, 'D');
3338 
3339         if (first[1] != 't' && first[1] != 'T')
3340                 return (first);
3341 
3342         size_t n = nlen(db);
3343         const char *t = parse_expression(first + 2, last, db);
3344         if (NAMT(db, n) != 1 || t == first + 2 || t == last || t[0] != 'E')
3345                 return (first);
3346 
3347         nfmt(db, "decltype({0})", NULL);
3348 
3349         /* skip E */
3350         return (t + 1);
3351 }
3352 
3353 /*
3354  * <array-type> ::= A <positive dimension number> _ <element type>
3355  *              ::= A [<dimension expression>] _ <element type>
3356  */
3357 static const char *
3358 parse_array_type(const char *first, const char *last, cpp_db_t *db)
3359 {
3360         ASSERT3P(first, <=, last);
3361         ASSERT3U(first[0], ==, 'A');
3362 
3363         if (last - first < 3)
3364                 return (first);
3365 
3366         const char *t = first + 1;
3367         const char *t1 = NULL;
3368         size_t n = nlen(db);
3369 
3370         if (t[0] != '_') {
3371                 if (is_digit(t[0]) && t[0] != '0') {
3372                         t1 = parse_number(t, last);
3373                         if (t1 == last)
3374                                 return (first);
3375 
3376                         nadd_l(db, t, (size_t)(t1 - t));
3377                 } else {
3378                         t1 = parse_expression(t, last, db);
3379                         if (t1 == last || t == t1)
3380                                 return (first);
3381                 }
3382 
3383                 if (t1[0] != '_')
3384                         return (first);
3385 
3386                 t = t1;
3387         } else {
3388                 nadd_l(db, "", 0);
3389         }
3390 
3391         ASSERT3U(t[0], ==, '_');
3392 
3393         t1 = parse_type(t + 1, last, db);
3394         if (t1 == t + 1 || NAMT(db, n) != 2)
3395                 return (first);
3396 
3397         /*
3398          * if we have  " [xxx]" already, want new result to be
3399          * " [yyy][xxx]"
3400          */
3401         str_t *r = &name_top(&db->cpp_name)->strp_r;
3402         if (r->str_len > 1 && r->str_s[0] == ' ' && r->str_s[1] == '[')
3403                 str_erase(r, 0, 1);
3404 
3405         nfmt(db, "{0:L}", " [{1}]{0:R}");
3406         return (t1);
3407 }
3408 
3409 /* <pointer-to-member-type> ::= M <class type> <member type> */
3410 static const char *
3411 parse_pointer_to_member_type(const char *first, const char *last, cpp_db_t *db)
3412 {
3413         ASSERT3P(first, <=, last);
3414 
3415         if (last - first < 3)
3416                 return (first);
3417 
3418         ASSERT3U(first[0], ==, 'M');
3419 
3420         const char *t1 = first + 1;
3421         const char *t2 = NULL;
3422         size_t n = nlen(db);
3423 
3424         t2 = parse_type(t1, last, db);
3425         if (t1 == t2)
3426                 return (first);
3427 
3428         t1 = t2;
3429         t2 = parse_type(t1, last, db);
3430         if (t1 == t2)
3431                 return (first);
3432 
3433         if (NAMT(db, n) != 2)
3434                 return (first);
3435 
3436         str_pair_t *func = name_top(&db->cpp_name);
3437 
3438         if (str_length(&func->strp_r) > 0 && func->strp_r.str_s[0] == '(')


3442 
3443         return (t2);
3444 }
3445 
3446 /* BEGIN CSTYLED */
3447 /*
3448  * <unresolved-name>
3449  *  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3450  *                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3451  *                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3452  *                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3453  *                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3454  *  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3455  *                                                                       # T::N::x /decltype(p)::N::x
3456  *  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3457  */
3458 /* END CSTYLED */
3459 static const char *
3460 parse_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3461 {
3462         ASSERT3P(first, <=, last);
3463 
3464         if (last - first < 2)
3465                 return (first);
3466 
3467         const char *t = first;
3468         const char *t2 = NULL;
3469         boolean_t global = B_FALSE;
3470         size_t n;
3471 
3472         if (t[0] == 'g' && t[1] == 's') {
3473                 global = B_TRUE;
3474                 t += 2;
3475         }
3476         if (t == last)
3477                 return (first);
3478 
3479         t2 = parse_base_unresolved_name(t, last, db);
3480         if (t != t2) {
3481                 if (global) {
3482                         if (nempty(db))


3490         if (t[0] != 's' || t[1] != 'r' || last - t < 2)
3491                 return (first);
3492 
3493         n = nlen(db);
3494         if (t[2] == 'N') {
3495                 t += 3;
3496                 t2 = parse_unresolved_type(t, last, db);
3497                 if (t2 == t || t2 == last)
3498                         return (first);
3499                 t = t2;
3500 
3501                 t2 = parse_template_args(t, last, db);
3502                 if (t2 != t) {
3503                         if (NAMT(db, n) < 2 || t2 == last)
3504                                 return (first);
3505 
3506                         nfmt(db, "{1:L}{0}", "{1:R}");
3507                         t = t2;
3508                 }
3509 
3510                 ASSERT3U(NAMT(db, n), ==, 1);
3511 
3512                 while (t[0] != 'E') {
3513                         size_t nn = nlen(db);
3514                         t2 = parse_unresolved_qualifier_level(t, last, db);
3515                         if (t == t2 || t == last || NAMT(db, nn) != 1)
3516                                 return (first);
3517 
3518                         t = t2;
3519                 }
3520 
3521                 /* skip E */
3522                 t++;
3523 
3524                 t2 = parse_base_unresolved_name(t, last, db);
3525                 if (t == t2 || NAMT(db, n) < 2)
3526                         return (first);
3527 
3528                 njoin(db, NAMT(db, n), "::");
3529                 return (t2);
3530         }


3562 
3563                 t = t2;
3564         }
3565 
3566         /* skip E */
3567         t++;
3568 
3569         t2 = parse_base_unresolved_name(t, last, db);
3570         if (t == t2 || nlen(db) < 2)
3571                 return (first);
3572 
3573         njoin(db, NAMT(db, n), "::");
3574         return (t2);
3575 }
3576 
3577 /* <unresolved-qualifier-level> ::= <simple-id> */
3578 static const char *
3579 parse_unresolved_qualifier_level(const char *first, const char *last,
3580     cpp_db_t *db)
3581 {
3582         ASSERT3P(first, <=, last);
3583         return (parse_simple_id(first, last, db));
3584 }
3585 
3586 /* BEGIN CSTYLED */
3587 /*
3588  * <base-unresolved-name> ::= <simple-id>                                # unresolved name
3589  *          extension     ::= <operator-name>                            # unresolved operator-function-id
3590  *          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3591  *                        ::= on <operator-name>                         # unresolved operator-function-id
3592  *                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3593  *                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3594  *                                                                       # e.g. ~X or ~X<N-1>
3595  */
3596 /* END CSTYLED */
3597 static const char *
3598 parse_base_unresolved_name(const char *first, const char *last, cpp_db_t *db)
3599 {
3600         ASSERT3P(first, <=, last);
3601 
3602         if (last - first < 2)
3603                 return (first);
3604 
3605         const char *t = NULL;
3606         const char *t1 = NULL;
3607 
3608         if ((first[0] != 'o' && first[0] != 'd') || first[1] != 'n') {
3609                 t = parse_simple_id(first, last, db);
3610                 if (t != first)
3611                         return (t);
3612 
3613                 t = parse_operator_name(first, last, db);
3614                 if (t == first)
3615                         return (first);
3616 
3617                 t1 = parse_template_args(t, last, db);
3618                 if (t1 != t) {
3619                         if (nlen(db) < 2)
3620                                 return (first);


3629                 return ((t != first + 2) ? t : first);
3630         }
3631 
3632         t = parse_operator_name(first + 2, last, db);
3633         if (t == first + 2)
3634                 return (first);
3635 
3636         t1 = parse_template_args(t, last, db);
3637         if (t1 != t)
3638                 nfmt(db, "{1:L}{0}", "{1:R}");
3639         return (t1);
3640 }
3641 
3642 /*
3643  * <destructor-name> ::= <unresolved-type>  # e.g., ~T or ~decltype(f())
3644  *                   ::= <simple-id>              # e.g., ~A<2*N>
3645  */
3646 static const char *
3647 parse_destructor_name(const char *first, const char *last, cpp_db_t *db)
3648 {
3649         ASSERT3P(first, <=, last);
3650 
3651         if (first == last)
3652                 return (first);
3653 
3654         const char *t = parse_unresolved_type(first, last, db);
3655 
3656         if (t == first)
3657                 t = parse_simple_id(first, last, db);
3658 
3659         if (t == first)
3660                 return (first);
3661 
3662         nfmt(db, "~{0:L}", "{0:R}");
3663         return (t);
3664 }
3665 
3666 /*
3667  *  <ref-qualifier> ::= R                   # & ref-qualifier
3668  *  <ref-qualifier> ::= O                   # && ref-qualifier
3669  *
3670  * <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
3671  */
3672 static const char *
3673 parse_function_type(const char *first, const char *last, cpp_db_t *db)
3674 {
3675         ASSERT3P(first, <=, last);
3676 
3677         if (last - first < 2)
3678                 return (first);
3679 
3680         ASSERT3U(first[0], ==, 'F');
3681 
3682         const char *t = first + 1;
3683 
3684         /* extern "C" */
3685         if (t[0] == 'Y')
3686                 t++;
3687 
3688         const char *t1 = parse_type(t, last, db);
3689         if (t1 == t)
3690                 return (first);
3691 
3692         size_t n = nlen(db);
3693         int ref_qual = 0;
3694 
3695         t = t1;
3696 
3697         while (t != last && t[0] != 'E') {
3698                 if (t[0] == 'v') {
3699                         t++;
3700                         continue;


3731                 nfmt(db, "{0} &", NULL);
3732                 break;
3733         case 2:
3734                 nfmt(db, "{0} &&", NULL);
3735                 break;
3736         }
3737 
3738         nfmt(db, "{1:L} ", "{0}{1:R}");
3739 
3740         /* skip E */
3741         return (t + 1);
3742 }
3743 
3744 /*
3745  * <template-param> ::= T_    # first template parameter
3746  *                  ::= T <parameter-2 non-negative number> _
3747  */
3748 static const char *
3749 parse_template_param(const char *first, const char *last, cpp_db_t *db)
3750 {
3751         ASSERT3P(first, <=, last);
3752 
3753         if (last - first < 2 || first[0] != 'T')
3754                 return (first);
3755 
3756         const char *t = first + 1;
3757         size_t idx = 0;
3758 
3759         while (t != last && t[0] != '_') {
3760                 if (!is_digit(t[0]))
3761                         return (first);
3762 
3763                 idx *= 10;
3764                 idx += t[0] - '0';
3765                 t++;
3766         }
3767 
3768         if (t == last)
3769                 return (first);
3770 
3771         ASSERT3U(t[0], ==, '_');
3772 
3773         /*
3774          * T_ -> idx 0
3775          * T0 -> idx 1
3776          * T1 -> idx 2
3777          * ...
3778          */
3779         if (first[1] != '_')
3780                 idx++;
3781 
3782         /* skip _ */
3783         t++;
3784 
3785         if (tempty(db))
3786                 return (first);
3787 
3788         if (idx >= ttlen(db)) {
3789                 nadd_l(db, first, (size_t)(t - first));
3790                 db->cpp_fix_forward_references = B_TRUE;
3791                 return (t);
3792         }
3793 
3794         tsub(db, idx);
3795         return (t);
3796 }
3797 
3798 /*
3799  * <template-args> ::= I <template-arg>* E
3800  *     extension, the abi says <template-arg>+
3801  */
3802 static const char *
3803 parse_template_args(const char *first, const char *last, cpp_db_t *db)
3804 {
3805         ASSERT3P(first, <=, last);
3806 
3807         if (last - first < 2 || first[0] != 'I')
3808                 return (first);
3809 
3810         if (db->cpp_tag_templates)
3811                 sub_clear(templ_top(&db->cpp_templ));
3812 
3813         const char *t = first + 1;
3814         size_t n = nlen(db);
3815 
3816         while (t[0] != 'E') {
3817                 if (db->cpp_tag_templates)
3818                         tpush(db);
3819 
3820                 size_t n1 = nlen(db);
3821                 const char *t1 = parse_template_arg(t, last, db);
3822 
3823                 if (db->cpp_tag_templates)
3824                         tpop(db);
3825 
3826                 if (t1 == t || t == last)
3827                         return (first);
3828 
3829                 if (db->cpp_tag_templates)
3830                         tsave(db, NAMT(db, n1));
3831 
3832                 t = t1;
3833         }
3834 
3835         /*
3836          * ugly, but if the last thing pushed was an empty string,
3837          * get rid of it so we dont get "<..., >"
3838          */
3839         if (NAMT(db, n) > 1 &&
3840             str_pair_len(name_top(&db->cpp_name)) == 0)
3841                 (void) name_pop(&db->cpp_name, NULL);
3842 
3843         njoin(db, NAMT(db, n), ", ");
3844 
3845         ASSERT3U(nlen(db), >, 0);
3846 
3847         /* make sure we don't bitshift ourselves into oblivion */
3848         str_t *top = TOP_L(db);
3849         if (str_length(top) > 0 &&
3850             top->str_s[top->str_len - 1] == '>')
3851                 nfmt(db, "<{0} >", NULL);
3852         else
3853                 nfmt(db, "<{0}>", NULL);
3854 
3855         /* skip E */
3856         return (t + 1);
3857 }
3858 
3859 /*
3860  * <discriminator> := _ <non-negative number>      # when number < 10
3861  *                 := __ <non-negative number> _   # when number >= 10
3862  *  extension      := decimal-digit+               # at the end of string
3863  */
3864 static const char *
3865 parse_discriminator(const char *first, const char *last)
3866 {
3867         ASSERT3P(first, <=, last);
3868 
3869         const char *t = NULL;
3870 
3871         if (first == last)
3872                 return (first);
3873 
3874         if (is_digit(first[0])) {
3875                 for (t = first; t != last && is_digit(t[0]); t++)
3876                         ;
3877 
3878                 /* not at the end of the string */
3879                 if (t != last)
3880                         return (first);
3881 
3882                 return (t);
3883         } else if (first[0] != '_' || first + 1 == last) {
3884                 return (first);
3885         }
3886 
3887         t = first + 1;
3888         if (is_digit(t[0]))
3889                 return (t + 1);
3890 
3891         if (t[0] != '_' || t + 1 == last)
3892                 return (first);
3893 
3894         for (t++; t != last && is_digit(t[0]); t++)
3895                 ;
3896         if (t == last || t[0] != '_')
3897                 return (first);
3898 
3899         return (t);
3900 }
3901 
3902 /* <CV-qualifiers> ::= [r] [V] [K] */
3903 const char *
3904 parse_cv_qualifiers(const char *first, const char *last, unsigned *cv)
3905 {
3906         ASSERT3P(first, <=, last);
3907 
3908         if (first == last)
3909                 return (first);
3910 
3911         *cv = 0;
3912         if (first[0] == 'r') {
3913                 *cv |= CPP_QUAL_RESTRICT;
3914                 first++;
3915         }
3916         if (first != last && first[0] == 'V') {
3917                 *cv |= CPP_QUAL_VOLATILE;
3918                 first++;
3919         }
3920         if (first != last && first[0] == 'K') {
3921                 *cv |= CPP_QUAL_CONST;
3922                 first++;
3923         }
3924 
3925         return (first);
3926 }
3927 
3928 /*
3929  * <number> ::= [n] <non-negative decimal integer>
3930  */
3931 static const char *
3932 parse_number(const char *first, const char *last)
3933 {
3934         ASSERT3P(first, <=, last);
3935 
3936         const char *t = first;
3937 
3938         if (first == last || (first[0] != 'n' && !is_digit(first[0])))
3939                 return (first);
3940 
3941         if (t[0] == 'n')
3942                 t++;
3943 
3944         if (t[0] == '0')
3945                 return (t + 1);
3946 
3947         while (is_digit(t[0]))
3948                 t++;
3949 
3950         return (t);
3951 }
3952 
3953 /*
3954  * we only ever use ASCII versions of these


3955  */
3956 static inline boolean_t
3957 is_digit(int c)
3958 {
3959         if (c < '0' || c > '9')
3960                 return (B_FALSE);
3961         return (B_TRUE);
3962 }
3963 
3964 static inline boolean_t
3965 is_upper(int c)
3966 {
3967         if (c < 'A' || c > 'Z')
3968                 return (B_FALSE);
3969         return (B_TRUE);
3970 }
3971 
3972 static inline boolean_t
3973 is_xdigit(int c)
3974 {
3975         if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
3976                 return (B_TRUE);
3977         return (B_FALSE);
3978 }
3979 
3980 static boolean_t
3981 nempty(cpp_db_t *db)
3982 {
3983         return (name_empty(&db->cpp_name));
3984 }
3985 
3986 static size_t
3987 nlen(cpp_db_t *db)
3988 {
3989         return (name_len(&db->cpp_name));
3990 }
3991 
3992 static void


4040 }
4041 
4042 static void
4043 tpush(cpp_db_t *db)
4044 {
4045         CK(templ_push(&db->cpp_templ));
4046 }
4047 
4048 static void
4049 tpop(cpp_db_t *db)
4050 {
4051         templ_pop(&db->cpp_templ);
4052 }
4053 
4054 static void
4055 tsave(cpp_db_t *db, size_t amt)
4056 {
4057         CK(templ_save(&db->cpp_name, amt, &db->cpp_templ));
4058 }
4059 
4060 static void
4061 db_init(cpp_db_t *db, sysdem_ops_t *ops)
4062 {
4063         (void) memset(db, 0, sizeof (*db));
4064         db->cpp_ops = ops;
4065         name_init(&db->cpp_name, ops);
4066         sub_init(&db->cpp_subs, ops);
4067         templ_init(&db->cpp_templ, ops);
4068         db->cpp_tag_templates = B_TRUE;
4069         db->cpp_try_to_parse_template_args = B_TRUE;
4070         tpush(db);


4071 }
4072 
4073 static void
4074 db_fini(cpp_db_t *db)
4075 {
4076         name_fini(&db->cpp_name);
4077         sub_fini(&db->cpp_subs);
4078         templ_fini(&db->cpp_templ);

4079         (void) memset(db, 0, sizeof (*db));
4080 }
4081 
4082 static void
4083 print_sp(const str_pair_t *sp, FILE *out)
4084 {
4085         (void) fprintf(out, "{%.*s#%.*s}",
4086             (int)sp->strp_l.str_len, sp->strp_l.str_s,
4087             (int)sp->strp_r.str_len, sp->strp_r.str_s);
4088 }
4089 
4090 static void
4091 print_name(const name_t *n, FILE *out)
4092 {
4093         const str_pair_t *sp = name_top((name_t *)n);
4094         size_t i;
4095 
4096         (void) fprintf(out, "Name:\n");
4097 
4098         if (name_len(n) == 0)
4099                 return;
4100 
4101         for (i = 0; i < n->nm_len; i++, sp--) {
4102                 (void) fprintf(out, "  [%02zu] ", i);
4103                 print_sp(sp, out);
4104                 (void) fputc('\n', out);
4105         }
4106 
4107         (void) fputc('\n', out);
4108 }
4109 
4110 
4111 static char *
4112 base36(char *buf, size_t val)
4113 {
4114         char tmp[16] = { 0 };
4115         char *p = tmp;
4116 
4117         if (val == 0) {
4118                 buf[0] = '0';
4119                 buf[1] = '\0';
4120                 return (buf);
4121         }
4122 
4123         while (val > 0) {
4124                 size_t r = val % 36;
4125 
4126                 if (r < 10)
4127                         *p++ = r + '0';
4128                 else
4129                         *p++ = r - 10 + 'A';
4130 


   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 *);


 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) {


 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);


 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));


 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:


 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 


 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++;


 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)


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));


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')


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


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);


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 


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 


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 


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)


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;


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':


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 {


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 


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]) {


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    # =


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 


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 


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] == '(')


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))


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         }


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);


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;


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


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