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