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