1 /* Demangler for GNU C++ 2 Copyright (C) 1989-2017 Free Software Foundation, Inc. 3 Written by James Clark (jjc (at) jclark.uucp) 4 Rewritten by Fred Fish (fnf (at) cygnus.com) for ARM and Lucid demangling 5 Modified by Satish Pai (pai (at) apollo.hp.com) for HP demangling 6 7 This file is part of the libiberty library. 8 Libiberty is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public 10 License as published by the Free Software Foundation; either 11 version 2 of the License, or (at your option) any later version. 12 13 In addition to the permissions in the GNU Library General Public 14 License, the Free Software Foundation gives you unlimited permission 15 to link the compiled version of this file into combinations with other 16 programs, and to distribute those combinations without any restriction 17 coming from the use of this file. (The Library Public License 18 restrictions do apply in other respects; for example, they cover 19 modification of the file, and distribution when not linked into a 20 combined executable.) 21 22 Libiberty is distributed in the hope that it will be useful, 23 but WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25 Library General Public License for more details. 26 27 You should have received a copy of the GNU Library General Public 28 License along with libiberty; see the file COPYING.LIB. If 29 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 30 Boston, MA 02110-1301, USA. */ 31 32 /* This file exports two functions; cplus_mangle_opname and cplus_demangle. 33 34 This file imports xmalloc and xrealloc, which are like malloc and 35 realloc except that they generate a fatal error if there is no 36 available memory. */ 37 38 /* This file lives in both GCC and libiberty. When making changes, please 39 try not to break either. */ 40 41 #if 0 /* in valgrind */ 42 #ifdef HAVE_CONFIG_H 43 #include "config.h" 44 #endif 45 #endif /* ! in valgrind */ 46 47 #if 0 /* in valgrind */ 48 #include "safe-ctype.h" 49 #endif /* ! in valgrind */ 50 51 #if 0 /* in valgrind */ 52 #include <sys/types.h> 53 #include <string.h> 54 #include <stdio.h> 55 #endif /* ! in valgrind */ 56 57 #if 0 /* in valgrind */ 58 #ifdef HAVE_STDLIB_H 59 #include <stdlib.h> 60 #else 61 void * malloc (); 62 void * realloc (); 63 #endif 64 #endif /* ! in valgrind */ 65 66 #if 0 /* in valgrind */ 67 #ifdef HAVE_LIMITS_H 68 #include <limits.h> 69 #endif 70 #endif /* ! in valgrind */ 71 #ifndef INT_MAX 72 # define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ 73 #endif 74 75 #if 0 /* in valgrind */ 76 #include <demangle.h> 77 #undef CURRENT_DEMANGLING_STYLE 78 #define CURRENT_DEMANGLING_STYLE work->options 79 #endif /* ! in valgrind */ 80 81 #if 0 /* in valgrind */ 82 #include "libiberty.h" 83 #endif /* ! in valgrind */ 84 85 #include "vg_libciface.h" 86 87 #include "ansidecl.h" 88 #include "demangle.h" 89 #include "safe-ctype.h" 90 91 #define min(X,Y) (((X) < (Y)) ? (X) : (Y)) 92 93 /* A value at least one greater than the maximum number of characters 94 that will be output when using the `%d' format with `printf'. */ 95 #define INTBUF_SIZE 32 96 97 extern void fancy_abort (void) ATTRIBUTE_NORETURN; 98 99 /* In order to allow a single demangler executable to demangle strings 100 using various common values of CPLUS_MARKER, as well as any specific 101 one set at compile time, we maintain a string containing all the 102 commonly used ones, and check to see if the marker we are looking for 103 is in that string. CPLUS_MARKER is usually '$' on systems where the 104 assembler can deal with that. Where the assembler can't, it's usually 105 '.' (but on many systems '.' is used for other things). We put the 106 current defined CPLUS_MARKER first (which defaults to '$'), followed 107 by the next most common value, followed by an explicit '$' in case 108 the value of CPLUS_MARKER is not '$'. 109 110 We could avoid this if we could just get g++ to tell us what the actual 111 cplus marker character is as part of the debug information, perhaps by 112 ensuring that it is the character that terminates the gcc<n>_compiled 113 marker symbol (FIXME). */ 114 115 #if !defined (CPLUS_MARKER) 116 #define CPLUS_MARKER '$' 117 #endif 118 119 enum demangling_styles current_demangling_style = auto_demangling; 120 121 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; 122 123 static char char_str[2] = { '\000', '\000' }; 124 125 void 126 set_cplus_marker_for_demangling (int ch) 127 { 128 cplus_markers[0] = ch; 129 } 130 131 typedef struct string /* Beware: these aren't required to be */ 132 { /* '\0' terminated. */ 133 char *b; /* pointer to start of string */ 134 char *p; /* pointer after last character */ 135 char *e; /* pointer after end of allocated space */ 136 } string; 137 138 /* Stuff that is shared between sub-routines. 139 Using a shared structure allows cplus_demangle to be reentrant. */ 140 141 struct work_stuff 142 { 143 int options; 144 char **typevec; 145 char **ktypevec; 146 char **btypevec; 147 int numk; 148 int numb; 149 int ksize; 150 int bsize; 151 int ntypes; 152 int typevec_size; 153 int constructor; 154 int destructor; 155 int static_type; /* A static member function */ 156 int temp_start; /* index in demangled to start of template args */ 157 int type_quals; /* The type qualifiers. */ 158 int dllimported; /* Symbol imported from a PE DLL */ 159 char **tmpl_argvec; /* Template function arguments. */ 160 int ntmpl_args; /* The number of template function arguments. */ 161 int forgetting_types; /* Nonzero if we are not remembering the types 162 we see. */ 163 string* previous_argument; /* The last function argument demangled. */ 164 int nrepeats; /* The number of times to repeat the previous 165 argument. */ 166 int *proctypevec; /* Indices of currently processed remembered typevecs. */ 167 int proctypevec_size; 168 int nproctypes; 169 }; 170 171 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) 172 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) 173 174 static const struct optable 175 { 176 const char *const in; 177 const char *const out; 178 const int flags; 179 } optable[] = { 180 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ 181 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ 182 {"new", " new", 0}, /* old (1.91, and 1.x) */ 183 {"delete", " delete", 0}, /* old (1.91, and 1.x) */ 184 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ 185 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ 186 {"as", "=", DMGL_ANSI}, /* ansi */ 187 {"ne", "!=", DMGL_ANSI}, /* old, ansi */ 188 {"eq", "==", DMGL_ANSI}, /* old, ansi */ 189 {"ge", ">=", DMGL_ANSI}, /* old, ansi */ 190 {"gt", ">", DMGL_ANSI}, /* old, ansi */ 191 {"le", "<=", DMGL_ANSI}, /* old, ansi */ 192 {"lt", "<", DMGL_ANSI}, /* old, ansi */ 193 {"plus", "+", 0}, /* old */ 194 {"pl", "+", DMGL_ANSI}, /* ansi */ 195 {"apl", "+=", DMGL_ANSI}, /* ansi */ 196 {"minus", "-", 0}, /* old */ 197 {"mi", "-", DMGL_ANSI}, /* ansi */ 198 {"ami", "-=", DMGL_ANSI}, /* ansi */ 199 {"mult", "*", 0}, /* old */ 200 {"ml", "*", DMGL_ANSI}, /* ansi */ 201 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ 202 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ 203 {"convert", "+", 0}, /* old (unary +) */ 204 {"negate", "-", 0}, /* old (unary -) */ 205 {"trunc_mod", "%", 0}, /* old */ 206 {"md", "%", DMGL_ANSI}, /* ansi */ 207 {"amd", "%=", DMGL_ANSI}, /* ansi */ 208 {"trunc_div", "/", 0}, /* old */ 209 {"dv", "/", DMGL_ANSI}, /* ansi */ 210 {"adv", "/=", DMGL_ANSI}, /* ansi */ 211 {"truth_andif", "&&", 0}, /* old */ 212 {"aa", "&&", DMGL_ANSI}, /* ansi */ 213 {"truth_orif", "||", 0}, /* old */ 214 {"oo", "||", DMGL_ANSI}, /* ansi */ 215 {"truth_not", "!", 0}, /* old */ 216 {"nt", "!", DMGL_ANSI}, /* ansi */ 217 {"postincrement","++", 0}, /* old */ 218 {"pp", "++", DMGL_ANSI}, /* ansi */ 219 {"postdecrement","--", 0}, /* old */ 220 {"mm", "--", DMGL_ANSI}, /* ansi */ 221 {"bit_ior", "|", 0}, /* old */ 222 {"or", "|", DMGL_ANSI}, /* ansi */ 223 {"aor", "|=", DMGL_ANSI}, /* ansi */ 224 {"bit_xor", "^", 0}, /* old */ 225 {"er", "^", DMGL_ANSI}, /* ansi */ 226 {"aer", "^=", DMGL_ANSI}, /* ansi */ 227 {"bit_and", "&", 0}, /* old */ 228 {"ad", "&", DMGL_ANSI}, /* ansi */ 229 {"aad", "&=", DMGL_ANSI}, /* ansi */ 230 {"bit_not", "~", 0}, /* old */ 231 {"co", "~", DMGL_ANSI}, /* ansi */ 232 {"call", "()", 0}, /* old */ 233 {"cl", "()", DMGL_ANSI}, /* ansi */ 234 {"alshift", "<<", 0}, /* old */ 235 {"ls", "<<", DMGL_ANSI}, /* ansi */ 236 {"als", "<<=", DMGL_ANSI}, /* ansi */ 237 {"arshift", ">>", 0}, /* old */ 238 {"rs", ">>", DMGL_ANSI}, /* ansi */ 239 {"ars", ">>=", DMGL_ANSI}, /* ansi */ 240 {"component", "->", 0}, /* old */ 241 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ 242 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ 243 {"indirect", "*", 0}, /* old */ 244 {"method_call", "->()", 0}, /* old */ 245 {"addr", "&", 0}, /* old (unary &) */ 246 {"array", "[]", 0}, /* old */ 247 {"vc", "[]", DMGL_ANSI}, /* ansi */ 248 {"compound", ", ", 0}, /* old */ 249 {"cm", ", ", DMGL_ANSI}, /* ansi */ 250 {"cond", "?:", 0}, /* old */ 251 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ 252 {"max", ">?", 0}, /* old */ 253 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ 254 {"min", "<?", 0}, /* old */ 255 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */ 256 {"nop", "", 0}, /* old (for operator=) */ 257 {"rm", "->*", DMGL_ANSI}, /* ansi */ 258 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */ 259 }; 260 261 /* These values are used to indicate the various type varieties. 262 They are all non-zero so that they can be used as `success' 263 values. */ 264 typedef enum type_kind_t 265 { 266 tk_none, 267 tk_pointer, 268 tk_reference, 269 tk_rvalue_reference, 270 tk_integral, 271 tk_bool, 272 tk_char, 273 tk_real 274 } type_kind_t; 275 276 const struct demangler_engine libiberty_demanglers[] = 277 { 278 { 279 NO_DEMANGLING_STYLE_STRING, 280 no_demangling, 281 "Demangling disabled" 282 } 283 , 284 { 285 AUTO_DEMANGLING_STYLE_STRING, 286 auto_demangling, 287 "Automatic selection based on executable" 288 } 289 , 290 { 291 GNU_DEMANGLING_STYLE_STRING, 292 gnu_demangling, 293 "GNU (g++) style demangling" 294 } 295 , 296 { 297 LUCID_DEMANGLING_STYLE_STRING, 298 lucid_demangling, 299 "Lucid (lcc) style demangling" 300 } 301 , 302 { 303 ARM_DEMANGLING_STYLE_STRING, 304 arm_demangling, 305 "ARM style demangling" 306 } 307 , 308 { 309 HP_DEMANGLING_STYLE_STRING, 310 hp_demangling, 311 "HP (aCC) style demangling" 312 } 313 , 314 { 315 EDG_DEMANGLING_STYLE_STRING, 316 edg_demangling, 317 "EDG style demangling" 318 } 319 , 320 { 321 GNU_V3_DEMANGLING_STYLE_STRING, 322 gnu_v3_demangling, 323 "GNU (g++) V3 ABI-style demangling" 324 } 325 , 326 { 327 JAVA_DEMANGLING_STYLE_STRING, 328 java_demangling, 329 "Java style demangling" 330 } 331 , 332 { 333 GNAT_DEMANGLING_STYLE_STRING, 334 gnat_demangling, 335 "GNAT style demangling" 336 } 337 , 338 { 339 DLANG_DEMANGLING_STYLE_STRING, 340 dlang_demangling, 341 "DLANG style demangling" 342 } 343 , 344 { 345 RUST_DEMANGLING_STYLE_STRING, 346 rust_demangling, 347 "Rust style demangling" 348 } 349 , 350 { 351 NULL, unknown_demangling, NULL 352 } 353 }; 354 355 #define STRING_EMPTY(str) ((str) -> b == (str) -> p) 356 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ 357 string_append(str, " ");} 358 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) 359 360 /* The scope separator appropriate for the language being demangled. */ 361 362 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::") 363 364 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ 365 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ 366 367 /* Prototypes for local functions */ 368 369 static void delete_work_stuff (struct work_stuff *); 370 371 static void delete_non_B_K_work_stuff (struct work_stuff *); 372 373 static char *mop_up (struct work_stuff *, string *, int); 374 375 static void squangle_mop_up (struct work_stuff *); 376 377 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *); 378 379 #if 0 380 static int 381 demangle_method_args (struct work_stuff *, const char **, string *); 382 #endif 383 384 static char * 385 internal_cplus_demangle (struct work_stuff *, const char *); 386 387 static int 388 demangle_template_template_parm (struct work_stuff *work, 389 const char **, string *); 390 391 static int 392 demangle_template (struct work_stuff *work, const char **, string *, 393 string *, int, int); 394 395 static int 396 arm_pt (const char *, int, const char **, const char **); 397 398 static int 399 demangle_class_name (struct work_stuff *, const char **, string *); 400 401 static int 402 demangle_qualified (struct work_stuff *, const char **, string *, 403 int, int); 404 405 static int demangle_class (struct work_stuff *, const char **, string *); 406 407 static int demangle_fund_type (struct work_stuff *, const char **, string *); 408 409 static int demangle_signature (struct work_stuff *, const char **, string *); 410 411 static int demangle_prefix (struct work_stuff *, const char **, string *); 412 413 static int gnu_special (struct work_stuff *, const char **, string *); 414 415 static int arm_special (const char **, string *); 416 417 static void string_need (string *, int); 418 419 static void string_delete (string *); 420 421 static void 422 string_init (string *); 423 424 static void string_clear (string *); 425 426 #if 0 427 static int string_empty (string *); 428 #endif 429 430 static void string_append (string *, const char *); 431 432 static void string_appends (string *, string *); 433 434 static void string_appendn (string *, const char *, int); 435 436 static void string_prepend (string *, const char *); 437 438 static void string_prependn (string *, const char *, int); 439 440 static void string_append_template_idx (string *, int); 441 442 static int get_count (const char **, int *); 443 444 static int consume_count (const char **); 445 446 static int consume_count_with_underscores (const char**); 447 448 static int demangle_args (struct work_stuff *, const char **, string *); 449 450 static int demangle_nested_args (struct work_stuff*, const char**, string*); 451 452 static int do_type (struct work_stuff *, const char **, string *); 453 454 static int do_arg (struct work_stuff *, const char **, string *); 455 456 static int 457 demangle_function_name (struct work_stuff *, const char **, string *, 458 const char *); 459 460 static int 461 iterate_demangle_function (struct work_stuff *, 462 const char **, string *, const char *); 463 464 static void remember_type (struct work_stuff *, const char *, int); 465 466 static void push_processed_type (struct work_stuff *, int); 467 468 static void pop_processed_type (struct work_stuff *); 469 470 static void remember_Btype (struct work_stuff *, const char *, int, int); 471 472 static int register_Btype (struct work_stuff *); 473 474 static void remember_Ktype (struct work_stuff *, const char *, int); 475 476 static void forget_types (struct work_stuff *); 477 478 static void forget_B_and_K_types (struct work_stuff *); 479 480 static void string_prepends (string *, string *); 481 482 static int 483 demangle_template_value_parm (struct work_stuff*, const char**, 484 string*, type_kind_t); 485 486 static int 487 do_hpacc_template_const_value (struct work_stuff *, const char **, string *); 488 489 static int 490 do_hpacc_template_literal (struct work_stuff *, const char **, string *); 491 492 static int snarf_numeric_literal (const char **, string *); 493 494 /* There is a TYPE_QUAL value for each type qualifier. They can be 495 combined by bitwise-or to form the complete set of qualifiers for a 496 type. */ 497 498 #define TYPE_UNQUALIFIED 0x0 499 #define TYPE_QUAL_CONST 0x1 500 #define TYPE_QUAL_VOLATILE 0x2 501 #define TYPE_QUAL_RESTRICT 0x4 502 503 static int code_for_qualifier (int); 504 505 static const char* qualifier_string (int); 506 507 static const char* demangle_qualifier (int); 508 509 static int demangle_expression (struct work_stuff *, const char **, string *, 510 type_kind_t); 511 512 static int 513 demangle_integral_value (struct work_stuff *, const char **, string *); 514 515 static int 516 demangle_real_value (struct work_stuff *, const char **, string *); 517 518 static void 519 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *); 520 521 static void 522 recursively_demangle (struct work_stuff *, const char **, string *, int); 523 524 /* Translate count to integer, consuming tokens in the process. 525 Conversion terminates on the first non-digit character. 526 527 Trying to consume something that isn't a count results in no 528 consumption of input and a return of -1. 529 530 Overflow consumes the rest of the digits, and returns -1. */ 531 532 static int 533 consume_count (const char **type) 534 { 535 int count = 0; 536 537 if (! ISDIGIT ((unsigned char)**type)) 538 return -1; 539 540 while (ISDIGIT ((unsigned char)**type)) 541 { 542 count *= 10; 543 544 /* Check for overflow. 545 We assume that count is represented using two's-complement; 546 no power of two is divisible by ten, so if an overflow occurs 547 when multiplying by ten, the result will not be a multiple of 548 ten. */ 549 if ((count % 10) != 0) 550 { 551 while (ISDIGIT ((unsigned char) **type)) 552 (*type)++; 553 return -1; 554 } 555 556 count += **type - '0'; 557 (*type)++; 558 } 559 560 if (count < 0) 561 count = -1; 562 563 return (count); 564 } 565 566 567 /* Like consume_count, but for counts that are preceded and followed 568 by '_' if they are greater than 10. Also, -1 is returned for 569 failure, since 0 can be a valid value. */ 570 571 static int 572 consume_count_with_underscores (const char **mangled) 573 { 574 int idx; 575 576 if (**mangled == '_') 577 { 578 (*mangled)++; 579 if (!ISDIGIT ((unsigned char)**mangled)) 580 return -1; 581 582 idx = consume_count (mangled); 583 if (**mangled != '_') 584 /* The trailing underscore was missing. */ 585 return -1; 586 587 (*mangled)++; 588 } 589 else 590 { 591 if (**mangled < '0' || **mangled > '9') 592 return -1; 593 594 idx = **mangled - '0'; 595 (*mangled)++; 596 } 597 598 return idx; 599 } 600 601 /* C is the code for a type-qualifier. Return the TYPE_QUAL 602 corresponding to this qualifier. */ 603 604 static int 605 code_for_qualifier (int c) 606 { 607 switch (c) 608 { 609 case 'C': 610 return TYPE_QUAL_CONST; 611 612 case 'V': 613 return TYPE_QUAL_VOLATILE; 614 615 case 'u': 616 return TYPE_QUAL_RESTRICT; 617 618 default: 619 break; 620 } 621 622 /* C was an invalid qualifier. */ 623 abort (); 624 } 625 626 /* Return the string corresponding to the qualifiers given by 627 TYPE_QUALS. */ 628 629 static const char* 630 qualifier_string (int type_quals) 631 { 632 switch (type_quals) 633 { 634 case TYPE_UNQUALIFIED: 635 return ""; 636 637 case TYPE_QUAL_CONST: 638 return "const"; 639 640 case TYPE_QUAL_VOLATILE: 641 return "volatile"; 642 643 case TYPE_QUAL_RESTRICT: 644 return "__restrict"; 645 646 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: 647 return "const volatile"; 648 649 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: 650 return "const __restrict"; 651 652 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: 653 return "volatile __restrict"; 654 655 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: 656 return "const volatile __restrict"; 657 658 default: 659 break; 660 } 661 662 /* TYPE_QUALS was an invalid qualifier set. */ 663 abort (); 664 } 665 666 /* C is the code for a type-qualifier. Return the string 667 corresponding to this qualifier. This function should only be 668 called with a valid qualifier code. */ 669 670 static const char* 671 demangle_qualifier (int c) 672 { 673 return qualifier_string (code_for_qualifier (c)); 674 } 675 676 int 677 cplus_demangle_opname (const char *opname, char *result, int options) 678 { 679 int len, len1, ret; 680 string type; 681 struct work_stuff work[1]; 682 const char *tem; 683 684 len = strlen(opname); 685 result[0] = '\0'; 686 ret = 0; 687 memset ((char *) work, 0, sizeof (work)); 688 work->options = options; 689 690 if (opname[0] == '_' && opname[1] == '_' 691 && opname[2] == 'o' && opname[3] == 'p') 692 { 693 /* ANSI. */ 694 /* type conversion operator. */ 695 tem = opname + 4; 696 if (do_type (work, &tem, &type)) 697 { 698 strcat (result, "operator "); 699 strncat (result, type.b, type.p - type.b); 700 string_delete (&type); 701 ret = 1; 702 } 703 } 704 else if (opname[0] == '_' && opname[1] == '_' 705 && ISLOWER((unsigned char)opname[2]) 706 && ISLOWER((unsigned char)opname[3])) 707 { 708 if (opname[4] == '\0') 709 { 710 /* Operator. */ 711 size_t i; 712 for (i = 0; i < ARRAY_SIZE (optable); i++) 713 { 714 if (strlen (optable[i].in) == 2 715 && memcmp (optable[i].in, opname + 2, 2) == 0) 716 { 717 strcat (result, "operator"); 718 strcat (result, optable[i].out); 719 ret = 1; 720 break; 721 } 722 } 723 } 724 else 725 { 726 if (opname[2] == 'a' && opname[5] == '\0') 727 { 728 /* Assignment. */ 729 size_t i; 730 for (i = 0; i < ARRAY_SIZE (optable); i++) 731 { 732 if (strlen (optable[i].in) == 3 733 && memcmp (optable[i].in, opname + 2, 3) == 0) 734 { 735 strcat (result, "operator"); 736 strcat (result, optable[i].out); 737 ret = 1; 738 break; 739 } 740 } 741 } 742 } 743 } 744 else if (len >= 3 745 && opname[0] == 'o' 746 && opname[1] == 'p' 747 && strchr (cplus_markers, opname[2]) != NULL) 748 { 749 /* see if it's an assignment expression */ 750 if (len >= 10 /* op$assign_ */ 751 && memcmp (opname + 3, "assign_", 7) == 0) 752 { 753 size_t i; 754 for (i = 0; i < ARRAY_SIZE (optable); i++) 755 { 756 len1 = len - 10; 757 if ((int) strlen (optable[i].in) == len1 758 && memcmp (optable[i].in, opname + 10, len1) == 0) 759 { 760 strcat (result, "operator"); 761 strcat (result, optable[i].out); 762 strcat (result, "="); 763 ret = 1; 764 break; 765 } 766 } 767 } 768 else 769 { 770 size_t i; 771 for (i = 0; i < ARRAY_SIZE (optable); i++) 772 { 773 len1 = len - 3; 774 if ((int) strlen (optable[i].in) == len1 775 && memcmp (optable[i].in, opname + 3, len1) == 0) 776 { 777 strcat (result, "operator"); 778 strcat (result, optable[i].out); 779 ret = 1; 780 break; 781 } 782 } 783 } 784 } 785 else if (len >= 5 && memcmp (opname, "type", 4) == 0 786 && strchr (cplus_markers, opname[4]) != NULL) 787 { 788 /* type conversion operator */ 789 tem = opname + 5; 790 if (do_type (work, &tem, &type)) 791 { 792 strcat (result, "operator "); 793 strncat (result, type.b, type.p - type.b); 794 string_delete (&type); 795 ret = 1; 796 } 797 } 798 squangle_mop_up (work); 799 return ret; 800 801 } 802 803 /* Takes operator name as e.g. "++" and returns mangled 804 operator name (e.g. "postincrement_expr"), or NULL if not found. 805 806 If OPTIONS & DMGL_ANSI == 1, return the ANSI name; 807 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ 808 809 const char * 810 cplus_mangle_opname (const char *opname, int options) 811 { 812 size_t i; 813 int len; 814 815 len = strlen (opname); 816 for (i = 0; i < ARRAY_SIZE (optable); i++) 817 { 818 if ((int) strlen (optable[i].out) == len 819 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) 820 && memcmp (optable[i].out, opname, len) == 0) 821 return optable[i].in; 822 } 823 return (0); 824 } 825 826 /* Add a routine to set the demangling style to be sure it is valid and 827 allow for any demangler initialization that maybe necessary. */ 828 829 enum demangling_styles 830 cplus_demangle_set_style (enum demangling_styles style) 831 { 832 const struct demangler_engine *demangler = libiberty_demanglers; 833 834 for (; demangler->demangling_style != unknown_demangling; ++demangler) 835 if (style == demangler->demangling_style) 836 { 837 current_demangling_style = style; 838 return current_demangling_style; 839 } 840 841 return unknown_demangling; 842 } 843 844 /* Do string name to style translation */ 845 846 enum demangling_styles 847 cplus_demangle_name_to_style (const char *name) 848 { 849 const struct demangler_engine *demangler = libiberty_demanglers; 850 851 for (; demangler->demangling_style != unknown_demangling; ++demangler) 852 if (strcmp (name, demangler->demangling_style_name) == 0) 853 return demangler->demangling_style; 854 855 return unknown_demangling; 856 } 857 858 /* char *cplus_demangle (const char *mangled, int options) 859 860 If MANGLED is a mangled function name produced by GNU C++, then 861 a pointer to a @code{malloc}ed string giving a C++ representation 862 of the name will be returned; otherwise NULL will be returned. 863 It is the caller's responsibility to free the string which 864 is returned. 865 866 The OPTIONS arg may contain one or more of the following bits: 867 868 DMGL_ANSI ANSI qualifiers such as `const' and `void' are 869 included. 870 DMGL_PARAMS Function parameters are included. 871 872 For example, 873 874 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" 875 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" 876 cplus_demangle ("foo__1Ai", 0) => "A::foo" 877 878 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" 879 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" 880 cplus_demangle ("foo__1Afe", 0) => "A::foo" 881 882 Note that any leading underscores, or other such characters prepended by 883 the compilation system, are presumed to have already been stripped from 884 MANGLED. */ 885 886 char * 887 ML_(cplus_demangle) (const char *mangled, int options) 888 { 889 char *ret; 890 struct work_stuff work[1]; 891 892 if (current_demangling_style == no_demangling) 893 return xstrdup (mangled); 894 895 memset ((char *) work, 0, sizeof (work)); 896 work->options = options; 897 if ((work->options & DMGL_STYLE_MASK) == 0) 898 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; 899 900 /* The V3 ABI demangling is implemented elsewhere. */ 901 if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING) 902 { 903 ret = cplus_demangle_v3 (mangled, work->options); 904 if (GNU_V3_DEMANGLING) 905 return ret; 906 907 if (ret) 908 { 909 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. 910 The subtitutions are always smaller, so do in place changes. */ 911 if (rust_is_mangled (ret)) 912 rust_demangle_sym (ret); 913 else if (RUST_DEMANGLING) 914 { 915 free (ret); 916 ret = NULL; 917 } 918 } 919 920 if (ret || RUST_DEMANGLING) 921 return ret; 922 } 923 924 if (JAVA_DEMANGLING) 925 { 926 ret = java_demangle_v3 (mangled); 927 if (ret) 928 return ret; 929 } 930 931 if (GNAT_DEMANGLING) 932 return ada_demangle (mangled, options); 933 934 if (DLANG_DEMANGLING) 935 { 936 ret = dlang_demangle (mangled, options); 937 if (ret) 938 return ret; 939 } 940 941 ret = internal_cplus_demangle (work, mangled); 942 squangle_mop_up (work); 943 return (ret); 944 } 945 946 char * 947 rust_demangle (const char *mangled, int options) 948 { 949 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */ 950 char *ret = cplus_demangle_v3 (mangled, options); 951 952 /* The Rust subtitutions are always smaller, so do in place changes. */ 953 if (ret != NULL) 954 { 955 if (rust_is_mangled (ret)) 956 rust_demangle_sym (ret); 957 else 958 { 959 free (ret); 960 ret = NULL; 961 } 962 } 963 964 return ret; 965 } 966 967 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */ 968 969 char * 970 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) 971 { 972 int len0; 973 const char* p; 974 char *d; 975 char *demangled = NULL; 976 977 /* Discard leading _ada_, which is used for library level subprograms. */ 978 if (strncmp (mangled, "_ada_", 5) == 0) 979 mangled += 5; 980 981 /* All ada unit names are lower-case. */ 982 if (!ISLOWER (mangled[0])) 983 goto unknown; 984 985 /* Most of the demangling will trivially remove chars. Operator names 986 may add one char but because they are always preceded by '__' which is 987 replaced by '.', they eventually never expand the size. 988 A few special names such as '___elabs' add a few chars (at most 7), but 989 they occur only once. */ 990 len0 = strlen (mangled) + 7 + 1; 991 demangled = XNEWVEC (char, len0); 992 993 d = demangled; 994 p = mangled; 995 while (1) 996 { 997 /* An entity names is expected. */ 998 if (ISLOWER (*p)) 999 { 1000 /* An identifier, which is always lower case. */ 1001 do 1002 *d++ = *p++; 1003 while (ISLOWER(*p) || ISDIGIT (*p) 1004 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1])))); 1005 } 1006 else if (p[0] == 'O') 1007 { 1008 /* An operator name. */ 1009 static const char * const operators[][2] = 1010 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"}, 1011 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"}, 1012 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="}, 1013 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"}, 1014 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"}, 1015 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"}, 1016 {"Oexpon", "**"}, {NULL, NULL}}; 1017 int k; 1018 1019 for (k = 0; operators[k][0] != NULL; k++) 1020 { 1021 size_t slen = strlen (operators[k][0]); 1022 if (strncmp (p, operators[k][0], slen) == 0) 1023 { 1024 p += slen; 1025 slen = strlen (operators[k][1]); 1026 *d++ = '"'; 1027 memcpy (d, operators[k][1], slen); 1028 d += slen; 1029 *d++ = '"'; 1030 break; 1031 } 1032 } 1033 /* Operator not found. */ 1034 if (operators[k][0] == NULL) 1035 goto unknown; 1036 } 1037 else 1038 { 1039 /* Not a GNAT encoding. */ 1040 goto unknown; 1041 } 1042 1043 /* The name can be directly followed by some uppercase letters. */ 1044 if (p[0] == 'T' && p[1] == 'K') 1045 { 1046 /* Task stuff. */ 1047 if (p[2] == 'B' && p[3] == 0) 1048 { 1049 /* Subprogram for task body. */ 1050 break; 1051 } 1052 else if (p[2] == '_' && p[3] == '_') 1053 { 1054 /* Inner declarations in a task. */ 1055 p += 4; 1056 *d++ = '.'; 1057 continue; 1058 } 1059 else 1060 goto unknown; 1061 } 1062 if (p[0] == 'E' && p[1] == 0) 1063 { 1064 /* Exception name. */ 1065 goto unknown; 1066 } 1067 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0) 1068 { 1069 /* Protected type subprogram. */ 1070 break; 1071 } 1072 if ((*p == 'N' || *p == 'S') && p[1] == 0) 1073 { 1074 /* Enumerated type name table. */ 1075 goto unknown; 1076 } 1077 if (p[0] == 'X') 1078 { 1079 /* Body nested. */ 1080 p++; 1081 while (p[0] == 'n' || p[0] == 'b') 1082 p++; 1083 } 1084 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0)) 1085 { 1086 /* Stream operations. */ 1087 const char *name; 1088 switch (p[1]) 1089 { 1090 case 'R': 1091 name = "'Read"; 1092 break; 1093 case 'W': 1094 name = "'Write"; 1095 break; 1096 case 'I': 1097 name = "'Input"; 1098 break; 1099 case 'O': 1100 name = "'Output"; 1101 break; 1102 default: 1103 goto unknown; 1104 } 1105 p += 2; 1106 strcpy (d, name); 1107 d += strlen (name); 1108 } 1109 else if (p[0] == 'D') 1110 { 1111 /* Controlled type operation. */ 1112 const char *name; 1113 switch (p[1]) 1114 { 1115 case 'F': 1116 name = ".Finalize"; 1117 break; 1118 case 'A': 1119 name = ".Adjust"; 1120 break; 1121 default: 1122 goto unknown; 1123 } 1124 strcpy (d, name); 1125 d += strlen (name); 1126 break; 1127 } 1128 1129 if (p[0] == '_') 1130 { 1131 /* Separator. */ 1132 if (p[1] == '_') 1133 { 1134 /* Standard separator. Handled first. */ 1135 p += 2; 1136 1137 if (ISDIGIT (*p)) 1138 { 1139 /* Overloading number. */ 1140 do 1141 p++; 1142 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1]))); 1143 if (*p == 'X') 1144 { 1145 p++; 1146 while (p[0] == 'n' || p[0] == 'b') 1147 p++; 1148 } 1149 } 1150 else if (p[0] == '_' && p[1] != '_') 1151 { 1152 /* Special names. */ 1153 static const char * const special[][2] = { 1154 { "_elabb", "'Elab_Body" }, 1155 { "_elabs", "'Elab_Spec" }, 1156 { "_size", "'Size" }, 1157 { "_alignment", "'Alignment" }, 1158 { "_assign", ".\":=\"" }, 1159 { NULL, NULL } 1160 }; 1161 int k; 1162 1163 for (k = 0; special[k][0] != NULL; k++) 1164 { 1165 size_t slen = strlen (special[k][0]); 1166 if (strncmp (p, special[k][0], slen) == 0) 1167 { 1168 p += slen; 1169 slen = strlen (special[k][1]); 1170 memcpy (d, special[k][1], slen); 1171 d += slen; 1172 break; 1173 } 1174 } 1175 if (special[k][0] != NULL) 1176 break; 1177 else 1178 goto unknown; 1179 } 1180 else 1181 { 1182 *d++ = '.'; 1183 continue; 1184 } 1185 } 1186 else if (p[1] == 'B' || p[1] == 'E') 1187 { 1188 /* Entry Body or barrier Evaluation. */ 1189 p += 2; 1190 while (ISDIGIT (*p)) 1191 p++; 1192 if (p[0] == 's' && p[1] == 0) 1193 break; 1194 else 1195 goto unknown; 1196 } 1197 else 1198 goto unknown; 1199 } 1200 1201 if (p[0] == '.' && ISDIGIT (p[1])) 1202 { 1203 /* Nested subprogram. */ 1204 p += 2; 1205 while (ISDIGIT (*p)) 1206 p++; 1207 } 1208 if (*p == 0) 1209 { 1210 /* End of mangled name. */ 1211 break; 1212 } 1213 else 1214 goto unknown; 1215 } 1216 *d = 0; 1217 return demangled; 1218 1219 unknown: 1220 XDELETEVEC (demangled); 1221 len0 = strlen (mangled); 1222 demangled = XNEWVEC (char, len0 + 3); 1223 1224 if (mangled[0] == '<') 1225 strcpy (demangled, mangled); 1226 else 1227 sprintf (demangled, "<%s>", mangled); 1228 1229 return demangled; 1230 } 1231 1232 /* This function performs most of what cplus_demangle use to do, but 1233 to be able to demangle a name with a B, K or n code, we need to 1234 have a longer term memory of what types have been seen. The original 1235 now initializes and cleans up the squangle code info, while internal 1236 calls go directly to this routine to avoid resetting that info. */ 1237 1238 static char * 1239 internal_cplus_demangle (struct work_stuff *work, const char *mangled) 1240 { 1241 1242 string decl; 1243 int success = 0; 1244 char *demangled = NULL; 1245 int s1, s2, s3, s4; 1246 s1 = work->constructor; 1247 s2 = work->destructor; 1248 s3 = work->static_type; 1249 s4 = work->type_quals; 1250 work->constructor = work->destructor = 0; 1251 work->type_quals = TYPE_UNQUALIFIED; 1252 work->dllimported = 0; 1253 1254 if ((mangled != NULL) && (*mangled != '\0')) 1255 { 1256 string_init (&decl); 1257 1258 /* First check to see if gnu style demangling is active and if the 1259 string to be demangled contains a CPLUS_MARKER. If so, attempt to 1260 recognize one of the gnu special forms rather than looking for a 1261 standard prefix. In particular, don't worry about whether there 1262 is a "__" string in the mangled string. Consider "_$_5__foo" for 1263 example. */ 1264 1265 if ((AUTO_DEMANGLING || GNU_DEMANGLING)) 1266 { 1267 success = gnu_special (work, &mangled, &decl); 1268 if (!success) 1269 { 1270 delete_work_stuff (work); 1271 string_delete (&decl); 1272 } 1273 } 1274 if (!success) 1275 { 1276 success = demangle_prefix (work, &mangled, &decl); 1277 } 1278 if (success && (*mangled != '\0')) 1279 { 1280 success = demangle_signature (work, &mangled, &decl); 1281 } 1282 if (work->constructor == 2) 1283 { 1284 string_prepend (&decl, "global constructors keyed to "); 1285 work->constructor = 0; 1286 } 1287 else if (work->destructor == 2) 1288 { 1289 string_prepend (&decl, "global destructors keyed to "); 1290 work->destructor = 0; 1291 } 1292 else if (work->dllimported == 1) 1293 { 1294 string_prepend (&decl, "import stub for "); 1295 work->dllimported = 0; 1296 } 1297 demangled = mop_up (work, &decl, success); 1298 } 1299 work->constructor = s1; 1300 work->destructor = s2; 1301 work->static_type = s3; 1302 work->type_quals = s4; 1303 return demangled; 1304 } 1305 1306 1307 /* Clear out and squangling related storage */ 1308 static void 1309 squangle_mop_up (struct work_stuff *work) 1310 { 1311 /* clean up the B and K type mangling types. */ 1312 forget_B_and_K_types (work); 1313 if (work -> btypevec != NULL) 1314 { 1315 free ((char *) work -> btypevec); 1316 work->btypevec = NULL; 1317 work->bsize = 0; 1318 } 1319 if (work -> ktypevec != NULL) 1320 { 1321 free ((char *) work -> ktypevec); 1322 work->ktypevec = NULL; 1323 work->ksize = 0; 1324 } 1325 } 1326 1327 1328 /* Copy the work state and storage. */ 1329 1330 static void 1331 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) 1332 { 1333 int i; 1334 1335 delete_work_stuff (to); 1336 1337 /* Shallow-copy scalars. */ 1338 memcpy (to, from, sizeof (*to)); 1339 1340 /* Deep-copy dynamic storage. */ 1341 if (from->typevec_size) 1342 to->typevec = XNEWVEC (char *, from->typevec_size); 1343 1344 for (i = 0; i < from->ntypes; i++) 1345 { 1346 int len = strlen (from->typevec[i]) + 1; 1347 1348 to->typevec[i] = XNEWVEC (char, len); 1349 memcpy (to->typevec[i], from->typevec[i], len); 1350 } 1351 1352 if (from->ksize) 1353 to->ktypevec = XNEWVEC (char *, from->ksize); 1354 1355 for (i = 0; i < from->numk; i++) 1356 { 1357 int len = strlen (from->ktypevec[i]) + 1; 1358 1359 to->ktypevec[i] = XNEWVEC (char, len); 1360 memcpy (to->ktypevec[i], from->ktypevec[i], len); 1361 } 1362 1363 if (from->bsize) 1364 to->btypevec = XNEWVEC (char *, from->bsize); 1365 1366 for (i = 0; i < from->numb; i++) 1367 { 1368 int len = strlen (from->btypevec[i]) + 1; 1369 1370 to->btypevec[i] = XNEWVEC (char , len); 1371 memcpy (to->btypevec[i], from->btypevec[i], len); 1372 } 1373 1374 if (from->proctypevec) 1375 to->proctypevec = 1376 XDUPVEC (int, from->proctypevec, from->proctypevec_size); 1377 1378 if (from->ntmpl_args) 1379 to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); 1380 1381 for (i = 0; i < from->ntmpl_args; i++) 1382 { 1383 int len = strlen (from->tmpl_argvec[i]) + 1; 1384 1385 to->tmpl_argvec[i] = XNEWVEC (char, len); 1386 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); 1387 } 1388 1389 if (from->previous_argument) 1390 { 1391 to->previous_argument = XNEW (string); 1392 string_init (to->previous_argument); 1393 string_appends (to->previous_argument, from->previous_argument); 1394 } 1395 } 1396 1397 1398 /* Delete dynamic stuff in work_stuff that is not to be re-used. */ 1399 1400 static void 1401 delete_non_B_K_work_stuff (struct work_stuff *work) 1402 { 1403 /* Discard the remembered types, if any. */ 1404 1405 forget_types (work); 1406 if (work->typevec != NULL) 1407 { 1408 free ((char *) work->typevec); 1409 work->typevec = NULL; 1410 work->typevec_size = 0; 1411 } 1412 if (work->proctypevec != NULL) 1413 { 1414 free (work->proctypevec); 1415 work->proctypevec = NULL; 1416 work->proctypevec_size = 0; 1417 } 1418 if (work->tmpl_argvec) 1419 { 1420 int i; 1421 1422 for (i = 0; i < work->ntmpl_args; i++) 1423 free ((char*) work->tmpl_argvec[i]); 1424 1425 free ((char*) work->tmpl_argvec); 1426 work->tmpl_argvec = NULL; 1427 } 1428 if (work->previous_argument) 1429 { 1430 string_delete (work->previous_argument); 1431 free ((char*) work->previous_argument); 1432 work->previous_argument = NULL; 1433 } 1434 } 1435 1436 1437 /* Delete all dynamic storage in work_stuff. */ 1438 static void 1439 delete_work_stuff (struct work_stuff *work) 1440 { 1441 delete_non_B_K_work_stuff (work); 1442 squangle_mop_up (work); 1443 } 1444 1445 1446 /* Clear out any mangled storage */ 1447 1448 static char * 1449 mop_up (struct work_stuff *work, string *declp, int success) 1450 { 1451 char *demangled = NULL; 1452 1453 delete_non_B_K_work_stuff (work); 1454 1455 /* If demangling was successful, ensure that the demangled string is null 1456 terminated and return it. Otherwise, free the demangling decl. */ 1457 1458 if (!success) 1459 { 1460 string_delete (declp); 1461 } 1462 else 1463 { 1464 string_appendn (declp, "", 1); 1465 demangled = declp->b; 1466 } 1467 return (demangled); 1468 } 1469 1470 /* 1471 1472 LOCAL FUNCTION 1473 1474 demangle_signature -- demangle the signature part of a mangled name 1475 1476 SYNOPSIS 1477 1478 static int 1479 demangle_signature (struct work_stuff *work, const char **mangled, 1480 string *declp); 1481 1482 DESCRIPTION 1483 1484 Consume and demangle the signature portion of the mangled name. 1485 1486 DECLP is the string where demangled output is being built. At 1487 entry it contains the demangled root name from the mangled name 1488 prefix. I.E. either a demangled operator name or the root function 1489 name. In some special cases, it may contain nothing. 1490 1491 *MANGLED points to the current unconsumed location in the mangled 1492 name. As tokens are consumed and demangling is performed, the 1493 pointer is updated to continuously point at the next token to 1494 be consumed. 1495 1496 Demangling GNU style mangled names is nasty because there is no 1497 explicit token that marks the start of the outermost function 1498 argument list. */ 1499 1500 static int 1501 demangle_signature (struct work_stuff *work, 1502 const char **mangled, string *declp) 1503 { 1504 int success = 1; 1505 int func_done = 0; 1506 int expect_func = 0; 1507 int expect_return_type = 0; 1508 const char *oldmangled = NULL; 1509 string trawname; 1510 string tname; 1511 1512 while (success && (**mangled != '\0')) 1513 { 1514 switch (**mangled) 1515 { 1516 case 'Q': 1517 oldmangled = *mangled; 1518 success = demangle_qualified (work, mangled, declp, 1, 0); 1519 if (success) 1520 remember_type (work, oldmangled, *mangled - oldmangled); 1521 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1522 expect_func = 1; 1523 oldmangled = NULL; 1524 break; 1525 1526 case 'K': 1527 //oldmangled = *mangled; 1528 success = demangle_qualified (work, mangled, declp, 1, 0); 1529 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1530 { 1531 expect_func = 1; 1532 } 1533 oldmangled = NULL; 1534 break; 1535 1536 case 'S': 1537 /* Static member function */ 1538 if (oldmangled == NULL) 1539 { 1540 oldmangled = *mangled; 1541 } 1542 (*mangled)++; 1543 work -> static_type = 1; 1544 break; 1545 1546 case 'C': 1547 case 'V': 1548 case 'u': 1549 work->type_quals |= code_for_qualifier (**mangled); 1550 1551 /* a qualified member function */ 1552 if (oldmangled == NULL) 1553 oldmangled = *mangled; 1554 (*mangled)++; 1555 break; 1556 1557 case 'L': 1558 /* Local class name follows after "Lnnn_" */ 1559 if (HP_DEMANGLING) 1560 { 1561 while (**mangled && (**mangled != '_')) 1562 (*mangled)++; 1563 if (!**mangled) 1564 success = 0; 1565 else 1566 (*mangled)++; 1567 } 1568 else 1569 success = 0; 1570 break; 1571 1572 case '0': case '1': case '2': case '3': case '4': 1573 case '5': case '6': case '7': case '8': case '9': 1574 if (oldmangled == NULL) 1575 { 1576 oldmangled = *mangled; 1577 } 1578 work->temp_start = -1; /* uppermost call to demangle_class */ 1579 success = demangle_class (work, mangled, declp); 1580 if (success) 1581 { 1582 remember_type (work, oldmangled, *mangled - oldmangled); 1583 } 1584 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) 1585 { 1586 /* EDG and others will have the "F", so we let the loop cycle 1587 if we are looking at one. */ 1588 if (**mangled != 'F') 1589 expect_func = 1; 1590 } 1591 oldmangled = NULL; 1592 break; 1593 1594 case 'B': 1595 { 1596 string s; 1597 success = do_type (work, mangled, &s); 1598 if (success) 1599 { 1600 string_append (&s, SCOPE_STRING (work)); 1601 string_prepends (declp, &s); 1602 string_delete (&s); 1603 } 1604 oldmangled = NULL; 1605 expect_func = 1; 1606 } 1607 break; 1608 1609 case 'F': 1610 /* Function */ 1611 /* ARM/HP style demangling includes a specific 'F' character after 1612 the class name. For GNU style, it is just implied. So we can 1613 safely just consume any 'F' at this point and be compatible 1614 with either style. */ 1615 1616 oldmangled = NULL; 1617 func_done = 1; 1618 (*mangled)++; 1619 1620 /* For lucid/ARM/HP style we have to forget any types we might 1621 have remembered up to this point, since they were not argument 1622 types. GNU style considers all types seen as available for 1623 back references. See comment in demangle_args() */ 1624 1625 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 1626 { 1627 forget_types (work); 1628 } 1629 success = demangle_args (work, mangled, declp); 1630 /* After picking off the function args, we expect to either 1631 find the function return type (preceded by an '_') or the 1632 end of the string. */ 1633 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') 1634 { 1635 ++(*mangled); 1636 /* At this level, we do not care about the return type. */ 1637 success = do_type (work, mangled, &tname); 1638 string_delete (&tname); 1639 } 1640 1641 break; 1642 1643 case 't': 1644 /* G++ Template */ 1645 string_init(&trawname); 1646 string_init(&tname); 1647 if (oldmangled == NULL) 1648 { 1649 oldmangled = *mangled; 1650 } 1651 success = demangle_template (work, mangled, &tname, 1652 &trawname, 1, 1); 1653 if (success) 1654 { 1655 remember_type (work, oldmangled, *mangled - oldmangled); 1656 } 1657 string_append (&tname, SCOPE_STRING (work)); 1658 1659 string_prepends(declp, &tname); 1660 if (work -> destructor & 1) 1661 { 1662 string_prepend (&trawname, "~"); 1663 string_appends (declp, &trawname); 1664 work->destructor -= 1; 1665 } 1666 if ((work->constructor & 1) || (work->destructor & 1)) 1667 { 1668 string_appends (declp, &trawname); 1669 work->constructor -= 1; 1670 } 1671 string_delete(&trawname); 1672 string_delete(&tname); 1673 oldmangled = NULL; 1674 expect_func = 1; 1675 break; 1676 1677 case '_': 1678 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type) 1679 { 1680 /* Read the return type. */ 1681 string return_type; 1682 1683 (*mangled)++; 1684 success = do_type (work, mangled, &return_type); 1685 APPEND_BLANK (&return_type); 1686 1687 string_prepends (declp, &return_type); 1688 string_delete (&return_type); 1689 break; 1690 } 1691 else 1692 /* At the outermost level, we cannot have a return type specified, 1693 so if we run into another '_' at this point we are dealing with 1694 a mangled name that is either bogus, or has been mangled by 1695 some algorithm we don't know how to deal with. So just 1696 reject the entire demangling. */ 1697 /* However, "_nnn" is an expected suffix for alternate entry point 1698 numbered nnn for a function, with HP aCC, so skip over that 1699 without reporting failure. pai/1997-09-04 */ 1700 if (HP_DEMANGLING) 1701 { 1702 (*mangled)++; 1703 while (**mangled && ISDIGIT ((unsigned char)**mangled)) 1704 (*mangled)++; 1705 } 1706 else 1707 success = 0; 1708 break; 1709 1710 case 'H': 1711 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1712 { 1713 /* A G++ template function. Read the template arguments. */ 1714 success = demangle_template (work, mangled, declp, 0, 0, 1715 0); 1716 if (!(work->constructor & 1)) 1717 expect_return_type = 1; 1718 if (!**mangled) 1719 success = 0; 1720 else 1721 (*mangled)++; 1722 break; 1723 } 1724 /* fall through */ 1725 1726 default: 1727 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1728 { 1729 /* Assume we have stumbled onto the first outermost function 1730 argument token, and start processing args. */ 1731 func_done = 1; 1732 success = demangle_args (work, mangled, declp); 1733 } 1734 else 1735 { 1736 /* Non-GNU demanglers use a specific token to mark the start 1737 of the outermost function argument tokens. Typically 'F', 1738 for ARM/HP-demangling, for example. So if we find something 1739 we are not prepared for, it must be an error. */ 1740 success = 0; 1741 } 1742 break; 1743 } 1744 /* 1745 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1746 */ 1747 { 1748 if (success && expect_func) 1749 { 1750 func_done = 1; 1751 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) 1752 { 1753 forget_types (work); 1754 } 1755 success = demangle_args (work, mangled, declp); 1756 /* Since template include the mangling of their return types, 1757 we must set expect_func to 0 so that we don't try do 1758 demangle more arguments the next time we get here. */ 1759 expect_func = 0; 1760 } 1761 } 1762 } 1763 if (success && !func_done) 1764 { 1765 if (AUTO_DEMANGLING || GNU_DEMANGLING) 1766 { 1767 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and 1768 bar__3fooi is 'foo::bar(int)'. We get here when we find the 1769 first case, and need to ensure that the '(void)' gets added to 1770 the current declp. Note that with ARM/HP, the first case 1771 represents the name of a static data member 'foo::bar', 1772 which is in the current declp, so we leave it alone. */ 1773 success = demangle_args (work, mangled, declp); 1774 } 1775 } 1776 if (success && PRINT_ARG_TYPES) 1777 { 1778 if (work->static_type) 1779 string_append (declp, " static"); 1780 if (work->type_quals != TYPE_UNQUALIFIED) 1781 { 1782 APPEND_BLANK (declp); 1783 string_append (declp, qualifier_string (work->type_quals)); 1784 } 1785 } 1786 1787 return (success); 1788 } 1789 1790 #if 0 1791 1792 static int 1793 demangle_method_args (struct work_stuff *work, const char **mangled, 1794 string *declp) 1795 { 1796 int success = 0; 1797 1798 if (work -> static_type) 1799 { 1800 string_append (declp, *mangled + 1); 1801 *mangled += strlen (*mangled); 1802 success = 1; 1803 } 1804 else 1805 { 1806 success = demangle_args (work, mangled, declp); 1807 } 1808 return (success); 1809 } 1810 1811 #endif 1812 1813 static int 1814 demangle_template_template_parm (struct work_stuff *work, 1815 const char **mangled, string *tname) 1816 { 1817 int i; 1818 int r; 1819 int need_comma = 0; 1820 int success = 1; 1821 string temp; 1822 1823 string_append (tname, "template <"); 1824 /* get size of template parameter list */ 1825 if (get_count (mangled, &r)) 1826 { 1827 for (i = 0; i < r; i++) 1828 { 1829 if (need_comma) 1830 { 1831 string_append (tname, ", "); 1832 } 1833 1834 /* Z for type parameters */ 1835 if (**mangled == 'Z') 1836 { 1837 (*mangled)++; 1838 string_append (tname, "class"); 1839 } 1840 /* z for template parameters */ 1841 else if (**mangled == 'z') 1842 { 1843 (*mangled)++; 1844 success = 1845 demangle_template_template_parm (work, mangled, tname); 1846 if (!success) 1847 { 1848 break; 1849 } 1850 } 1851 else 1852 { 1853 /* temp is initialized in do_type */ 1854 success = do_type (work, mangled, &temp); 1855 if (success) 1856 { 1857 string_appends (tname, &temp); 1858 } 1859 string_delete(&temp); 1860 if (!success) 1861 { 1862 break; 1863 } 1864 } 1865 need_comma = 1; 1866 } 1867 1868 } 1869 if (tname->p[-1] == '>') 1870 string_append (tname, " "); 1871 string_append (tname, "> class"); 1872 return (success); 1873 } 1874 1875 static int 1876 demangle_expression (struct work_stuff *work, const char **mangled, 1877 string *s, type_kind_t tk) 1878 { 1879 int need_operator = 0; 1880 int success; 1881 1882 success = 1; 1883 string_appendn (s, "(", 1); 1884 (*mangled)++; 1885 while (success && **mangled != 'W' && **mangled != '\0') 1886 { 1887 if (need_operator) 1888 { 1889 size_t i; 1890 size_t len; 1891 1892 success = 0; 1893 1894 len = strlen (*mangled); 1895 1896 for (i = 0; i < ARRAY_SIZE (optable); ++i) 1897 { 1898 size_t l = strlen (optable[i].in); 1899 1900 if (l <= len 1901 && memcmp (optable[i].in, *mangled, l) == 0) 1902 { 1903 string_appendn (s, " ", 1); 1904 string_append (s, optable[i].out); 1905 string_appendn (s, " ", 1); 1906 success = 1; 1907 (*mangled) += l; 1908 break; 1909 } 1910 } 1911 1912 if (!success) 1913 break; 1914 } 1915 else 1916 need_operator = 1; 1917 1918 success = demangle_template_value_parm (work, mangled, s, tk); 1919 } 1920 1921 if (**mangled != 'W') 1922 success = 0; 1923 else 1924 { 1925 string_appendn (s, ")", 1); 1926 (*mangled)++; 1927 } 1928 1929 return success; 1930 } 1931 1932 static int 1933 demangle_integral_value (struct work_stuff *work, 1934 const char **mangled, string *s) 1935 { 1936 int success; 1937 1938 if (**mangled == 'E') 1939 success = demangle_expression (work, mangled, s, tk_integral); 1940 else if (**mangled == 'Q' || **mangled == 'K') 1941 success = demangle_qualified (work, mangled, s, 0, 1); 1942 else 1943 { 1944 int value; 1945 1946 /* By default, we let the number decide whether we shall consume an 1947 underscore. */ 1948 int multidigit_without_leading_underscore = 0; 1949 int leave_following_underscore = 0; 1950 1951 success = 0; 1952 1953 if (**mangled == '_') 1954 { 1955 if (mangled[0][1] == 'm') 1956 { 1957 /* Since consume_count_with_underscores does not handle the 1958 `m'-prefix we must do it here, using consume_count and 1959 adjusting underscores: we have to consume the underscore 1960 matching the prepended one. */ 1961 multidigit_without_leading_underscore = 1; 1962 string_appendn (s, "-", 1); 1963 (*mangled) += 2; 1964 } 1965 else 1966 { 1967 /* Do not consume a following underscore; 1968 consume_count_with_underscores will consume what 1969 should be consumed. */ 1970 leave_following_underscore = 1; 1971 } 1972 } 1973 else 1974 { 1975 /* Negative numbers are indicated with a leading `m'. */ 1976 if (**mangled == 'm') 1977 { 1978 string_appendn (s, "-", 1); 1979 (*mangled)++; 1980 } 1981 /* Since consume_count_with_underscores does not handle 1982 multi-digit numbers that do not start with an underscore, 1983 and this number can be an integer template parameter, 1984 we have to call consume_count. */ 1985 multidigit_without_leading_underscore = 1; 1986 /* These multi-digit numbers never end on an underscore, 1987 so if there is one then don't eat it. */ 1988 leave_following_underscore = 1; 1989 } 1990 1991 /* We must call consume_count if we expect to remove a trailing 1992 underscore, since consume_count_with_underscores expects 1993 the leading underscore (that we consumed) if it is to handle 1994 multi-digit numbers. */ 1995 if (multidigit_without_leading_underscore) 1996 value = consume_count (mangled); 1997 else 1998 value = consume_count_with_underscores (mangled); 1999 2000 if (value != -1) 2001 { 2002 char buf[INTBUF_SIZE]; 2003 sprintf (buf, "%d", value); 2004 string_append (s, buf); 2005 2006 /* Numbers not otherwise delimited, might have an underscore 2007 appended as a delimiter, which we should skip. 2008 2009 ??? This used to always remove a following underscore, which 2010 is wrong. If other (arbitrary) cases are followed by an 2011 underscore, we need to do something more radical. */ 2012 2013 if ((value > 9 || multidigit_without_leading_underscore) 2014 && ! leave_following_underscore 2015 && **mangled == '_') 2016 (*mangled)++; 2017 2018 /* All is well. */ 2019 success = 1; 2020 } 2021 } 2022 2023 return success; 2024 } 2025 2026 /* Demangle the real value in MANGLED. */ 2027 2028 static int 2029 demangle_real_value (struct work_stuff *work, 2030 const char **mangled, string *s) 2031 { 2032 if (**mangled == 'E') 2033 return demangle_expression (work, mangled, s, tk_real); 2034 2035 if (**mangled == 'm') 2036 { 2037 string_appendn (s, "-", 1); 2038 (*mangled)++; 2039 } 2040 while (ISDIGIT ((unsigned char)**mangled)) 2041 { 2042 string_appendn (s, *mangled, 1); 2043 (*mangled)++; 2044 } 2045 if (**mangled == '.') /* fraction */ 2046 { 2047 string_appendn (s, ".", 1); 2048 (*mangled)++; 2049 while (ISDIGIT ((unsigned char)**mangled)) 2050 { 2051 string_appendn (s, *mangled, 1); 2052 (*mangled)++; 2053 } 2054 } 2055 if (**mangled == 'e') /* exponent */ 2056 { 2057 string_appendn (s, "e", 1); 2058 (*mangled)++; 2059 while (ISDIGIT ((unsigned char)**mangled)) 2060 { 2061 string_appendn (s, *mangled, 1); 2062 (*mangled)++; 2063 } 2064 } 2065 2066 return 1; 2067 } 2068 2069 static int 2070 demangle_template_value_parm (struct work_stuff *work, const char **mangled, 2071 string *s, type_kind_t tk) 2072 { 2073 int success = 1; 2074 2075 if (**mangled == 'Y') 2076 { 2077 /* The next argument is a template parameter. */ 2078 int idx; 2079 2080 (*mangled)++; 2081 idx = consume_count_with_underscores (mangled); 2082 if (idx == -1 2083 || (work->tmpl_argvec && idx >= work->ntmpl_args) 2084 || consume_count_with_underscores (mangled) == -1) 2085 return -1; 2086 if (work->tmpl_argvec) 2087 string_append (s, work->tmpl_argvec[idx]); 2088 else 2089 string_append_template_idx (s, idx); 2090 } 2091 else if (tk == tk_integral) 2092 success = demangle_integral_value (work, mangled, s); 2093 else if (tk == tk_char) 2094 { 2095 char tmp[2]; 2096 int val; 2097 if (**mangled == 'm') 2098 { 2099 string_appendn (s, "-", 1); 2100 (*mangled)++; 2101 } 2102 string_appendn (s, "'", 1); 2103 val = consume_count(mangled); 2104 if (val <= 0) 2105 success = 0; 2106 else 2107 { 2108 tmp[0] = (char)val; 2109 tmp[1] = '\0'; 2110 string_appendn (s, &tmp[0], 1); 2111 string_appendn (s, "'", 1); 2112 } 2113 } 2114 else if (tk == tk_bool) 2115 { 2116 int val = consume_count (mangled); 2117 if (val == 0) 2118 string_appendn (s, "false", 5); 2119 else if (val == 1) 2120 string_appendn (s, "true", 4); 2121 else 2122 success = 0; 2123 } 2124 else if (tk == tk_real) 2125 success = demangle_real_value (work, mangled, s); 2126 else if (tk == tk_pointer || tk == tk_reference 2127 || tk == tk_rvalue_reference) 2128 { 2129 if (**mangled == 'Q') 2130 success = demangle_qualified (work, mangled, s, 2131 /*isfuncname=*/0, 2132 /*append=*/1); 2133 else 2134 { 2135 int symbol_len = consume_count (mangled); 2136 if (symbol_len == -1 2137 || symbol_len > (long) strlen (*mangled)) 2138 return -1; 2139 if (symbol_len == 0) 2140 string_appendn (s, "0", 1); 2141 else 2142 { 2143 char *p = XNEWVEC (char, symbol_len + 1), *q; 2144 strncpy (p, *mangled, symbol_len); 2145 p [symbol_len] = '\0'; 2146 /* We use cplus_demangle here, rather than 2147 internal_cplus_demangle, because the name of the entity 2148 mangled here does not make use of any of the squangling 2149 or type-code information we have built up thus far; it is 2150 mangled independently. */ 2151 q = ML_(cplus_demangle) (p, work->options); 2152 if (tk == tk_pointer) 2153 string_appendn (s, "&", 1); 2154 /* FIXME: Pointer-to-member constants should get a 2155 qualifying class name here. */ 2156 if (q) 2157 { 2158 string_append (s, q); 2159 free (q); 2160 } 2161 else 2162 string_append (s, p); 2163 free (p); 2164 } 2165 *mangled += symbol_len; 2166 } 2167 } 2168 2169 return success; 2170 } 2171 2172 /* Demangle the template name in MANGLED. The full name of the 2173 template (e.g., S<int>) is placed in TNAME. The name without the 2174 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is 2175 non-NULL. If IS_TYPE is nonzero, this template is a type template, 2176 not a function template. If both IS_TYPE and REMEMBER are nonzero, 2177 the template is remembered in the list of back-referenceable 2178 types. */ 2179 2180 static int 2181 demangle_template (struct work_stuff *work, const char **mangled, 2182 string *tname, string *trawname, 2183 int is_type, int remember) 2184 { 2185 int i; 2186 int r; 2187 int need_comma = 0; 2188 int success = 0; 2189 int is_java_array = 0; 2190 string temp; 2191 2192 (*mangled)++; 2193 if (is_type) 2194 { 2195 /* get template name */ 2196 if (**mangled == 'z') 2197 { 2198 int idx; 2199 (*mangled)++; 2200 if (**mangled == '\0') 2201 return (0); 2202 (*mangled)++; 2203 2204 idx = consume_count_with_underscores (mangled); 2205 if (idx == -1 2206 || (work->tmpl_argvec && idx >= work->ntmpl_args) 2207 || consume_count_with_underscores (mangled) == -1) 2208 return (0); 2209 2210 if (work->tmpl_argvec) 2211 { 2212 string_append (tname, work->tmpl_argvec[idx]); 2213 if (trawname) 2214 string_append (trawname, work->tmpl_argvec[idx]); 2215 } 2216 else 2217 { 2218 string_append_template_idx (tname, idx); 2219 if (trawname) 2220 string_append_template_idx (trawname, idx); 2221 } 2222 } 2223 else 2224 { 2225 if ((r = consume_count (mangled)) <= 0 2226 || (int) strlen (*mangled) < r) 2227 { 2228 return (0); 2229 } 2230 is_java_array = (work -> options & DMGL_JAVA) 2231 && strncmp (*mangled, "JArray1Z", 8) == 0; 2232 if (! is_java_array) 2233 { 2234 string_appendn (tname, *mangled, r); 2235 } 2236 if (trawname) 2237 string_appendn (trawname, *mangled, r); 2238 *mangled += r; 2239 } 2240 } 2241 if (!is_java_array) 2242 string_append (tname, "<"); 2243 /* get size of template parameter list */ 2244 if (!get_count (mangled, &r)) 2245 { 2246 return (0); 2247 } 2248 if (!is_type) 2249 { 2250 /* Create an array for saving the template argument values. */ 2251 work->tmpl_argvec = XNEWVEC (char *, r); 2252 work->ntmpl_args = r; 2253 for (i = 0; i < r; i++) 2254 work->tmpl_argvec[i] = 0; 2255 } 2256 for (i = 0; i < r; i++) 2257 { 2258 if (need_comma) 2259 { 2260 string_append (tname, ", "); 2261 } 2262 /* Z for type parameters */ 2263 if (**mangled == 'Z') 2264 { 2265 (*mangled)++; 2266 /* temp is initialized in do_type */ 2267 success = do_type (work, mangled, &temp); 2268 if (success) 2269 { 2270 string_appends (tname, &temp); 2271 2272 if (!is_type) 2273 { 2274 /* Save the template argument. */ 2275 int len = temp.p - temp.b; 2276 work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2277 memcpy (work->tmpl_argvec[i], temp.b, len); 2278 work->tmpl_argvec[i][len] = '\0'; 2279 } 2280 } 2281 string_delete(&temp); 2282 if (!success) 2283 { 2284 break; 2285 } 2286 } 2287 /* z for template parameters */ 2288 else if (**mangled == 'z') 2289 { 2290 int r2; 2291 (*mangled)++; 2292 success = demangle_template_template_parm (work, mangled, tname); 2293 2294 if (success 2295 && (r2 = consume_count (mangled)) > 0 2296 && (int) strlen (*mangled) >= r2) 2297 { 2298 string_append (tname, " "); 2299 string_appendn (tname, *mangled, r2); 2300 if (!is_type) 2301 { 2302 /* Save the template argument. */ 2303 int len = r2; 2304 work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2305 memcpy (work->tmpl_argvec[i], *mangled, len); 2306 work->tmpl_argvec[i][len] = '\0'; 2307 } 2308 *mangled += r2; 2309 } 2310 if (!success) 2311 { 2312 break; 2313 } 2314 } 2315 else 2316 { 2317 string param; 2318 string* s; 2319 2320 /* otherwise, value parameter */ 2321 2322 /* temp is initialized in do_type */ 2323 success = do_type (work, mangled, &temp); 2324 string_delete(&temp); 2325 if (!success) 2326 break; 2327 2328 if (!is_type) 2329 { 2330 s = ¶m; 2331 string_init (s); 2332 } 2333 else 2334 s = tname; 2335 2336 success = demangle_template_value_parm (work, mangled, s, 2337 (type_kind_t) success); 2338 2339 if (!success) 2340 { 2341 if (!is_type) 2342 string_delete (s); 2343 success = 0; 2344 break; 2345 } 2346 2347 if (!is_type) 2348 { 2349 int len = s->p - s->b; 2350 work->tmpl_argvec[i] = XNEWVEC (char, len + 1); 2351 memcpy (work->tmpl_argvec[i], s->b, len); 2352 work->tmpl_argvec[i][len] = '\0'; 2353 2354 string_appends (tname, s); 2355 string_delete (s); 2356 } 2357 } 2358 need_comma = 1; 2359 } 2360 if (is_java_array) 2361 { 2362 string_append (tname, "[]"); 2363 } 2364 else 2365 { 2366 if (tname->p[-1] == '>') 2367 string_append (tname, " "); 2368 string_append (tname, ">"); 2369 } 2370 2371 if (is_type && remember) 2372 { 2373 const int bindex = register_Btype (work); 2374 remember_Btype (work, tname->b, LEN_STRING (tname), bindex); 2375 } 2376 2377 /* 2378 if (work -> static_type) 2379 { 2380 string_append (declp, *mangled + 1); 2381 *mangled += strlen (*mangled); 2382 success = 1; 2383 } 2384 else 2385 { 2386 success = demangle_args (work, mangled, declp); 2387 } 2388 } 2389 */ 2390 return (success); 2391 } 2392 2393 static int 2394 arm_pt (const char *mangled, 2395 int n, const char **anchor, const char **args) 2396 { 2397 /* Check if ARM template with "__pt__" in it ("parameterized type") */ 2398 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ 2399 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__"))) 2400 { 2401 int len; 2402 *args = *anchor + 6; 2403 len = consume_count (args); 2404 if (len == -1) 2405 return 0; 2406 if (*args + len == mangled + n && **args == '_') 2407 { 2408 ++*args; 2409 return 1; 2410 } 2411 } 2412 if (AUTO_DEMANGLING || EDG_DEMANGLING) 2413 { 2414 if ((*anchor = strstr (mangled, "__tm__")) 2415 || (*anchor = strstr (mangled, "__ps__")) 2416 || (*anchor = strstr (mangled, "__pt__"))) 2417 { 2418 int len; 2419 *args = *anchor + 6; 2420 len = consume_count (args); 2421 if (len == -1) 2422 return 0; 2423 if (*args + len == mangled + n && **args == '_') 2424 { 2425 ++*args; 2426 return 1; 2427 } 2428 } 2429 else if ((*anchor = strstr (mangled, "__S"))) 2430 { 2431 int len; 2432 *args = *anchor + 3; 2433 len = consume_count (args); 2434 if (len == -1) 2435 return 0; 2436 if (*args + len == mangled + n && **args == '_') 2437 { 2438 ++*args; 2439 return 1; 2440 } 2441 } 2442 } 2443 2444 return 0; 2445 } 2446 2447 static void 2448 demangle_arm_hp_template (struct work_stuff *work, const char **mangled, 2449 int n, string *declp) 2450 { 2451 const char *p; 2452 const char *args; 2453 const char *e = *mangled + n; 2454 string arg; 2455 2456 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are 2457 template args */ 2458 if (HP_DEMANGLING && ((*mangled)[n] == 'X')) 2459 { 2460 char *start_spec_args = NULL; 2461 int hold_options; 2462 2463 /* First check for and omit template specialization pseudo-arguments, 2464 such as in "Spec<#1,#1.*>" */ 2465 start_spec_args = strchr (*mangled, '<'); 2466 if (start_spec_args && (start_spec_args - *mangled < n)) 2467 string_appendn (declp, *mangled, start_spec_args - *mangled); 2468 else 2469 string_appendn (declp, *mangled, n); 2470 (*mangled) += n + 1; 2471 string_init (&arg); 2472 if (work->temp_start == -1) /* non-recursive call */ 2473 work->temp_start = declp->p - declp->b; 2474 2475 /* We want to unconditionally demangle parameter types in 2476 template parameters. */ 2477 hold_options = work->options; 2478 work->options |= DMGL_PARAMS; 2479 2480 string_append (declp, "<"); 2481 while (1) 2482 { 2483 string_delete (&arg); 2484 switch (**mangled) 2485 { 2486 case 'T': 2487 /* 'T' signals a type parameter */ 2488 (*mangled)++; 2489 if (!do_type (work, mangled, &arg)) 2490 goto hpacc_template_args_done; 2491 break; 2492 2493 case 'U': 2494 case 'S': 2495 /* 'U' or 'S' signals an integral value */ 2496 if (!do_hpacc_template_const_value (work, mangled, &arg)) 2497 goto hpacc_template_args_done; 2498 break; 2499 2500 case 'A': 2501 /* 'A' signals a named constant expression (literal) */ 2502 if (!do_hpacc_template_literal (work, mangled, &arg)) 2503 goto hpacc_template_args_done; 2504 break; 2505 2506 default: 2507 /* Today, 1997-09-03, we have only the above types 2508 of template parameters */ 2509 /* FIXME: maybe this should fail and return null */ 2510 goto hpacc_template_args_done; 2511 } 2512 string_appends (declp, &arg); 2513 /* Check if we're at the end of template args. 2514 0 if at end of static member of template class, 2515 _ if done with template args for a function */ 2516 if ((**mangled == '\000') || (**mangled == '_')) 2517 break; 2518 else 2519 string_append (declp, ","); 2520 } 2521 hpacc_template_args_done: 2522 string_append (declp, ">"); 2523 string_delete (&arg); 2524 if (**mangled == '_') 2525 (*mangled)++; 2526 work->options = hold_options; 2527 return; 2528 } 2529 /* ARM template? (Also handles HP cfront extensions) */ 2530 else if (arm_pt (*mangled, n, &p, &args)) 2531 { 2532 int hold_options; 2533 string type_str; 2534 2535 string_init (&arg); 2536 string_appendn (declp, *mangled, p - *mangled); 2537 if (work->temp_start == -1) /* non-recursive call */ 2538 work->temp_start = declp->p - declp->b; 2539 2540 /* We want to unconditionally demangle parameter types in 2541 template parameters. */ 2542 hold_options = work->options; 2543 work->options |= DMGL_PARAMS; 2544 2545 string_append (declp, "<"); 2546 /* should do error checking here */ 2547 while (args < e) { 2548 string_delete (&arg); 2549 2550 /* Check for type or literal here */ 2551 switch (*args) 2552 { 2553 /* HP cfront extensions to ARM for template args */ 2554 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ 2555 /* FIXME: We handle only numeric literals for HP cfront */ 2556 case 'X': 2557 /* A typed constant value follows */ 2558 args++; 2559 if (!do_type (work, &args, &type_str)) 2560 goto cfront_template_args_done; 2561 string_append (&arg, "("); 2562 string_appends (&arg, &type_str); 2563 string_delete (&type_str); 2564 string_append (&arg, ")"); 2565 if (*args != 'L') 2566 goto cfront_template_args_done; 2567 args++; 2568 /* Now snarf a literal value following 'L' */ 2569 if (!snarf_numeric_literal (&args, &arg)) 2570 goto cfront_template_args_done; 2571 break; 2572 2573 case 'L': 2574 /* Snarf a literal following 'L' */ 2575 args++; 2576 if (!snarf_numeric_literal (&args, &arg)) 2577 goto cfront_template_args_done; 2578 break; 2579 default: 2580 /* Not handling other HP cfront stuff */ 2581 { 2582 const char* old_args = args; 2583 if (!do_type (work, &args, &arg)) 2584 goto cfront_template_args_done; 2585 2586 /* Fail if we didn't make any progress: prevent infinite loop. */ 2587 if (args == old_args) 2588 { 2589 work->options = hold_options; 2590 return; 2591 } 2592 } 2593 } 2594 string_appends (declp, &arg); 2595 string_append (declp, ","); 2596 } 2597 cfront_template_args_done: 2598 string_delete (&arg); 2599 if (args >= e) 2600 --declp->p; /* remove extra comma */ 2601 string_append (declp, ">"); 2602 work->options = hold_options; 2603 } 2604 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 2605 && (*mangled)[9] == 'N' 2606 && (*mangled)[8] == (*mangled)[10] 2607 && strchr (cplus_markers, (*mangled)[8])) 2608 { 2609 /* A member of the anonymous namespace. */ 2610 string_append (declp, "{anonymous}"); 2611 } 2612 else 2613 { 2614 if (work->temp_start == -1) /* non-recursive call only */ 2615 work->temp_start = 0; /* disable in recursive calls */ 2616 string_appendn (declp, *mangled, n); 2617 } 2618 *mangled += n; 2619 } 2620 2621 /* Extract a class name, possibly a template with arguments, from the 2622 mangled string; qualifiers, local class indicators, etc. have 2623 already been dealt with */ 2624 2625 static int 2626 demangle_class_name (struct work_stuff *work, const char **mangled, 2627 string *declp) 2628 { 2629 int n; 2630 int success = 0; 2631 2632 n = consume_count (mangled); 2633 if (n == -1) 2634 return 0; 2635 if ((int) strlen (*mangled) >= n) 2636 { 2637 demangle_arm_hp_template (work, mangled, n, declp); 2638 success = 1; 2639 } 2640 2641 return (success); 2642 } 2643 2644 /* 2645 2646 LOCAL FUNCTION 2647 2648 demangle_class -- demangle a mangled class sequence 2649 2650 SYNOPSIS 2651 2652 static int 2653 demangle_class (struct work_stuff *work, const char **mangled, 2654 strint *declp) 2655 2656 DESCRIPTION 2657 2658 DECLP points to the buffer into which demangling is being done. 2659 2660 *MANGLED points to the current token to be demangled. On input, 2661 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) 2662 On exit, it points to the next token after the mangled class on 2663 success, or the first unconsumed token on failure. 2664 2665 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then 2666 we are demangling a constructor or destructor. In this case 2667 we prepend "class::class" or "class::~class" to DECLP. 2668 2669 Otherwise, we prepend "class::" to the current DECLP. 2670 2671 Reset the constructor/destructor flags once they have been 2672 "consumed". This allows demangle_class to be called later during 2673 the same demangling, to do normal class demangling. 2674 2675 Returns 1 if demangling is successful, 0 otherwise. 2676 2677 */ 2678 2679 static int 2680 demangle_class (struct work_stuff *work, const char **mangled, string *declp) 2681 { 2682 int success = 0; 2683 int btype; 2684 string class_name; 2685 char *save_class_name_end = 0; 2686 2687 string_init (&class_name); 2688 btype = register_Btype (work); 2689 if (demangle_class_name (work, mangled, &class_name)) 2690 { 2691 save_class_name_end = class_name.p; 2692 if ((work->constructor & 1) || (work->destructor & 1)) 2693 { 2694 /* adjust so we don't include template args */ 2695 if (work->temp_start && (work->temp_start != -1)) 2696 { 2697 class_name.p = class_name.b + work->temp_start; 2698 } 2699 string_prepends (declp, &class_name); 2700 if (work -> destructor & 1) 2701 { 2702 string_prepend (declp, "~"); 2703 work -> destructor -= 1; 2704 } 2705 else 2706 { 2707 work -> constructor -= 1; 2708 } 2709 } 2710 class_name.p = save_class_name_end; 2711 remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); 2712 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); 2713 string_prepend (declp, SCOPE_STRING (work)); 2714 string_prepends (declp, &class_name); 2715 success = 1; 2716 } 2717 string_delete (&class_name); 2718 return (success); 2719 } 2720 2721 2722 /* Called when there's a "__" in the mangled name, with `scan' pointing to 2723 the rightmost guess. 2724 2725 Find the correct "__"-sequence where the function name ends and the 2726 signature starts, which is ambiguous with GNU mangling. 2727 Call demangle_signature here, so we can make sure we found the right 2728 one; *mangled will be consumed so caller will not make further calls to 2729 demangle_signature. */ 2730 2731 static int 2732 iterate_demangle_function (struct work_stuff *work, const char **mangled, 2733 string *declp, const char *scan) 2734 { 2735 const char *mangle_init = *mangled; 2736 int success = 0; 2737 string decl_init; 2738 struct work_stuff work_init; 2739 2740 if (*(scan + 2) == '\0') 2741 return 0; 2742 2743 /* Do not iterate for some demangling modes, or if there's only one 2744 "__"-sequence. This is the normal case. */ 2745 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING 2746 || strstr (scan + 2, "__") == NULL) 2747 return demangle_function_name (work, mangled, declp, scan); 2748 2749 /* Save state so we can restart if the guess at the correct "__" was 2750 wrong. */ 2751 string_init (&decl_init); 2752 string_appends (&decl_init, declp); 2753 memset (&work_init, 0, sizeof work_init); 2754 work_stuff_copy_to_from (&work_init, work); 2755 2756 /* Iterate over occurrences of __, allowing names and types to have a 2757 "__" sequence in them. We must start with the first (not the last) 2758 occurrence, since "__" most often occur between independent mangled 2759 parts, hence starting at the last occurrence inside a signature 2760 might get us a "successful" demangling of the signature. */ 2761 2762 while (scan[2]) 2763 { 2764 if (demangle_function_name (work, mangled, declp, scan)) 2765 { 2766 success = demangle_signature (work, mangled, declp); 2767 if (success) 2768 break; 2769 } 2770 2771 /* Reset demangle state for the next round. */ 2772 *mangled = mangle_init; 2773 string_clear (declp); 2774 string_appends (declp, &decl_init); 2775 work_stuff_copy_to_from (work, &work_init); 2776 2777 /* Leave this underscore-sequence. */ 2778 scan += 2; 2779 2780 /* Scan for the next "__" sequence. */ 2781 while (*scan && (scan[0] != '_' || scan[1] != '_')) 2782 scan++; 2783 2784 /* Move to last "__" in this sequence. */ 2785 while (*scan && *scan == '_') 2786 scan++; 2787 scan -= 2; 2788 } 2789 2790 /* Delete saved state. */ 2791 delete_work_stuff (&work_init); 2792 string_delete (&decl_init); 2793 2794 return success; 2795 } 2796 2797 /* 2798 2799 LOCAL FUNCTION 2800 2801 demangle_prefix -- consume the mangled name prefix and find signature 2802 2803 SYNOPSIS 2804 2805 static int 2806 demangle_prefix (struct work_stuff *work, const char **mangled, 2807 string *declp); 2808 2809 DESCRIPTION 2810 2811 Consume and demangle the prefix of the mangled name. 2812 While processing the function name root, arrange to call 2813 demangle_signature if the root is ambiguous. 2814 2815 DECLP points to the string buffer into which demangled output is 2816 placed. On entry, the buffer is empty. On exit it contains 2817 the root function name, the demangled operator name, or in some 2818 special cases either nothing or the completely demangled result. 2819 2820 MANGLED points to the current pointer into the mangled name. As each 2821 token of the mangled name is consumed, it is updated. Upon entry 2822 the current mangled name pointer points to the first character of 2823 the mangled name. Upon exit, it should point to the first character 2824 of the signature if demangling was successful, or to the first 2825 unconsumed character if demangling of the prefix was unsuccessful. 2826 2827 Returns 1 on success, 0 otherwise. 2828 */ 2829 2830 static int 2831 demangle_prefix (struct work_stuff *work, const char **mangled, 2832 string *declp) 2833 { 2834 int success = 1; 2835 const char *scan; 2836 int i; 2837 2838 if (strlen(*mangled) > 6 2839 && (strncmp(*mangled, "_imp__", 6) == 0 2840 || strncmp(*mangled, "__imp_", 6) == 0)) 2841 { 2842 /* it's a symbol imported from a PE dynamic library. Check for both 2843 new style prefix _imp__ and legacy __imp_ used by older versions 2844 of dlltool. */ 2845 (*mangled) += 6; 2846 work->dllimported = 1; 2847 } 2848 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) 2849 { 2850 char *marker = strchr (cplus_markers, (*mangled)[8]); 2851 if (marker != NULL && *marker == (*mangled)[10]) 2852 { 2853 if ((*mangled)[9] == 'D') 2854 { 2855 /* it's a GNU global destructor to be executed at program exit */ 2856 (*mangled) += 11; 2857 work->destructor = 2; 2858 if (gnu_special (work, mangled, declp)) 2859 return success; 2860 } 2861 else if ((*mangled)[9] == 'I') 2862 { 2863 /* it's a GNU global constructor to be executed at program init */ 2864 (*mangled) += 11; 2865 work->constructor = 2; 2866 if (gnu_special (work, mangled, declp)) 2867 return success; 2868 } 2869 } 2870 } 2871 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0) 2872 { 2873 /* it's a ARM global destructor to be executed at program exit */ 2874 (*mangled) += 7; 2875 work->destructor = 2; 2876 } 2877 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0) 2878 { 2879 /* it's a ARM global constructor to be executed at program initial */ 2880 (*mangled) += 7; 2881 work->constructor = 2; 2882 } 2883 2884 /* This block of code is a reduction in strength time optimization 2885 of: 2886 scan = strstr (*mangled, "__"); */ 2887 2888 { 2889 scan = *mangled; 2890 2891 do { 2892 scan = strchr (scan, '_'); 2893 } while (scan != NULL && *++scan != '_'); 2894 2895 if (scan != NULL) --scan; 2896 } 2897 2898 if (scan != NULL) 2899 { 2900 /* We found a sequence of two or more '_', ensure that we start at 2901 the last pair in the sequence. */ 2902 i = strspn (scan, "_"); 2903 if (i > 2) 2904 { 2905 scan += (i - 2); 2906 } 2907 } 2908 2909 if (scan == NULL) 2910 { 2911 success = 0; 2912 } 2913 else if (work -> static_type) 2914 { 2915 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't')) 2916 { 2917 success = 0; 2918 } 2919 } 2920 else if ((scan == *mangled) 2921 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q') 2922 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) 2923 { 2924 /* The ARM says nothing about the mangling of local variables. 2925 But cfront mangles local variables by prepending __<nesting_level> 2926 to them. As an extension to ARM demangling we handle this case. */ 2927 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) 2928 && ISDIGIT ((unsigned char)scan[2])) 2929 { 2930 *mangled = scan + 2; 2931 consume_count (mangled); 2932 string_append (declp, *mangled); 2933 *mangled += strlen (*mangled); 2934 success = 1; 2935 } 2936 else 2937 { 2938 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses 2939 names like __Q2_3foo3bar for nested type names. So don't accept 2940 this style of constructor for cfront demangling. A GNU 2941 style member-template constructor starts with 'H'. */ 2942 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)) 2943 work -> constructor += 1; 2944 *mangled = scan + 2; 2945 } 2946 } 2947 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') 2948 { 2949 /* Cfront-style parameterized type. Handled later as a signature. */ 2950 success = 1; 2951 2952 /* ARM template? */ 2953 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); 2954 } 2955 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm') 2956 || (scan[2] == 'p' && scan[3] == 's') 2957 || (scan[2] == 'p' && scan[3] == 't'))) 2958 { 2959 /* EDG-style parameterized type. Handled later as a signature. */ 2960 success = 1; 2961 2962 /* EDG template? */ 2963 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); 2964 } 2965 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2]) 2966 && (scan[2] != 't')) 2967 { 2968 /* Mangled name starts with "__". Skip over any leading '_' characters, 2969 then find the next "__" that separates the prefix from the signature. 2970 */ 2971 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 2972 || (arm_special (mangled, declp) == 0)) 2973 { 2974 while (*scan == '_') 2975 { 2976 scan++; 2977 } 2978 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) 2979 { 2980 /* No separator (I.E. "__not_mangled"), or empty signature 2981 (I.E. "__not_mangled_either__") */ 2982 success = 0; 2983 } 2984 else 2985 return iterate_demangle_function (work, mangled, declp, scan); 2986 } 2987 } 2988 else if (*(scan + 2) != '\0') 2989 { 2990 /* Mangled name does not start with "__" but does have one somewhere 2991 in there with non empty stuff after it. Looks like a global 2992 function name. Iterate over all "__":s until the right 2993 one is found. */ 2994 return iterate_demangle_function (work, mangled, declp, scan); 2995 } 2996 else 2997 { 2998 /* Doesn't look like a mangled name */ 2999 success = 0; 3000 } 3001 3002 if (!success && (work->constructor == 2 || work->destructor == 2)) 3003 { 3004 string_append (declp, *mangled); 3005 *mangled += strlen (*mangled); 3006 success = 1; 3007 } 3008 return (success); 3009 } 3010 3011 /* 3012 3013 LOCAL FUNCTION 3014 3015 gnu_special -- special handling of gnu mangled strings 3016 3017 SYNOPSIS 3018 3019 static int 3020 gnu_special (struct work_stuff *work, const char **mangled, 3021 string *declp); 3022 3023 3024 DESCRIPTION 3025 3026 Process some special GNU style mangling forms that don't fit 3027 the normal pattern. For example: 3028 3029 _$_3foo (destructor for class foo) 3030 _vt$foo (foo virtual table) 3031 _vt$foo$bar (foo::bar virtual table) 3032 __vt_foo (foo virtual table, new style with thunks) 3033 _3foo$varname (static data member) 3034 _Q22rs2tu$vw (static data member) 3035 __t6vector1Zii (constructor with template) 3036 __thunk_4__$_7ostream (virtual function thunk) 3037 */ 3038 3039 static int 3040 gnu_special (struct work_stuff *work, const char **mangled, string *declp) 3041 { 3042 int n; 3043 int success = 1; 3044 const char *p; 3045 3046 if ((*mangled)[0] == '_' && (*mangled)[1] != '\0' 3047 && strchr (cplus_markers, (*mangled)[1]) != NULL 3048 && (*mangled)[2] == '_') 3049 { 3050 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */ 3051 (*mangled) += 3; 3052 work -> destructor += 1; 3053 } 3054 else if ((*mangled)[0] == '_' 3055 && (((*mangled)[1] == '_' 3056 && (*mangled)[2] == 'v' 3057 && (*mangled)[3] == 't' 3058 && (*mangled)[4] == '_') 3059 || ((*mangled)[1] == 'v' 3060 && (*mangled)[2] == 't' && (*mangled)[3] != '\0' 3061 && strchr (cplus_markers, (*mangled)[3]) != NULL))) 3062 { 3063 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>" 3064 and create the decl. Note that we consume the entire mangled 3065 input string, which means that demangle_signature has no work 3066 to do. */ 3067 if ((*mangled)[2] == 'v') 3068 (*mangled) += 5; /* New style, with thunks: "__vt_" */ 3069 else 3070 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */ 3071 while (**mangled != '\0') 3072 { 3073 switch (**mangled) 3074 { 3075 case 'Q': 3076 case 'K': 3077 success = demangle_qualified (work, mangled, declp, 0, 1); 3078 break; 3079 case 't': 3080 success = demangle_template (work, mangled, declp, 0, 1, 3081 1); 3082 break; 3083 default: 3084 if (ISDIGIT((unsigned char)*mangled[0])) 3085 { 3086 n = consume_count(mangled); 3087 /* We may be seeing a too-large size, or else a 3088 ".<digits>" indicating a static local symbol. In 3089 any case, declare victory and move on; *don't* try 3090 to use n to allocate. */ 3091 if (n > (int) strlen (*mangled)) 3092 { 3093 success = 1; 3094 break; 3095 } 3096 else if (n == -1) 3097 { 3098 success = 0; 3099 break; 3100 } 3101 } 3102 else 3103 { 3104 n = strcspn (*mangled, cplus_markers); 3105 } 3106 string_appendn (declp, *mangled, n); 3107 (*mangled) += n; 3108 } 3109 3110 p = strpbrk (*mangled, cplus_markers); 3111 if (success && ((p == NULL) || (p == *mangled))) 3112 { 3113 if (p != NULL) 3114 { 3115 string_append (declp, SCOPE_STRING (work)); 3116 (*mangled)++; 3117 } 3118 } 3119 else 3120 { 3121 success = 0; 3122 break; 3123 } 3124 } 3125 if (success) 3126 string_append (declp, " virtual table"); 3127 } 3128 else if ((*mangled)[0] == '_' 3129 && (strchr("0123456789Qt", (*mangled)[1]) != NULL) 3130 && (p = strpbrk (*mangled, cplus_markers)) != NULL) 3131 { 3132 /* static data member, "_3foo$varname" for example */ 3133 (*mangled)++; 3134 switch (**mangled) 3135 { 3136 case 'Q': 3137 case 'K': 3138 success = demangle_qualified (work, mangled, declp, 0, 1); 3139 break; 3140 case 't': 3141 success = demangle_template (work, mangled, declp, 0, 1, 1); 3142 break; 3143 default: 3144 n = consume_count (mangled); 3145 if (n < 0 || n > (long) strlen (*mangled)) 3146 { 3147 success = 0; 3148 break; 3149 } 3150 3151 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 3152 && (*mangled)[9] == 'N' 3153 && (*mangled)[8] == (*mangled)[10] 3154 && strchr (cplus_markers, (*mangled)[8])) 3155 { 3156 /* A member of the anonymous namespace. There's information 3157 about what identifier or filename it was keyed to, but 3158 it's just there to make the mangled name unique; we just 3159 step over it. */ 3160 string_append (declp, "{anonymous}"); 3161 (*mangled) += n; 3162 3163 /* Now p points to the marker before the N, so we need to 3164 update it to the first marker after what we consumed. */ 3165 p = strpbrk (*mangled, cplus_markers); 3166 break; 3167 } 3168 3169 string_appendn (declp, *mangled, n); 3170 (*mangled) += n; 3171 } 3172 if (success && (p == *mangled)) 3173 { 3174 /* Consumed everything up to the cplus_marker, append the 3175 variable name. */ 3176 (*mangled)++; 3177 string_append (declp, SCOPE_STRING (work)); 3178 n = strlen (*mangled); 3179 string_appendn (declp, *mangled, n); 3180 (*mangled) += n; 3181 } 3182 else 3183 { 3184 success = 0; 3185 } 3186 } 3187 else if (strncmp (*mangled, "__thunk_", 8) == 0) 3188 { 3189 int delta; 3190 3191 (*mangled) += 8; 3192 delta = consume_count (mangled); 3193 if (delta == -1) 3194 success = 0; 3195 else 3196 { 3197 char *method = internal_cplus_demangle (work, ++*mangled); 3198 3199 if (method) 3200 { 3201 char buf[50]; 3202 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); 3203 string_append (declp, buf); 3204 string_append (declp, method); 3205 free (method); 3206 n = strlen (*mangled); 3207 (*mangled) += n; 3208 } 3209 else 3210 { 3211 success = 0; 3212 } 3213 } 3214 } 3215 else if (strncmp (*mangled, "__t", 3) == 0 3216 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) 3217 { 3218 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; 3219 (*mangled) += 4; 3220 switch (**mangled) 3221 { 3222 case 'Q': 3223 case 'K': 3224 success = demangle_qualified (work, mangled, declp, 0, 1); 3225 break; 3226 case 't': 3227 success = demangle_template (work, mangled, declp, 0, 1, 1); 3228 break; 3229 default: 3230 success = do_type (work, mangled, declp); 3231 break; 3232 } 3233 if (success && **mangled != '\0') 3234 success = 0; 3235 if (success) 3236 string_append (declp, p); 3237 } 3238 else 3239 { 3240 success = 0; 3241 } 3242 return (success); 3243 } 3244 3245 static void 3246 recursively_demangle(struct work_stuff *work, const char **mangled, 3247 string *result, int namelength) 3248 { 3249 char * recurse = (char *)NULL; 3250 char * recurse_dem = (char *)NULL; 3251 3252 recurse = XNEWVEC (char, namelength + 1); 3253 memcpy (recurse, *mangled, namelength); 3254 recurse[namelength] = '\000'; 3255 3256 recurse_dem = ML_(cplus_demangle) (recurse, work->options); 3257 3258 if (recurse_dem) 3259 { 3260 string_append (result, recurse_dem); 3261 free (recurse_dem); 3262 } 3263 else 3264 { 3265 string_appendn (result, *mangled, namelength); 3266 } 3267 free (recurse); 3268 *mangled += namelength; 3269 } 3270 3271 /* 3272 3273 LOCAL FUNCTION 3274 3275 arm_special -- special handling of ARM/lucid mangled strings 3276 3277 SYNOPSIS 3278 3279 static int 3280 arm_special (const char **mangled, 3281 string *declp); 3282 3283 3284 DESCRIPTION 3285 3286 Process some special ARM style mangling forms that don't fit 3287 the normal pattern. For example: 3288 3289 __vtbl__3foo (foo virtual table) 3290 __vtbl__3foo__3bar (bar::foo virtual table) 3291 3292 */ 3293 3294 static int 3295 arm_special (const char **mangled, string *declp) 3296 { 3297 int n; 3298 int success = 1; 3299 const char *scan; 3300 3301 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) 3302 { 3303 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING 3304 and create the decl. Note that we consume the entire mangled 3305 input string, which means that demangle_signature has no work 3306 to do. */ 3307 scan = *mangled + ARM_VTABLE_STRLEN; 3308 while (*scan != '\0') /* first check it can be demangled */ 3309 { 3310 n = consume_count (&scan); 3311 if (n == -1) 3312 { 3313 return (0); /* no good */ 3314 } 3315 scan += n; 3316 if (scan[0] == '_' && scan[1] == '_') 3317 { 3318 scan += 2; 3319 } 3320 } 3321 (*mangled) += ARM_VTABLE_STRLEN; 3322 while (**mangled != '\0') 3323 { 3324 n = consume_count (mangled); 3325 if (n == -1 3326 || n > (long) strlen (*mangled)) 3327 return 0; 3328 string_prependn (declp, *mangled, n); 3329 (*mangled) += n; 3330 if ((*mangled)[0] == '_' && (*mangled)[1] == '_') 3331 { 3332 string_prepend (declp, "::"); 3333 (*mangled) += 2; 3334 } 3335 } 3336 string_append (declp, " virtual table"); 3337 } 3338 else 3339 { 3340 success = 0; 3341 } 3342 return (success); 3343 } 3344 3345 /* 3346 3347 LOCAL FUNCTION 3348 3349 demangle_qualified -- demangle 'Q' qualified name strings 3350 3351 SYNOPSIS 3352 3353 static int 3354 demangle_qualified (struct work_stuff *, const char *mangled, 3355 string *result, int isfuncname, int append); 3356 3357 DESCRIPTION 3358 3359 Demangle a qualified name, such as "Q25Outer5Inner" which is 3360 the mangled form of "Outer::Inner". The demangled output is 3361 prepended or appended to the result string according to the 3362 state of the append flag. 3363 3364 If isfuncname is nonzero, then the qualified name we are building 3365 is going to be used as a member function name, so if it is a 3366 constructor or destructor function, append an appropriate 3367 constructor or destructor name. I.E. for the above example, 3368 the result for use as a constructor is "Outer::Inner::Inner" 3369 and the result for use as a destructor is "Outer::Inner::~Inner". 3370 3371 BUGS 3372 3373 Numeric conversion is ASCII dependent (FIXME). 3374 3375 */ 3376 3377 static int 3378 demangle_qualified (struct work_stuff *work, const char **mangled, 3379 string *result, int isfuncname, int append) 3380 { 3381 int qualifiers = 0; 3382 int success = 1; 3383 char num[2]; 3384 string temp; 3385 string last_name; 3386 int bindex = register_Btype (work); 3387 3388 /* We only make use of ISFUNCNAME if the entity is a constructor or 3389 destructor. */ 3390 isfuncname = (isfuncname 3391 && ((work->constructor & 1) || (work->destructor & 1))); 3392 3393 string_init (&temp); 3394 string_init (&last_name); 3395 3396 if ((*mangled)[0] == 'K') 3397 { 3398 /* Squangling qualified name reuse */ 3399 int idx; 3400 (*mangled)++; 3401 idx = consume_count_with_underscores (mangled); 3402 if (idx == -1 || idx >= work -> numk) 3403 success = 0; 3404 else 3405 string_append (&temp, work -> ktypevec[idx]); 3406 } 3407 else 3408 switch ((*mangled)[1]) 3409 { 3410 case '_': 3411 /* GNU mangled name with more than 9 classes. The count is preceded 3412 by an underscore (to distinguish it from the <= 9 case) and followed 3413 by an underscore. */ 3414 (*mangled)++; 3415 qualifiers = consume_count_with_underscores (mangled); 3416 if (qualifiers == -1) 3417 success = 0; 3418 break; 3419 3420 case '1': 3421 case '2': 3422 case '3': 3423 case '4': 3424 case '5': 3425 case '6': 3426 case '7': 3427 case '8': 3428 case '9': 3429 /* The count is in a single digit. */ 3430 num[0] = (*mangled)[1]; 3431 num[1] = '\0'; 3432 qualifiers = atoi (num); 3433 3434 /* If there is an underscore after the digit, skip it. This is 3435 said to be for ARM-qualified names, but the ARM makes no 3436 mention of such an underscore. Perhaps cfront uses one. */ 3437 if ((*mangled)[2] == '_') 3438 { 3439 (*mangled)++; 3440 } 3441 (*mangled) += 2; 3442 break; 3443 3444 case '0': 3445 default: 3446 success = 0; 3447 } 3448 3449 if (!success) 3450 return success; 3451 3452 /* Pick off the names and collect them in the temp buffer in the order 3453 in which they are found, separated by '::'. */ 3454 3455 while (qualifiers-- > 0) 3456 { 3457 int remember_K = 1; 3458 string_clear (&last_name); 3459 3460 if (*mangled[0] == '_') 3461 (*mangled)++; 3462 3463 if (*mangled[0] == 't') 3464 { 3465 /* Here we always append to TEMP since we will want to use 3466 the template name without the template parameters as a 3467 constructor or destructor name. The appropriate 3468 (parameter-less) value is returned by demangle_template 3469 in LAST_NAME. We do not remember the template type here, 3470 in order to match the G++ mangling algorithm. */ 3471 success = demangle_template(work, mangled, &temp, 3472 &last_name, 1, 0); 3473 if (!success) 3474 break; 3475 } 3476 else if (*mangled[0] == 'K') 3477 { 3478 int idx; 3479 (*mangled)++; 3480 idx = consume_count_with_underscores (mangled); 3481 if (idx == -1 || idx >= work->numk) 3482 success = 0; 3483 else 3484 string_append (&temp, work->ktypevec[idx]); 3485 remember_K = 0; 3486 3487 if (!success) break; 3488 } 3489 else 3490 { 3491 if (EDG_DEMANGLING) 3492 { 3493 int namelength; 3494 /* Now recursively demangle the qualifier 3495 * This is necessary to deal with templates in 3496 * mangling styles like EDG */ 3497 namelength = consume_count (mangled); 3498 if (namelength == -1) 3499 { 3500 success = 0; 3501 break; 3502 } 3503 recursively_demangle(work, mangled, &temp, namelength); 3504 } 3505 else 3506 { 3507 string_delete (&last_name); 3508 success = do_type (work, mangled, &last_name); 3509 if (!success) 3510 break; 3511 string_appends (&temp, &last_name); 3512 } 3513 } 3514 3515 if (remember_K) 3516 remember_Ktype (work, temp.b, LEN_STRING (&temp)); 3517 3518 if (qualifiers > 0) 3519 string_append (&temp, SCOPE_STRING (work)); 3520 } 3521 3522 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex); 3523 3524 /* If we are using the result as a function name, we need to append 3525 the appropriate '::' separated constructor or destructor name. 3526 We do this here because this is the most convenient place, where 3527 we already have a pointer to the name and the length of the name. */ 3528 3529 if (isfuncname) 3530 { 3531 string_append (&temp, SCOPE_STRING (work)); 3532 if (work -> destructor & 1) 3533 string_append (&temp, "~"); 3534 string_appends (&temp, &last_name); 3535 } 3536 3537 /* Now either prepend the temp buffer to the result, or append it, 3538 depending upon the state of the append flag. */ 3539 3540 if (append) 3541 string_appends (result, &temp); 3542 else 3543 { 3544 if (!STRING_EMPTY (result)) 3545 string_append (&temp, SCOPE_STRING (work)); 3546 string_prepends (result, &temp); 3547 } 3548 3549 string_delete (&last_name); 3550 string_delete (&temp); 3551 return (success); 3552 } 3553 3554 /* 3555 3556 LOCAL FUNCTION 3557 3558 get_count -- convert an ascii count to integer, consuming tokens 3559 3560 SYNOPSIS 3561 3562 static int 3563 get_count (const char **type, int *count) 3564 3565 DESCRIPTION 3566 3567 Assume that *type points at a count in a mangled name; set 3568 *count to its value, and set *type to the next character after 3569 the count. There are some weird rules in effect here. 3570 3571 If *type does not point at a string of digits, return zero. 3572 3573 If *type points at a string of digits followed by an 3574 underscore, set *count to their value as an integer, advance 3575 *type to point *after the underscore, and return 1. 3576 3577 If *type points at a string of digits not followed by an 3578 underscore, consume only the first digit. Set *count to its 3579 value as an integer, leave *type pointing after that digit, 3580 and return 1. 3581 3582 The excuse for this odd behavior: in the ARM and HP demangling 3583 styles, a type can be followed by a repeat count of the form 3584 `Nxy', where: 3585 3586 `x' is a single digit specifying how many additional copies 3587 of the type to append to the argument list, and 3588 3589 `y' is one or more digits, specifying the zero-based index of 3590 the first repeated argument in the list. Yes, as you're 3591 unmangling the name you can figure this out yourself, but 3592 it's there anyway. 3593 3594 So, for example, in `bar__3fooFPiN51', the first argument is a 3595 pointer to an integer (`Pi'), and then the next five arguments 3596 are the same (`N5'), and the first repeat is the function's 3597 second argument (`1'). 3598 */ 3599 3600 static int 3601 get_count (const char **type, int *count) 3602 { 3603 const char *p; 3604 int n; 3605 3606 if (!ISDIGIT ((unsigned char)**type)) 3607 return (0); 3608 else 3609 { 3610 *count = **type - '0'; 3611 (*type)++; 3612 if (ISDIGIT ((unsigned char)**type)) 3613 { 3614 p = *type; 3615 n = *count; 3616 do 3617 { 3618 n *= 10; 3619 n += *p - '0'; 3620 p++; 3621 } 3622 while (ISDIGIT ((unsigned char)*p)); 3623 if (*p == '_') 3624 { 3625 *type = p + 1; 3626 *count = n; 3627 } 3628 } 3629 } 3630 return (1); 3631 } 3632 3633 /* RESULT will be initialised here; it will be freed on failure. The 3634 value returned is really a type_kind_t. */ 3635 3636 static int 3637 do_type (struct work_stuff *work, const char **mangled, string *result) 3638 { 3639 int n; 3640 int i; 3641 int is_proctypevec; 3642 int done; 3643 int success; 3644 string decl; 3645 const char *remembered_type; 3646 int type_quals; 3647 type_kind_t tk = tk_none; 3648 3649 string_init (&decl); 3650 string_init (result); 3651 3652 done = 0; 3653 success = 1; 3654 is_proctypevec = 0; 3655 while (success && !done) 3656 { 3657 int member; 3658 switch (**mangled) 3659 { 3660 3661 /* A pointer type */ 3662 case 'P': 3663 case 'p': 3664 (*mangled)++; 3665 if (! (work -> options & DMGL_JAVA)) 3666 string_prepend (&decl, "*"); 3667 if (tk == tk_none) 3668 tk = tk_pointer; 3669 break; 3670 3671 /* A reference type */ 3672 case 'R': 3673 (*mangled)++; 3674 string_prepend (&decl, "&"); 3675 if (tk == tk_none) 3676 tk = tk_reference; 3677 break; 3678 3679 /* An rvalue reference type */ 3680 case 'O': 3681 (*mangled)++; 3682 string_prepend (&decl, "&&"); 3683 if (tk == tk_none) 3684 tk = tk_rvalue_reference; 3685 break; 3686 3687 /* An array */ 3688 case 'A': 3689 { 3690 ++(*mangled); 3691 if (!STRING_EMPTY (&decl) 3692 && (decl.b[0] == '*' || decl.b[0] == '&')) 3693 { 3694 string_prepend (&decl, "("); 3695 string_append (&decl, ")"); 3696 } 3697 string_append (&decl, "["); 3698 if (**mangled != '_') 3699 success = demangle_template_value_parm (work, mangled, &decl, 3700 tk_integral); 3701 if (**mangled == '_') 3702 ++(*mangled); 3703 string_append (&decl, "]"); 3704 break; 3705 } 3706 3707 /* A back reference to a previously seen type */ 3708 case 'T': 3709 (*mangled)++; 3710 if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes) 3711 { 3712 success = 0; 3713 } 3714 else 3715 for (i = 0; i < work->nproctypes; i++) 3716 if (work -> proctypevec [i] == n) 3717 success = 0; 3718 3719 if (success) 3720 { 3721 is_proctypevec = 1; 3722 push_processed_type (work, n); 3723 remembered_type = work->typevec[n]; 3724 mangled = &remembered_type; 3725 } 3726 break; 3727 3728 /* A function */ 3729 case 'F': 3730 (*mangled)++; 3731 if (!STRING_EMPTY (&decl) 3732 && (decl.b[0] == '*' || decl.b[0] == '&')) 3733 { 3734 string_prepend (&decl, "("); 3735 string_append (&decl, ")"); 3736 } 3737 /* After picking off the function args, we expect to either find the 3738 function return type (preceded by an '_') or the end of the 3739 string. */ 3740 if (!demangle_nested_args (work, mangled, &decl) 3741 || (**mangled != '_' && **mangled != '\0')) 3742 { 3743 success = 0; 3744 break; 3745 } 3746 if (success && (**mangled == '_')) 3747 (*mangled)++; 3748 break; 3749 3750 case 'M': 3751 { 3752 type_quals = TYPE_UNQUALIFIED; 3753 3754 member = **mangled == 'M'; 3755 (*mangled)++; 3756 3757 string_append (&decl, ")"); 3758 3759 /* We don't need to prepend `::' for a qualified name; 3760 demangle_qualified will do that for us. */ 3761 if (**mangled != 'Q') 3762 string_prepend (&decl, SCOPE_STRING (work)); 3763 3764 if (ISDIGIT ((unsigned char)**mangled)) 3765 { 3766 n = consume_count (mangled); 3767 if (n == -1 3768 || (int) strlen (*mangled) < n) 3769 { 3770 success = 0; 3771 break; 3772 } 3773 string_prependn (&decl, *mangled, n); 3774 *mangled += n; 3775 } 3776 else if (**mangled == 'X' || **mangled == 'Y') 3777 { 3778 string temp; 3779 do_type (work, mangled, &temp); 3780 string_prepends (&decl, &temp); 3781 string_delete (&temp); 3782 } 3783 else if (**mangled == 't') 3784 { 3785 string temp; 3786 string_init (&temp); 3787 success = demangle_template (work, mangled, &temp, 3788 NULL, 1, 1); 3789 if (success) 3790 { 3791 string_prependn (&decl, temp.b, temp.p - temp.b); 3792 string_delete (&temp); 3793 } 3794 else 3795 { 3796 string_delete (&temp); 3797 break; 3798 } 3799 } 3800 else if (**mangled == 'Q') 3801 { 3802 success = demangle_qualified (work, mangled, &decl, 3803 /*isfuncnam=*/0, 3804 /*append=*/0); 3805 if (!success) 3806 break; 3807 } 3808 else 3809 { 3810 success = 0; 3811 break; 3812 } 3813 3814 string_prepend (&decl, "("); 3815 if (member) 3816 { 3817 switch (**mangled) 3818 { 3819 case 'C': 3820 case 'V': 3821 case 'u': 3822 type_quals |= code_for_qualifier (**mangled); 3823 (*mangled)++; 3824 break; 3825 3826 default: 3827 break; 3828 } 3829 3830 if (*(*mangled) != 'F') 3831 { 3832 success = 0; 3833 break; 3834 } 3835 (*mangled)++; 3836 } 3837 if ((member && !demangle_nested_args (work, mangled, &decl)) 3838 || **mangled != '_') 3839 { 3840 success = 0; 3841 break; 3842 } 3843 (*mangled)++; 3844 if (! PRINT_ANSI_QUALIFIERS) 3845 { 3846 break; 3847 } 3848 if (type_quals != TYPE_UNQUALIFIED) 3849 { 3850 APPEND_BLANK (&decl); 3851 string_append (&decl, qualifier_string (type_quals)); 3852 } 3853 break; 3854 } 3855 case 'G': 3856 (*mangled)++; 3857 break; 3858 3859 case 'C': 3860 case 'V': 3861 case 'u': 3862 if (PRINT_ANSI_QUALIFIERS) 3863 { 3864 if (!STRING_EMPTY (&decl)) 3865 string_prepend (&decl, " "); 3866 3867 string_prepend (&decl, demangle_qualifier (**mangled)); 3868 } 3869 (*mangled)++; 3870 break; 3871 /* 3872 } 3873 */ 3874 3875 /* fall through */ 3876 default: 3877 done = 1; 3878 break; 3879 } 3880 } 3881 3882 if (success) switch (**mangled) 3883 { 3884 /* A qualified name, such as "Outer::Inner". */ 3885 case 'Q': 3886 case 'K': 3887 { 3888 success = demangle_qualified (work, mangled, result, 0, 1); 3889 break; 3890 } 3891 3892 /* A back reference to a previously seen squangled type */ 3893 case 'B': 3894 (*mangled)++; 3895 if (!get_count (mangled, &n) || n < 0 || n >= work -> numb) 3896 success = 0; 3897 else 3898 string_append (result, work->btypevec[n]); 3899 break; 3900 3901 case 'X': 3902 case 'Y': 3903 /* A template parm. We substitute the corresponding argument. */ 3904 { 3905 int idx; 3906 3907 (*mangled)++; 3908 idx = consume_count_with_underscores (mangled); 3909 3910 if (idx == -1 3911 || (work->tmpl_argvec && idx >= work->ntmpl_args) 3912 || consume_count_with_underscores (mangled) == -1) 3913 { 3914 success = 0; 3915 break; 3916 } 3917 3918 if (work->tmpl_argvec) 3919 string_append (result, work->tmpl_argvec[idx]); 3920 else 3921 string_append_template_idx (result, idx); 3922 3923 success = 1; 3924 } 3925 break; 3926 3927 default: 3928 success = demangle_fund_type (work, mangled, result); 3929 if (tk == tk_none) 3930 tk = (type_kind_t) success; 3931 break; 3932 } 3933 3934 if (success) 3935 { 3936 if (!STRING_EMPTY (&decl)) 3937 { 3938 string_append (result, " "); 3939 string_appends (result, &decl); 3940 } 3941 } 3942 else 3943 string_delete (result); 3944 string_delete (&decl); 3945 3946 if (is_proctypevec) 3947 pop_processed_type (work); 3948 3949 if (success) 3950 /* Assume an integral type, if we're not sure. */ 3951 return (int) ((tk == tk_none) ? tk_integral : tk); 3952 else 3953 return 0; 3954 } 3955 3956 /* Given a pointer to a type string that represents a fundamental type 3957 argument (int, long, unsigned int, etc) in TYPE, a pointer to the 3958 string in which the demangled output is being built in RESULT, and 3959 the WORK structure, decode the types and add them to the result. 3960 3961 For example: 3962 3963 "Ci" => "const int" 3964 "Sl" => "signed long" 3965 "CUs" => "const unsigned short" 3966 3967 The value returned is really a type_kind_t. */ 3968 3969 static int 3970 demangle_fund_type (struct work_stuff *work, 3971 const char **mangled, string *result) 3972 { 3973 int done = 0; 3974 int success = 1; 3975 char buf[INTBUF_SIZE + 5 /* 'int%u_t' */]; 3976 /* unsigned int dec = 0; */ /* JRS 2008-Oct-26: unused (see below) */ 3977 type_kind_t tk = tk_integral; 3978 3979 /* First pick off any type qualifiers. There can be more than one. */ 3980 3981 while (!done) 3982 { 3983 switch (**mangled) 3984 { 3985 case 'C': 3986 case 'V': 3987 case 'u': 3988 if (PRINT_ANSI_QUALIFIERS) 3989 { 3990 if (!STRING_EMPTY (result)) 3991 string_prepend (result, " "); 3992 string_prepend (result, demangle_qualifier (**mangled)); 3993 } 3994 (*mangled)++; 3995 break; 3996 case 'U': 3997 (*mangled)++; 3998 APPEND_BLANK (result); 3999 string_append (result, "unsigned"); 4000 break; 4001 case 'S': /* signed char only */ 4002 (*mangled)++; 4003 APPEND_BLANK (result); 4004 string_append (result, "signed"); 4005 break; 4006 case 'J': 4007 (*mangled)++; 4008 APPEND_BLANK (result); 4009 string_append (result, "__complex"); 4010 break; 4011 default: 4012 done = 1; 4013 break; 4014 } 4015 } 4016 4017 /* Now pick off the fundamental type. There can be only one. */ 4018 4019 switch (**mangled) 4020 { 4021 case '\0': 4022 case '_': 4023 break; 4024 case 'v': 4025 (*mangled)++; 4026 APPEND_BLANK (result); 4027 string_append (result, "void"); 4028 break; 4029 case 'x': 4030 (*mangled)++; 4031 APPEND_BLANK (result); 4032 string_append (result, "long long"); 4033 break; 4034 case 'l': 4035 (*mangled)++; 4036 APPEND_BLANK (result); 4037 string_append (result, "long"); 4038 break; 4039 case 'i': 4040 (*mangled)++; 4041 APPEND_BLANK (result); 4042 string_append (result, "int"); 4043 break; 4044 case 's': 4045 (*mangled)++; 4046 APPEND_BLANK (result); 4047 string_append (result, "short"); 4048 break; 4049 case 'b': 4050 (*mangled)++; 4051 APPEND_BLANK (result); 4052 string_append (result, "bool"); 4053 tk = tk_bool; 4054 break; 4055 case 'c': 4056 (*mangled)++; 4057 APPEND_BLANK (result); 4058 string_append (result, "char"); 4059 tk = tk_char; 4060 break; 4061 case 'w': 4062 (*mangled)++; 4063 APPEND_BLANK (result); 4064 string_append (result, "wchar_t"); 4065 tk = tk_char; 4066 break; 4067 case 'r': 4068 (*mangled)++; 4069 APPEND_BLANK (result); 4070 string_append (result, "long double"); 4071 tk = tk_real; 4072 break; 4073 case 'd': 4074 (*mangled)++; 4075 APPEND_BLANK (result); 4076 string_append (result, "double"); 4077 tk = tk_real; 4078 break; 4079 case 'f': 4080 (*mangled)++; 4081 APPEND_BLANK (result); 4082 string_append (result, "float"); 4083 tk = tk_real; 4084 break; 4085 case 'G': 4086 (*mangled)++; 4087 if (!ISDIGIT ((unsigned char)**mangled)) 4088 { 4089 success = 0; 4090 break; 4091 } 4092 /* fall through */ 4093 case 'I': 4094 (*mangled)++; 4095 if (**mangled == '_') 4096 { 4097 int i; 4098 (*mangled)++; 4099 for (i = 0; 4100 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_'; 4101 (*mangled)++, i++) 4102 buf[i] = **mangled; 4103 if (**mangled != '_') 4104 { 4105 success = 0; 4106 break; 4107 } 4108 buf[i] = '\0'; 4109 (*mangled)++; 4110 } 4111 else 4112 { 4113 strncpy (buf, *mangled, 2); 4114 buf[2] = '\0'; 4115 *mangled += min (strlen (*mangled), 2); 4116 } 4117 /* JRS 2008-Oct-26: the next two commented out lines have been 4118 replaced by the sprintf that follows. This is to avoid use 4119 of sscanf. This hack is merely copied from the old demangler 4120 port (by Michael Matz, Simon Hausmann?) -- I have no idea if 4121 it is really correct/safe, but it looks ok. */ 4122 /*sscanf (buf, "%x", &dec); 4123 sprintf (buf, "int%u_t", dec);*/ 4124 sprintf (buf, "%s", "intXX_t"); 4125 /* end JRS 2008-Oct-26 */ 4126 APPEND_BLANK (result); 4127 string_append (result, buf); 4128 break; 4129 4130 /* fall through */ 4131 /* An explicit type, such as "6mytype" or "7integer" */ 4132 case '0': 4133 case '1': 4134 case '2': 4135 case '3': 4136 case '4': 4137 case '5': 4138 case '6': 4139 case '7': 4140 case '8': 4141 case '9': 4142 { 4143 int bindex = register_Btype (work); 4144 string btype; 4145 string_init (&btype); 4146 if (demangle_class_name (work, mangled, &btype)) { 4147 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex); 4148 APPEND_BLANK (result); 4149 string_appends (result, &btype); 4150 } 4151 else 4152 success = 0; 4153 string_delete (&btype); 4154 break; 4155 } 4156 case 't': 4157 { 4158 string btype; 4159 string_init (&btype); 4160 success = demangle_template (work, mangled, &btype, 0, 1, 1); 4161 string_appends (result, &btype); 4162 string_delete (&btype); 4163 break; 4164 } 4165 default: 4166 success = 0; 4167 break; 4168 } 4169 4170 return success ? ((int) tk) : 0; 4171 } 4172 4173 4174 /* Handle a template's value parameter for HP aCC (extension from ARM) 4175 **mangled points to 'S' or 'U' */ 4176 4177 static int 4178 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED, 4179 const char **mangled, string *result) 4180 { 4181 int unsigned_const; 4182 4183 if (**mangled != 'U' && **mangled != 'S') 4184 return 0; 4185 4186 unsigned_const = (**mangled == 'U'); 4187 4188 (*mangled)++; 4189 4190 switch (**mangled) 4191 { 4192 case 'N': 4193 string_append (result, "-"); 4194 /* fall through */ 4195 case 'P': 4196 (*mangled)++; 4197 break; 4198 case 'M': 4199 /* special case for -2^31 */ 4200 string_append (result, "-2147483648"); 4201 (*mangled)++; 4202 return 1; 4203 default: 4204 return 0; 4205 } 4206 4207 /* We have to be looking at an integer now */ 4208 if (!(ISDIGIT ((unsigned char)**mangled))) 4209 return 0; 4210 4211 /* We only deal with integral values for template 4212 parameters -- so it's OK to look only for digits */ 4213 while (ISDIGIT ((unsigned char)**mangled)) 4214 { 4215 char_str[0] = **mangled; 4216 string_append (result, char_str); 4217 (*mangled)++; 4218 } 4219 4220 if (unsigned_const) 4221 string_append (result, "U"); 4222 4223 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants 4224 with L or LL suffixes. pai/1997-09-03 */ 4225 4226 return 1; /* success */ 4227 } 4228 4229 /* Handle a template's literal parameter for HP aCC (extension from ARM) 4230 **mangled is pointing to the 'A' */ 4231 4232 static int 4233 do_hpacc_template_literal (struct work_stuff *work, const char **mangled, 4234 string *result) 4235 { 4236 int literal_len = 0; 4237 char * recurse; 4238 char * recurse_dem; 4239 4240 if (**mangled != 'A') 4241 return 0; 4242 4243 (*mangled)++; 4244 4245 literal_len = consume_count (mangled); 4246 4247 if (literal_len <= 0 4248 || literal_len > (long) strlen (*mangled)) 4249 return 0; 4250 4251 /* Literal parameters are names of arrays, functions, etc. and the 4252 canonical representation uses the address operator */ 4253 string_append (result, "&"); 4254 4255 /* Now recursively demangle the literal name */ 4256 recurse = XNEWVEC (char, literal_len + 1); 4257 memcpy (recurse, *mangled, literal_len); 4258 recurse[literal_len] = '\000'; 4259 4260 recurse_dem = ML_(cplus_demangle) (recurse, work->options); 4261 4262 if (recurse_dem) 4263 { 4264 string_append (result, recurse_dem); 4265 free (recurse_dem); 4266 } 4267 else 4268 { 4269 string_appendn (result, *mangled, literal_len); 4270 } 4271 (*mangled) += literal_len; 4272 free (recurse); 4273 4274 return 1; 4275 } 4276 4277 static int 4278 snarf_numeric_literal (const char **args, string *arg) 4279 { 4280 if (**args == '-') 4281 { 4282 char_str[0] = '-'; 4283 string_append (arg, char_str); 4284 (*args)++; 4285 } 4286 else if (**args == '+') 4287 (*args)++; 4288 4289 if (!ISDIGIT ((unsigned char)**args)) 4290 return 0; 4291 4292 while (ISDIGIT ((unsigned char)**args)) 4293 { 4294 char_str[0] = **args; 4295 string_append (arg, char_str); 4296 (*args)++; 4297 } 4298 4299 return 1; 4300 } 4301 4302 /* Demangle the next argument, given by MANGLED into RESULT, which 4303 *should be an uninitialized* string. It will be initialized here, 4304 and free'd should anything go wrong. */ 4305 4306 static int 4307 do_arg (struct work_stuff *work, const char **mangled, string *result) 4308 { 4309 /* Remember where we started so that we can record the type, for 4310 non-squangling type remembering. */ 4311 const char *start = *mangled; 4312 4313 string_init (result); 4314 4315 if (work->nrepeats > 0) 4316 { 4317 --work->nrepeats; 4318 4319 if (work->previous_argument == 0) 4320 return 0; 4321 4322 /* We want to reissue the previous type in this argument list. */ 4323 string_appends (result, work->previous_argument); 4324 return 1; 4325 } 4326 4327 if (**mangled == 'n') 4328 { 4329 /* A squangling-style repeat. */ 4330 (*mangled)++; 4331 work->nrepeats = consume_count(mangled); 4332 4333 if (work->nrepeats <= 0) 4334 /* This was not a repeat count after all. */ 4335 return 0; 4336 4337 if (work->nrepeats > 9) 4338 { 4339 if (**mangled != '_') 4340 /* The repeat count should be followed by an '_' in this 4341 case. */ 4342 return 0; 4343 else 4344 (*mangled)++; 4345 } 4346 4347 /* Now, the repeat is all set up. */ 4348 return do_arg (work, mangled, result); 4349 } 4350 4351 /* Save the result in WORK->previous_argument so that we can find it 4352 if it's repeated. Note that saving START is not good enough: we 4353 do not want to add additional types to the back-referenceable 4354 type vector when processing a repeated type. */ 4355 if (work->previous_argument) 4356 string_delete (work->previous_argument); 4357 else 4358 work->previous_argument = XNEW (string); 4359 4360 if (!do_type (work, mangled, work->previous_argument)) 4361 return 0; 4362 4363 string_appends (result, work->previous_argument); 4364 4365 remember_type (work, start, *mangled - start); 4366 return 1; 4367 } 4368 4369 static void 4370 push_processed_type (struct work_stuff *work, int typevec_index) 4371 { 4372 if (work->nproctypes >= work->proctypevec_size) 4373 { 4374 if (!work->proctypevec_size) 4375 { 4376 work->proctypevec_size = 4; 4377 work->proctypevec = XNEWVEC (int, work->proctypevec_size); 4378 } 4379 else 4380 { 4381 if (work->proctypevec_size < 16) 4382 /* Double when small. */ 4383 work->proctypevec_size *= 2; 4384 else 4385 { 4386 /* Grow slower when large. */ 4387 if (work->proctypevec_size > (INT_MAX / 3) * 2) 4388 xmalloc_failed (INT_MAX); 4389 work->proctypevec_size = (work->proctypevec_size * 3 / 2); 4390 } 4391 work->proctypevec 4392 = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size); 4393 } 4394 } 4395 work->proctypevec [work->nproctypes++] = typevec_index; 4396 } 4397 4398 static void 4399 pop_processed_type (struct work_stuff *work) 4400 { 4401 work->nproctypes--; 4402 } 4403 4404 static void 4405 remember_type (struct work_stuff *work, const char *start, int len) 4406 { 4407 char *tem; 4408 4409 if (work->forgetting_types) 4410 return; 4411 4412 if (work -> ntypes >= work -> typevec_size) 4413 { 4414 if (work -> typevec_size == 0) 4415 { 4416 work -> typevec_size = 3; 4417 work -> typevec = XNEWVEC (char *, work->typevec_size); 4418 } 4419 else 4420 { 4421 if (work -> typevec_size > INT_MAX / 2) 4422 xmalloc_failed (INT_MAX); 4423 work -> typevec_size *= 2; 4424 work -> typevec 4425 = XRESIZEVEC (char *, work->typevec, work->typevec_size); 4426 } 4427 } 4428 tem = XNEWVEC (char, len + 1); 4429 memcpy (tem, start, len); 4430 tem[len] = '\0'; 4431 work -> typevec[work -> ntypes++] = tem; 4432 } 4433 4434 4435 /* Remember a K type class qualifier. */ 4436 static void 4437 remember_Ktype (struct work_stuff *work, const char *start, int len) 4438 { 4439 char *tem; 4440 4441 if (work -> numk >= work -> ksize) 4442 { 4443 if (work -> ksize == 0) 4444 { 4445 work -> ksize = 5; 4446 work -> ktypevec = XNEWVEC (char *, work->ksize); 4447 } 4448 else 4449 { 4450 if (work -> ksize > INT_MAX / 2) 4451 xmalloc_failed (INT_MAX); 4452 work -> ksize *= 2; 4453 work -> ktypevec 4454 = XRESIZEVEC (char *, work->ktypevec, work->ksize); 4455 } 4456 } 4457 tem = XNEWVEC (char, len + 1); 4458 memcpy (tem, start, len); 4459 tem[len] = '\0'; 4460 work -> ktypevec[work -> numk++] = tem; 4461 } 4462 4463 /* Register a B code, and get an index for it. B codes are registered 4464 as they are seen, rather than as they are completed, so map<temp<char> > 4465 registers map<temp<char> > as B0, and temp<char> as B1 */ 4466 4467 static int 4468 register_Btype (struct work_stuff *work) 4469 { 4470 int ret; 4471 4472 if (work -> numb >= work -> bsize) 4473 { 4474 if (work -> bsize == 0) 4475 { 4476 work -> bsize = 5; 4477 work -> btypevec = XNEWVEC (char *, work->bsize); 4478 } 4479 else 4480 { 4481 if (work -> bsize > INT_MAX / 2) 4482 xmalloc_failed (INT_MAX); 4483 work -> bsize *= 2; 4484 work -> btypevec 4485 = XRESIZEVEC (char *, work->btypevec, work->bsize); 4486 } 4487 } 4488 ret = work -> numb++; 4489 work -> btypevec[ret] = NULL; 4490 return(ret); 4491 } 4492 4493 /* Store a value into a previously registered B code type. */ 4494 4495 static void 4496 remember_Btype (struct work_stuff *work, const char *start, 4497 int len, int indx) 4498 { 4499 char *tem; 4500 4501 tem = XNEWVEC (char, len + 1); 4502 memcpy (tem, start, len); 4503 tem[len] = '\0'; 4504 work -> btypevec[indx] = tem; 4505 } 4506 4507 /* Lose all the info related to B and K type codes. */ 4508 static void 4509 forget_B_and_K_types (struct work_stuff *work) 4510 { 4511 int i; 4512 4513 while (work -> numk > 0) 4514 { 4515 i = --(work -> numk); 4516 if (work -> ktypevec[i] != NULL) 4517 { 4518 free (work -> ktypevec[i]); 4519 work -> ktypevec[i] = NULL; 4520 } 4521 } 4522 4523 while (work -> numb > 0) 4524 { 4525 i = --(work -> numb); 4526 if (work -> btypevec[i] != NULL) 4527 { 4528 free (work -> btypevec[i]); 4529 work -> btypevec[i] = NULL; 4530 } 4531 } 4532 } 4533 /* Forget the remembered types, but not the type vector itself. */ 4534 4535 static void 4536 forget_types (struct work_stuff *work) 4537 { 4538 int i; 4539 4540 while (work -> ntypes > 0) 4541 { 4542 i = --(work -> ntypes); 4543 if (work -> typevec[i] != NULL) 4544 { 4545 free (work -> typevec[i]); 4546 work -> typevec[i] = NULL; 4547 } 4548 } 4549 } 4550 4551 /* Process the argument list part of the signature, after any class spec 4552 has been consumed, as well as the first 'F' character (if any). For 4553 example: 4554 4555 "__als__3fooRT0" => process "RT0" 4556 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" 4557 4558 DECLP must be already initialised, usually non-empty. It won't be freed 4559 on failure. 4560 4561 Note that g++ differs significantly from ARM and lucid style mangling 4562 with regards to references to previously seen types. For example, given 4563 the source fragment: 4564 4565 class foo { 4566 public: 4567 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); 4568 }; 4569 4570 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 4571 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 4572 4573 g++ produces the names: 4574 4575 __3fooiRT0iT2iT2 4576 foo__FiR3fooiT1iT1 4577 4578 while lcc (and presumably other ARM style compilers as well) produces: 4579 4580 foo__FiR3fooT1T2T1T2 4581 __ct__3fooFiR3fooT1T2T1T2 4582 4583 Note that g++ bases its type numbers starting at zero and counts all 4584 previously seen types, while lucid/ARM bases its type numbers starting 4585 at one and only considers types after it has seen the 'F' character 4586 indicating the start of the function args. For lucid/ARM style, we 4587 account for this difference by discarding any previously seen types when 4588 we see the 'F' character, and subtracting one from the type number 4589 reference. 4590 4591 */ 4592 4593 static int 4594 demangle_args (struct work_stuff *work, const char **mangled, 4595 string *declp) 4596 { 4597 string arg; 4598 int need_comma = 0; 4599 int r; 4600 int t; 4601 const char *tem; 4602 char temptype; 4603 4604 if (PRINT_ARG_TYPES) 4605 { 4606 string_append (declp, "("); 4607 if (**mangled == '\0') 4608 { 4609 string_append (declp, "void"); 4610 } 4611 } 4612 4613 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e') 4614 || work->nrepeats > 0) 4615 { 4616 if ((**mangled == 'N') || (**mangled == 'T')) 4617 { 4618 temptype = *(*mangled)++; 4619 4620 if (temptype == 'N') 4621 { 4622 if (!get_count (mangled, &r)) 4623 { 4624 return (0); 4625 } 4626 } 4627 else 4628 { 4629 r = 1; 4630 } 4631 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10) 4632 { 4633 /* If we have 10 or more types we might have more than a 1 digit 4634 index so we'll have to consume the whole count here. This 4635 will lose if the next thing is a type name preceded by a 4636 count but it's impossible to demangle that case properly 4637 anyway. Eg if we already have 12 types is T12Pc "(..., type1, 4638 Pc, ...)" or "(..., type12, char *, ...)" */ 4639 if ((t = consume_count(mangled)) <= 0) 4640 { 4641 return (0); 4642 } 4643 } 4644 else 4645 { 4646 if (!get_count (mangled, &t)) 4647 { 4648 return (0); 4649 } 4650 } 4651 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 4652 { 4653 t--; 4654 } 4655 /* Validate the type index. Protect against illegal indices from 4656 malformed type strings. */ 4657 if ((t < 0) || (t >= work -> ntypes)) 4658 { 4659 return (0); 4660 } 4661 while (work->nrepeats > 0 || --r >= 0) 4662 { 4663 tem = work -> typevec[t]; 4664 if (need_comma && PRINT_ARG_TYPES) 4665 { 4666 string_append (declp, ", "); 4667 } 4668 push_processed_type (work, t); 4669 if (!do_arg (work, &tem, &arg)) 4670 { 4671 pop_processed_type (work); 4672 return (0); 4673 } 4674 pop_processed_type (work); 4675 if (PRINT_ARG_TYPES) 4676 { 4677 string_appends (declp, &arg); 4678 } 4679 string_delete (&arg); 4680 need_comma = 1; 4681 } 4682 } 4683 else 4684 { 4685 if (need_comma && PRINT_ARG_TYPES) 4686 string_append (declp, ", "); 4687 if (!do_arg (work, mangled, &arg)) 4688 return (0); 4689 if (PRINT_ARG_TYPES) 4690 string_appends (declp, &arg); 4691 string_delete (&arg); 4692 need_comma = 1; 4693 } 4694 } 4695 4696 if (**mangled == 'e') 4697 { 4698 (*mangled)++; 4699 if (PRINT_ARG_TYPES) 4700 { 4701 if (need_comma) 4702 { 4703 string_append (declp, ","); 4704 } 4705 string_append (declp, "..."); 4706 } 4707 } 4708 4709 if (PRINT_ARG_TYPES) 4710 { 4711 string_append (declp, ")"); 4712 } 4713 return (1); 4714 } 4715 4716 /* Like demangle_args, but for demangling the argument lists of function 4717 and method pointers or references, not top-level declarations. */ 4718 4719 static int 4720 demangle_nested_args (struct work_stuff *work, const char **mangled, 4721 string *declp) 4722 { 4723 string* saved_previous_argument; 4724 int result; 4725 int saved_nrepeats; 4726 4727 /* The G++ name-mangling algorithm does not remember types on nested 4728 argument lists, unless -fsquangling is used, and in that case the 4729 type vector updated by remember_type is not used. So, we turn 4730 off remembering of types here. */ 4731 ++work->forgetting_types; 4732 4733 /* For the repeat codes used with -fsquangling, we must keep track of 4734 the last argument. */ 4735 saved_previous_argument = work->previous_argument; 4736 saved_nrepeats = work->nrepeats; 4737 work->previous_argument = 0; 4738 work->nrepeats = 0; 4739 4740 /* Actually demangle the arguments. */ 4741 result = demangle_args (work, mangled, declp); 4742 4743 /* Restore the previous_argument field. */ 4744 if (work->previous_argument) 4745 { 4746 string_delete (work->previous_argument); 4747 free ((char *) work->previous_argument); 4748 } 4749 work->previous_argument = saved_previous_argument; 4750 --work->forgetting_types; 4751 work->nrepeats = saved_nrepeats; 4752 4753 return result; 4754 } 4755 4756 /* Returns 1 if a valid function name was found or 0 otherwise. */ 4757 4758 static int 4759 demangle_function_name (struct work_stuff *work, const char **mangled, 4760 string *declp, const char *scan) 4761 { 4762 size_t i; 4763 string type; 4764 const char *tem; 4765 4766 string_appendn (declp, (*mangled), scan - (*mangled)); 4767 string_need (declp, 1); 4768 *(declp -> p) = '\0'; 4769 4770 /* Consume the function name, including the "__" separating the name 4771 from the signature. We are guaranteed that SCAN points to the 4772 separator. */ 4773 4774 (*mangled) = scan + 2; 4775 /* We may be looking at an instantiation of a template function: 4776 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a 4777 following _F marks the start of the function arguments. Handle 4778 the template arguments first. */ 4779 4780 if (HP_DEMANGLING && (**mangled == 'X')) 4781 { 4782 demangle_arm_hp_template (work, mangled, 0, declp); 4783 /* This leaves MANGLED pointing to the 'F' marking func args */ 4784 } 4785 4786 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) 4787 { 4788 4789 /* See if we have an ARM style constructor or destructor operator. 4790 If so, then just record it, clear the decl, and return. 4791 We can't build the actual constructor/destructor decl until later, 4792 when we recover the class name from the signature. */ 4793 4794 if (strcmp (declp -> b, "__ct") == 0) 4795 { 4796 work -> constructor += 1; 4797 string_clear (declp); 4798 return 1; 4799 } 4800 else if (strcmp (declp -> b, "__dt") == 0) 4801 { 4802 work -> destructor += 1; 4803 string_clear (declp); 4804 return 1; 4805 } 4806 } 4807 4808 if (declp->p - declp->b >= 3 4809 && declp->b[0] == 'o' 4810 && declp->b[1] == 'p' 4811 && strchr (cplus_markers, declp->b[2]) != NULL) 4812 { 4813 /* see if it's an assignment expression */ 4814 if (declp->p - declp->b >= 10 /* op$assign_ */ 4815 && memcmp (declp->b + 3, "assign_", 7) == 0) 4816 { 4817 for (i = 0; i < ARRAY_SIZE (optable); i++) 4818 { 4819 int len = declp->p - declp->b - 10; 4820 if ((int) strlen (optable[i].in) == len 4821 && memcmp (optable[i].in, declp->b + 10, len) == 0) 4822 { 4823 string_clear (declp); 4824 string_append (declp, "operator"); 4825 string_append (declp, optable[i].out); 4826 string_append (declp, "="); 4827 break; 4828 } 4829 } 4830 } 4831 else 4832 { 4833 for (i = 0; i < ARRAY_SIZE (optable); i++) 4834 { 4835 int len = declp->p - declp->b - 3; 4836 if ((int) strlen (optable[i].in) == len 4837 && memcmp (optable[i].in, declp->b + 3, len) == 0) 4838 { 4839 string_clear (declp); 4840 string_append (declp, "operator"); 4841 string_append (declp, optable[i].out); 4842 break; 4843 } 4844 } 4845 } 4846 } 4847 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 4848 && strchr (cplus_markers, declp->b[4]) != NULL) 4849 { 4850 /* type conversion operator */ 4851 tem = declp->b + 5; 4852 if (do_type (work, &tem, &type)) 4853 { 4854 string_clear (declp); 4855 string_append (declp, "operator "); 4856 string_appends (declp, &type); 4857 string_delete (&type); 4858 } 4859 } 4860 else if (declp->b[0] == '_' && declp->b[1] == '_' 4861 && declp->b[2] == 'o' && declp->b[3] == 'p') 4862 { 4863 /* ANSI. */ 4864 /* type conversion operator. */ 4865 tem = declp->b + 4; 4866 if (do_type (work, &tem, &type)) 4867 { 4868 string_clear (declp); 4869 string_append (declp, "operator "); 4870 string_appends (declp, &type); 4871 string_delete (&type); 4872 } 4873 } 4874 else if (declp->b[0] == '_' && declp->b[1] == '_' 4875 && ISLOWER((unsigned char)declp->b[2]) 4876 && ISLOWER((unsigned char)declp->b[3])) 4877 { 4878 if (declp->b[4] == '\0') 4879 { 4880 /* Operator. */ 4881 for (i = 0; i < ARRAY_SIZE (optable); i++) 4882 { 4883 if (strlen (optable[i].in) == 2 4884 && memcmp (optable[i].in, declp->b + 2, 2) == 0) 4885 { 4886 string_clear (declp); 4887 string_append (declp, "operator"); 4888 string_append (declp, optable[i].out); 4889 break; 4890 } 4891 } 4892 } 4893 4894 /* BEGIN hack inserted 20050403 by JRS to deal with apparently 4895 non-cfront compliant new[]/delete[] manglings generated by 4896 the Portland Group's C++ compiler. */ 4897 else 4898 if (strcmp (declp -> b, "__nwa") == 0) { 4899 string_clear (declp); 4900 string_append (declp, "operator new[]"); 4901 } 4902 else 4903 if (strcmp (declp -> b, "__dla") == 0) { 4904 string_clear (declp); 4905 string_append (declp, "operator delete[]"); 4906 } 4907 /* END hack */ 4908 4909 else 4910 { 4911 if (declp->b[2] == 'a' && declp->b[5] == '\0') 4912 { 4913 /* Assignment. */ 4914 for (i = 0; i < ARRAY_SIZE (optable); i++) 4915 { 4916 if (strlen (optable[i].in) == 3 4917 && memcmp (optable[i].in, declp->b + 2, 3) == 0) 4918 { 4919 string_clear (declp); 4920 string_append (declp, "operator"); 4921 string_append (declp, optable[i].out); 4922 break; 4923 } 4924 } 4925 } 4926 } 4927 } 4928 4929 /* If a function name was obtained but it's not valid, we were not 4930 successful. */ 4931 if (LEN_STRING (declp) == 1 && declp->b[0] == '.') 4932 return 0; 4933 else 4934 return 1; 4935 } 4936 4937 /* a mini string-handling package */ 4938 4939 static void 4940 string_need (string *s, int n) 4941 { 4942 int tem; 4943 4944 if (s->b == NULL) 4945 { 4946 if (n < 32) 4947 { 4948 n = 32; 4949 } 4950 s->p = s->b = XNEWVEC (char, n); 4951 s->e = s->b + n; 4952 } 4953 else if (s->e - s->p < n) 4954 { 4955 tem = s->p - s->b; 4956 if (n > INT_MAX / 2 - tem) 4957 xmalloc_failed (INT_MAX); 4958 n += tem; 4959 n *= 2; 4960 s->b = XRESIZEVEC (char, s->b, n); 4961 s->p = s->b + tem; 4962 s->e = s->b + n; 4963 } 4964 } 4965 4966 static void 4967 string_delete (string *s) 4968 { 4969 if (s->b != NULL) 4970 { 4971 free (s->b); 4972 s->b = s->e = s->p = NULL; 4973 } 4974 } 4975 4976 static void 4977 string_init (string *s) 4978 { 4979 s->b = s->p = s->e = NULL; 4980 } 4981 4982 static void 4983 string_clear (string *s) 4984 { 4985 s->p = s->b; 4986 } 4987 4988 #if 0 4989 4990 static int 4991 string_empty (string *s) 4992 { 4993 return (s->b == s->p); 4994 } 4995 4996 #endif 4997 4998 static void 4999 string_append (string *p, const char *s) 5000 { 5001 int n; 5002 if (s == NULL || *s == '\0') 5003 return; 5004 n = strlen (s); 5005 string_need (p, n); 5006 memcpy (p->p, s, n); 5007 p->p += n; 5008 } 5009 5010 static void 5011 string_appends (string *p, string *s) 5012 { 5013 int n; 5014 5015 if (s->b != s->p) 5016 { 5017 n = s->p - s->b; 5018 string_need (p, n); 5019 memcpy (p->p, s->b, n); 5020 p->p += n; 5021 } 5022 } 5023 5024 static void 5025 string_appendn (string *p, const char *s, int n) 5026 { 5027 if (n != 0) 5028 { 5029 string_need (p, n); 5030 memcpy (p->p, s, n); 5031 p->p += n; 5032 } 5033 } 5034 5035 static void 5036 string_prepend (string *p, const char *s) 5037 { 5038 if (s != NULL && *s != '\0') 5039 { 5040 string_prependn (p, s, strlen (s)); 5041 } 5042 } 5043 5044 static void 5045 string_prepends (string *p, string *s) 5046 { 5047 if (s->b != s->p) 5048 { 5049 string_prependn (p, s->b, s->p - s->b); 5050 } 5051 } 5052 5053 static void 5054 string_prependn (string *p, const char *s, int n) 5055 { 5056 char *q; 5057 5058 if (n != 0) 5059 { 5060 string_need (p, n); 5061 for (q = p->p - 1; q >= p->b; q--) 5062 { 5063 q[n] = q[0]; 5064 } 5065 memcpy (p->b, s, n); 5066 p->p += n; 5067 } 5068 } 5069 5070 static void 5071 string_append_template_idx (string *s, int idx) 5072 { 5073 char buf[INTBUF_SIZE + 1 /* 'T' */]; 5074 sprintf(buf, "T%d", idx); 5075 string_append (s, buf); 5076 } 5077