cplus-dem.c revision 38889
1/* Demangler for GNU C++ 2 Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 3 Written by James Clark (jjc@jclark.uucp) 4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling 5 6This file is part of the libiberty library. 7Libiberty is free software; you can redistribute it and/or 8modify it under the terms of the GNU Library General Public 9License as published by the Free Software Foundation; either 10version 2 of the License, or (at your option) any later version. 11 12Libiberty is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15Library General Public License for more details. 16 17You should have received a copy of the GNU Library General Public 18License along with libiberty; see the file COPYING.LIB. If 19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22/* This file exports two functions; cplus_mangle_opname and cplus_demangle. 23 24 This file imports xmalloc and xrealloc, which are like malloc and 25 realloc except that they generate a fatal error if there is no 26 available memory. */ 27 28/* This file lives in both GCC and libiberty. When making changes, please 29 try not to break either. */ 30 31#include <ctype.h> 32#include <string.h> 33#include <stdio.h> 34 35#include <demangle.h> 36#undef CURRENT_DEMANGLING_STYLE 37#define CURRENT_DEMANGLING_STYLE work->options 38 39extern char *xmalloc PARAMS((unsigned)); 40extern char *xrealloc PARAMS((char *, unsigned)); 41 42static const char *mystrstr PARAMS ((const char *, const char *)); 43 44static const char * 45mystrstr (s1, s2) 46 const char *s1, *s2; 47{ 48 register const char *p = s1; 49 register int len = strlen (s2); 50 51 for (; (p = strchr (p, *s2)) != 0; p++) 52 { 53 if (strncmp (p, s2, len) == 0) 54 { 55 return (p); 56 } 57 } 58 return (0); 59} 60 61/* In order to allow a single demangler executable to demangle strings 62 using various common values of CPLUS_MARKER, as well as any specific 63 one set at compile time, we maintain a string containing all the 64 commonly used ones, and check to see if the marker we are looking for 65 is in that string. CPLUS_MARKER is usually '$' on systems where the 66 assembler can deal with that. Where the assembler can't, it's usually 67 '.' (but on many systems '.' is used for other things). We put the 68 current defined CPLUS_MARKER first (which defaults to '$'), followed 69 by the next most common value, followed by an explicit '$' in case 70 the value of CPLUS_MARKER is not '$'. 71 72 We could avoid this if we could just get g++ to tell us what the actual 73 cplus marker character is as part of the debug information, perhaps by 74 ensuring that it is the character that terminates the gcc<n>_compiled 75 marker symbol (FIXME). */ 76 77#if !defined (CPLUS_MARKER) 78#define CPLUS_MARKER '$' 79#endif 80 81enum demangling_styles current_demangling_style = gnu_demangling; 82 83static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; 84 85void 86set_cplus_marker_for_demangling (ch) 87 int ch; 88{ 89 cplus_markers[0] = ch; 90} 91 92/* Stuff that is shared between sub-routines. 93 Using a shared structure allows cplus_demangle to be reentrant. */ 94 95struct work_stuff 96{ 97 int options; 98 char **typevec; 99 int ntypes; 100 int typevec_size; 101 int constructor; 102 int destructor; 103 int static_type; /* A static member function */ 104 int const_type; /* A const member function */ 105 char **tmpl_argvec; /* Template function arguments. */ 106 int ntmpl_args; /* The number of template function arguments. */ 107}; 108 109#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) 110#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) 111 112static const struct optable 113{ 114 const char *in; 115 const char *out; 116 int flags; 117} optable[] = { 118 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ 119 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ 120 {"new", " new", 0}, /* old (1.91, and 1.x) */ 121 {"delete", " delete", 0}, /* old (1.91, and 1.x) */ 122 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ 123 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ 124 {"as", "=", DMGL_ANSI}, /* ansi */ 125 {"ne", "!=", DMGL_ANSI}, /* old, ansi */ 126 {"eq", "==", DMGL_ANSI}, /* old, ansi */ 127 {"ge", ">=", DMGL_ANSI}, /* old, ansi */ 128 {"gt", ">", DMGL_ANSI}, /* old, ansi */ 129 {"le", "<=", DMGL_ANSI}, /* old, ansi */ 130 {"lt", "<", DMGL_ANSI}, /* old, ansi */ 131 {"plus", "+", 0}, /* old */ 132 {"pl", "+", DMGL_ANSI}, /* ansi */ 133 {"apl", "+=", DMGL_ANSI}, /* ansi */ 134 {"minus", "-", 0}, /* old */ 135 {"mi", "-", DMGL_ANSI}, /* ansi */ 136 {"ami", "-=", DMGL_ANSI}, /* ansi */ 137 {"mult", "*", 0}, /* old */ 138 {"ml", "*", DMGL_ANSI}, /* ansi */ 139 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ 140 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ 141 {"convert", "+", 0}, /* old (unary +) */ 142 {"negate", "-", 0}, /* old (unary -) */ 143 {"trunc_mod", "%", 0}, /* old */ 144 {"md", "%", DMGL_ANSI}, /* ansi */ 145 {"amd", "%=", DMGL_ANSI}, /* ansi */ 146 {"trunc_div", "/", 0}, /* old */ 147 {"dv", "/", DMGL_ANSI}, /* ansi */ 148 {"adv", "/=", DMGL_ANSI}, /* ansi */ 149 {"truth_andif", "&&", 0}, /* old */ 150 {"aa", "&&", DMGL_ANSI}, /* ansi */ 151 {"truth_orif", "||", 0}, /* old */ 152 {"oo", "||", DMGL_ANSI}, /* ansi */ 153 {"truth_not", "!", 0}, /* old */ 154 {"nt", "!", DMGL_ANSI}, /* ansi */ 155 {"postincrement","++", 0}, /* old */ 156 {"pp", "++", DMGL_ANSI}, /* ansi */ 157 {"postdecrement","--", 0}, /* old */ 158 {"mm", "--", DMGL_ANSI}, /* ansi */ 159 {"bit_ior", "|", 0}, /* old */ 160 {"or", "|", DMGL_ANSI}, /* ansi */ 161 {"aor", "|=", DMGL_ANSI}, /* ansi */ 162 {"bit_xor", "^", 0}, /* old */ 163 {"er", "^", DMGL_ANSI}, /* ansi */ 164 {"aer", "^=", DMGL_ANSI}, /* ansi */ 165 {"bit_and", "&", 0}, /* old */ 166 {"ad", "&", DMGL_ANSI}, /* ansi */ 167 {"aad", "&=", DMGL_ANSI}, /* ansi */ 168 {"bit_not", "~", 0}, /* old */ 169 {"co", "~", DMGL_ANSI}, /* ansi */ 170 {"call", "()", 0}, /* old */ 171 {"cl", "()", DMGL_ANSI}, /* ansi */ 172 {"alshift", "<<", 0}, /* old */ 173 {"ls", "<<", DMGL_ANSI}, /* ansi */ 174 {"als", "<<=", DMGL_ANSI}, /* ansi */ 175 {"arshift", ">>", 0}, /* old */ 176 {"rs", ">>", DMGL_ANSI}, /* ansi */ 177 {"ars", ">>=", DMGL_ANSI}, /* ansi */ 178 {"component", "->", 0}, /* old */ 179 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ 180 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ 181 {"indirect", "*", 0}, /* old */ 182 {"method_call", "->()", 0}, /* old */ 183 {"addr", "&", 0}, /* old (unary &) */ 184 {"array", "[]", 0}, /* old */ 185 {"vc", "[]", DMGL_ANSI}, /* ansi */ 186 {"compound", ", ", 0}, /* old */ 187 {"cm", ", ", DMGL_ANSI}, /* ansi */ 188 {"cond", "?:", 0}, /* old */ 189 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ 190 {"max", ">?", 0}, /* old */ 191 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ 192 {"min", "<?", 0}, /* old */ 193 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */ 194 {"nop", "", 0}, /* old (for operator=) */ 195 {"rm", "->*", DMGL_ANSI} /* ansi */ 196}; 197 198 199typedef struct string /* Beware: these aren't required to be */ 200{ /* '\0' terminated. */ 201 char *b; /* pointer to start of string */ 202 char *p; /* pointer after last character */ 203 char *e; /* pointer after end of allocated space */ 204} string; 205 206#define STRING_EMPTY(str) ((str) -> b == (str) -> p) 207#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ 208 string_prepend(str, " ");} 209#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ 210 string_append(str, " ");} 211 212#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ 213#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ 214 215/* Prototypes for local functions */ 216 217static char * 218mop_up PARAMS ((struct work_stuff *, string *, int)); 219 220#if 0 221static int 222demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *)); 223#endif 224 225static int 226demangle_template PARAMS ((struct work_stuff *work, const char **, string *, 227 string *, int)); 228 229static int 230arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **, 231 const char **)); 232 233static void 234demangle_arm_pt PARAMS ((struct work_stuff *, const char **, int, string *)); 235 236static int 237demangle_class_name PARAMS ((struct work_stuff *, const char **, string *)); 238 239static int 240demangle_qualified PARAMS ((struct work_stuff *, const char **, string *, 241 int, int)); 242 243static int 244demangle_class PARAMS ((struct work_stuff *, const char **, string *)); 245 246static int 247demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *)); 248 249static int 250demangle_signature PARAMS ((struct work_stuff *, const char **, string *)); 251 252static int 253demangle_prefix PARAMS ((struct work_stuff *, const char **, string *)); 254 255static int 256gnu_special PARAMS ((struct work_stuff *, const char **, string *)); 257 258static int 259arm_special PARAMS ((struct work_stuff *, const char **, string *)); 260 261static void 262string_need PARAMS ((string *, int)); 263 264static void 265string_delete PARAMS ((string *)); 266 267static void 268string_init PARAMS ((string *)); 269 270static void 271string_clear PARAMS ((string *)); 272 273#if 0 274static int 275string_empty PARAMS ((string *)); 276#endif 277 278static void 279string_append PARAMS ((string *, const char *)); 280 281static void 282string_appends PARAMS ((string *, string *)); 283 284static void 285string_appendn PARAMS ((string *, const char *, int)); 286 287static void 288string_prepend PARAMS ((string *, const char *)); 289 290static void 291string_prependn PARAMS ((string *, const char *, int)); 292 293static int 294get_count PARAMS ((const char **, int *)); 295 296static int 297consume_count PARAMS ((const char **)); 298 299static int 300consume_count_with_underscores PARAMS ((const char**)); 301 302static int 303demangle_args PARAMS ((struct work_stuff *, const char **, string *)); 304 305static int 306do_type PARAMS ((struct work_stuff *, const char **, string *)); 307 308static int 309do_arg PARAMS ((struct work_stuff *, const char **, string *)); 310 311static void 312demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, 313 const char *)); 314 315static void 316remember_type PARAMS ((struct work_stuff *, const char *, int)); 317 318static void 319forget_types PARAMS ((struct work_stuff *)); 320 321static void 322string_prepends PARAMS ((string *, string *)); 323 324/* Translate count to integer, consuming tokens in the process. 325 Conversion terminates on the first non-digit character. 326 Trying to consume something that isn't a count results in 327 no consumption of input and a return of 0. */ 328 329static int 330consume_count (type) 331 const char **type; 332{ 333 int count = 0; 334 335 while (isdigit (**type)) 336 { 337 count *= 10; 338 count += **type - '0'; 339 (*type)++; 340 } 341 return (count); 342} 343 344 345/* Like consume_count, but for counts that are preceeded and followed 346 by '_' if they are greater than 10. Also, -1 is returned for 347 failure, since 0 can be a valid value. */ 348 349static int 350consume_count_with_underscores (mangled) 351 const char **mangled; 352{ 353 int idx; 354 355 if (**mangled == '_') 356 { 357 (*mangled)++; 358 if (!isdigit (**mangled)) 359 return -1; 360 361 idx = consume_count (mangled); 362 if (**mangled != '_') 363 /* The trailing underscore was missing. */ 364 return -1; 365 366 (*mangled)++; 367 } 368 else 369 { 370 if (**mangled < '0' || **mangled > '9') 371 return -1; 372 373 idx = **mangled - '0'; 374 (*mangled)++; 375 } 376 377 return idx; 378} 379 380int 381cplus_demangle_opname (opname, result, options) 382 const char *opname; 383 char *result; 384 int options; 385{ 386 int len, i, len1, ret; 387 string type; 388 struct work_stuff work[1]; 389 const char *tem; 390 391 len = strlen(opname); 392 result[0] = '\0'; 393 ret = 0; 394 work->options = options; 395 396 if (opname[0] == '_' && opname[1] == '_' 397 && opname[2] == 'o' && opname[3] == 'p') 398 { 399 /* ANSI. */ 400 /* type conversion operator. */ 401 tem = opname + 4; 402 if (do_type (work, &tem, &type)) 403 { 404 strcat (result, "operator "); 405 strncat (result, type.b, type.p - type.b); 406 string_delete (&type); 407 ret = 1; 408 } 409 } 410 else if (opname[0] == '_' && opname[1] == '_' 411 && opname[2] >= 'a' && opname[2] <= 'z' 412 && opname[3] >= 'a' && opname[3] <= 'z') 413 { 414 if (opname[4] == '\0') 415 { 416 /* Operator. */ 417 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 418 { 419 if (strlen (optable[i].in) == 2 420 && memcmp (optable[i].in, opname + 2, 2) == 0) 421 { 422 strcat (result, "operator"); 423 strcat (result, optable[i].out); 424 ret = 1; 425 break; 426 } 427 } 428 } 429 else 430 { 431 if (opname[2] == 'a' && opname[5] == '\0') 432 { 433 /* Assignment. */ 434 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 435 { 436 if (strlen (optable[i].in) == 3 437 && memcmp (optable[i].in, opname + 2, 3) == 0) 438 { 439 strcat (result, "operator"); 440 strcat (result, optable[i].out); 441 ret = 1; 442 break; 443 } 444 } 445 } 446 } 447 } 448 else if (len >= 3 449 && opname[0] == 'o' 450 && opname[1] == 'p' 451 && strchr (cplus_markers, opname[2]) != NULL) 452 { 453 /* see if it's an assignment expression */ 454 if (len >= 10 /* op$assign_ */ 455 && memcmp (opname + 3, "assign_", 7) == 0) 456 { 457 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 458 { 459 len1 = len - 10; 460 if (strlen (optable[i].in) == len1 461 && memcmp (optable[i].in, opname + 10, len1) == 0) 462 { 463 strcat (result, "operator"); 464 strcat (result, optable[i].out); 465 strcat (result, "="); 466 ret = 1; 467 break; 468 } 469 } 470 } 471 else 472 { 473 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 474 { 475 len1 = len - 3; 476 if (strlen (optable[i].in) == len1 477 && memcmp (optable[i].in, opname + 3, len1) == 0) 478 { 479 strcat (result, "operator"); 480 strcat (result, optable[i].out); 481 ret = 1; 482 break; 483 } 484 } 485 } 486 } 487 else if (len >= 5 && memcmp (opname, "type", 4) == 0 488 && strchr (cplus_markers, opname[4]) != NULL) 489 { 490 /* type conversion operator */ 491 tem = opname + 5; 492 if (do_type (work, &tem, &type)) 493 { 494 strcat (result, "operator "); 495 strncat (result, type.b, type.p - type.b); 496 string_delete (&type); 497 ret = 1; 498 } 499 } 500 return ret; 501 502} 503/* Takes operator name as e.g. "++" and returns mangled 504 operator name (e.g. "postincrement_expr"), or NULL if not found. 505 506 If OPTIONS & DMGL_ANSI == 1, return the ANSI name; 507 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ 508 509const char * 510cplus_mangle_opname (opname, options) 511 const char *opname; 512 int options; 513{ 514 int i; 515 int len; 516 517 len = strlen (opname); 518 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 519 { 520 if (strlen (optable[i].out) == len 521 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) 522 && memcmp (optable[i].out, opname, len) == 0) 523 return optable[i].in; 524 } 525 return (0); 526} 527 528/* char *cplus_demangle (const char *mangled, int options) 529 530 If MANGLED is a mangled function name produced by GNU C++, then 531 a pointer to a malloced string giving a C++ representation 532 of the name will be returned; otherwise NULL will be returned. 533 It is the caller's responsibility to free the string which 534 is returned. 535 536 The OPTIONS arg may contain one or more of the following bits: 537 538 DMGL_ANSI ANSI qualifiers such as `const' and `void' are 539 included. 540 DMGL_PARAMS Function parameters are included. 541 542 For example, 543 544 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" 545 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" 546 cplus_demangle ("foo__1Ai", 0) => "A::foo" 547 548 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" 549 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" 550 cplus_demangle ("foo__1Afe", 0) => "A::foo" 551 552 Note that any leading underscores, or other such characters prepended by 553 the compilation system, are presumed to have already been stripped from 554 MANGLED. */ 555 556char * 557cplus_demangle (mangled, options) 558 const char *mangled; 559 int options; 560{ 561 string decl; 562 int success = 0; 563 struct work_stuff work[1]; 564 char *demangled = NULL; 565 566 if ((mangled != NULL) && (*mangled != '\0')) 567 { 568 memset ((char *) work, 0, sizeof (work)); 569 work -> options = options; 570 if ((work->options & DMGL_STYLE_MASK) == 0) 571 work->options |= (int)current_demangling_style & DMGL_STYLE_MASK; 572 573 string_init (&decl); 574 575 /* First check to see if gnu style demangling is active and if the 576 string to be demangled contains a CPLUS_MARKER. If so, attempt to 577 recognize one of the gnu special forms rather than looking for a 578 standard prefix. In particular, don't worry about whether there 579 is a "__" string in the mangled string. Consider "_$_5__foo" for 580 example. */ 581 582 if ((AUTO_DEMANGLING || GNU_DEMANGLING)) 583 { 584 success = gnu_special (work, &mangled, &decl); 585 } 586 if (!success) 587 { 588 success = demangle_prefix (work, &mangled, &decl); 589 } 590 if (success && (*mangled != '\0')) 591 { 592 success = demangle_signature (work, &mangled, &decl); 593 } 594 if (work->constructor == 2) 595 { 596 string_prepend(&decl, "global constructors keyed to "); 597 work->constructor = 0; 598 } 599 else if (work->destructor == 2) 600 { 601 string_prepend(&decl, "global destructors keyed to "); 602 work->destructor = 0; 603 } 604 demangled = mop_up (work, &decl, success); 605 } 606 return (demangled); 607} 608 609static char * 610mop_up (work, declp, success) 611 struct work_stuff *work; 612 string *declp; 613 int success; 614{ 615 char *demangled = NULL; 616 617 /* Discard the remembered types, if any. */ 618 619 forget_types (work); 620 if (work -> typevec != NULL) 621 { 622 free ((char *) work -> typevec); 623 } 624 if (work->tmpl_argvec) 625 { 626 int i; 627 628 for (i = 0; i < work->ntmpl_args; i++) 629 if (work->tmpl_argvec[i]) 630 free ((char*) work->tmpl_argvec[i]); 631 632 free ((char*) work->tmpl_argvec); 633 } 634 635 /* If demangling was successful, ensure that the demangled string is null 636 terminated and return it. Otherwise, free the demangling decl. */ 637 638 if (!success) 639 { 640 string_delete (declp); 641 } 642 else 643 { 644 string_appendn (declp, "", 1); 645 demangled = declp -> b; 646 } 647 return (demangled); 648} 649 650/* 651 652LOCAL FUNCTION 653 654 demangle_signature -- demangle the signature part of a mangled name 655 656SYNOPSIS 657 658 static int 659 demangle_signature (struct work_stuff *work, const char **mangled, 660 string *declp); 661 662DESCRIPTION 663 664 Consume and demangle the signature portion of the mangled name. 665 666 DECLP is the string where demangled output is being built. At 667 entry it contains the demangled root name from the mangled name 668 prefix. I.E. either a demangled operator name or the root function 669 name. In some special cases, it may contain nothing. 670 671 *MANGLED points to the current unconsumed location in the mangled 672 name. As tokens are consumed and demangling is performed, the 673 pointer is updated to continuously point at the next token to 674 be consumed. 675 676 Demangling GNU style mangled names is nasty because there is no 677 explicit token that marks the start of the outermost function 678 argument list. */ 679 680static int 681demangle_signature (work, mangled, declp) 682 struct work_stuff *work; 683 const char **mangled; 684 string *declp; 685{ 686 int success = 1; 687 int func_done = 0; 688 int expect_func = 0; 689 int expect_return_type = 0; 690 const char *oldmangled = NULL; 691 string trawname; 692 string tname; 693 694 while (success && (**mangled != '\0')) 695 { 696 switch (**mangled) 697 { 698 case 'Q': 699 oldmangled = *mangled; 700 success = demangle_qualified (work, mangled, declp, 1, 0); 701 if (success) 702 { 703 remember_type (work, oldmangled, *mangled - oldmangled); 704 } 705 if (AUTO_DEMANGLING || GNU_DEMANGLING) 706 { 707 expect_func = 1; 708 } 709 oldmangled = NULL; 710 break; 711 712 case 'S': 713 /* Static member function */ 714 if (oldmangled == NULL) 715 { 716 oldmangled = *mangled; 717 } 718 (*mangled)++; 719 work -> static_type = 1; 720 break; 721 722 case 'C': 723 /* a const member function */ 724 if (oldmangled == NULL) 725 { 726 oldmangled = *mangled; 727 } 728 (*mangled)++; 729 work -> const_type = 1; 730 break; 731 732 case '0': case '1': case '2': case '3': case '4': 733 case '5': case '6': case '7': case '8': case '9': 734 if (oldmangled == NULL) 735 { 736 oldmangled = *mangled; 737 } 738 success = demangle_class (work, mangled, declp); 739 if (success) 740 { 741 remember_type (work, oldmangled, *mangled - oldmangled); 742 } 743 if (AUTO_DEMANGLING || GNU_DEMANGLING) 744 { 745 expect_func = 1; 746 } 747 oldmangled = NULL; 748 break; 749 750 case 'F': 751 /* Function */ 752 /* ARM style demangling includes a specific 'F' character after 753 the class name. For GNU style, it is just implied. So we can 754 safely just consume any 'F' at this point and be compatible 755 with either style. */ 756 757 oldmangled = NULL; 758 func_done = 1; 759 (*mangled)++; 760 761 /* For lucid/ARM style we have to forget any types we might 762 have remembered up to this point, since they were not argument 763 types. GNU style considers all types seen as available for 764 back references. See comment in demangle_args() */ 765 766 if (LUCID_DEMANGLING || ARM_DEMANGLING) 767 { 768 forget_types (work); 769 } 770 success = demangle_args (work, mangled, declp); 771 break; 772 773 case 't': 774 /* G++ Template */ 775 string_init(&trawname); 776 string_init(&tname); 777 if (oldmangled == NULL) 778 { 779 oldmangled = *mangled; 780 } 781 success = demangle_template (work, mangled, &tname, &trawname, 1); 782 if (success) 783 { 784 remember_type (work, oldmangled, *mangled - oldmangled); 785 } 786 string_append(&tname, (work -> options & DMGL_JAVA) ? "." : "::"); 787 string_prepends(declp, &tname); 788 if (work -> destructor & 1) 789 { 790 string_prepend (&trawname, "~"); 791 string_appends (declp, &trawname); 792 work->destructor -= 1; 793 } 794 if ((work->constructor & 1) || (work->destructor & 1)) 795 { 796 string_appends (declp, &trawname); 797 work->constructor -= 1; 798 } 799 string_delete(&trawname); 800 string_delete(&tname); 801 oldmangled = NULL; 802 expect_func = 1; 803 break; 804 805 case '_': 806 if (GNU_DEMANGLING && expect_return_type) 807 { 808 /* Read the return type. */ 809 string return_type; 810 string_init (&return_type); 811 812 (*mangled)++; 813 success = do_type (work, mangled, &return_type); 814 APPEND_BLANK (&return_type); 815 816 string_prepends (declp, &return_type); 817 string_delete (&return_type); 818 break; 819 } 820 else 821 /* At the outermost level, we cannot have a return type specified, 822 so if we run into another '_' at this point we are dealing with 823 a mangled name that is either bogus, or has been mangled by 824 some algorithm we don't know how to deal with. So just 825 reject the entire demangling. */ 826 success = 0; 827 break; 828 829 case 'H': 830 if (GNU_DEMANGLING) 831 { 832 /* A G++ template function. Read the template arguments. */ 833 success = demangle_template (work, mangled, declp, 0, 0); 834 if (!(work->constructor & 1)) 835 expect_return_type = 1; 836 (*mangled)++; 837 break; 838 } 839 else 840 /* fall through */ 841 ; 842 843 default: 844 if (AUTO_DEMANGLING || GNU_DEMANGLING) 845 { 846 /* Assume we have stumbled onto the first outermost function 847 argument token, and start processing args. */ 848 func_done = 1; 849 success = demangle_args (work, mangled, declp); 850 } 851 else 852 { 853 /* Non-GNU demanglers use a specific token to mark the start 854 of the outermost function argument tokens. Typically 'F', 855 for ARM-demangling, for example. So if we find something 856 we are not prepared for, it must be an error. */ 857 success = 0; 858 } 859 break; 860 } 861 /* 862 if (AUTO_DEMANGLING || GNU_DEMANGLING) 863 */ 864 { 865 if (success && expect_func) 866 { 867 func_done = 1; 868 success = demangle_args (work, mangled, declp); 869 /* Since template include the mangling of their return types, 870 we must set expect_func to 0 so that we don't try do 871 demangle more arguments the next time we get here. */ 872 expect_func = 0; 873 } 874 } 875 } 876 if (success && !func_done) 877 { 878 if (AUTO_DEMANGLING || GNU_DEMANGLING) 879 { 880 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and 881 bar__3fooi is 'foo::bar(int)'. We get here when we find the 882 first case, and need to ensure that the '(void)' gets added to 883 the current declp. Note that with ARM, the first case 884 represents the name of a static data member 'foo::bar', 885 which is in the current declp, so we leave it alone. */ 886 success = demangle_args (work, mangled, declp); 887 } 888 } 889 if (success && work -> static_type && PRINT_ARG_TYPES) 890 { 891 string_append (declp, " static"); 892 } 893 if (success && work -> const_type && PRINT_ARG_TYPES) 894 { 895 string_append (declp, " const"); 896 } 897 return (success); 898} 899 900#if 0 901 902static int 903demangle_method_args (work, mangled, declp) 904 struct work_stuff *work; 905 const char **mangled; 906 string *declp; 907{ 908 int success = 0; 909 910 if (work -> static_type) 911 { 912 string_append (declp, *mangled + 1); 913 *mangled += strlen (*mangled); 914 success = 1; 915 } 916 else 917 { 918 success = demangle_args (work, mangled, declp); 919 } 920 return (success); 921} 922 923#endif 924 925static int 926demangle_template (work, mangled, tname, trawname, is_type) 927 struct work_stuff *work; 928 const char **mangled; 929 string *tname; 930 string *trawname; 931 int is_type; 932{ 933 int i; 934 int is_pointer; 935 int is_real; 936 int is_integral; 937 int is_char; 938 int is_bool; 939 int r; 940 int need_comma = 0; 941 int success = 0; 942 int done; 943 const char *old_p; 944 const char *start; 945 int symbol_len; 946 int is_java_array = 0; 947 string temp; 948 949 (*mangled)++; 950 if (is_type) 951 { 952 start = *mangled; 953 /* get template name */ 954 if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r) 955 { 956 return (0); 957 } 958 if (trawname) 959 string_appendn (trawname, *mangled, r); 960 is_java_array = (work -> options & DMGL_JAVA) 961 && strncmp (*mangled, "JArray1Z", 8) == 0; 962 if (! is_java_array) 963 { 964 string_appendn (tname, *mangled, r); 965 } 966 *mangled += r; 967 } 968 if (!is_java_array) 969 string_append (tname, "<"); 970 /* get size of template parameter list */ 971 if (!get_count (mangled, &r)) 972 { 973 return (0); 974 } 975 if (!is_type) 976 { 977 /* Create an array for saving the template argument values. */ 978 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); 979 work->ntmpl_args = r; 980 for (i = 0; i < r; i++) 981 work->tmpl_argvec[i] = 0; 982 } 983 for (i = 0; i < r; i++) 984 { 985 if (need_comma) 986 { 987 string_append (tname, ", "); 988 } 989 /* Z for type parameters */ 990 if (**mangled == 'Z') 991 { 992 (*mangled)++; 993 /* temp is initialized in do_type */ 994 success = do_type (work, mangled, &temp); 995 if (success) 996 { 997 string_appends (tname, &temp); 998 999 if (!is_type) 1000 { 1001 /* Save the template argument. */ 1002 int len = temp.p - temp.b; 1003 work->tmpl_argvec[i] = xmalloc (len + 1); 1004 memcpy (work->tmpl_argvec[i], temp.b, len); 1005 work->tmpl_argvec[i][len] = '\0'; 1006 } 1007 } 1008 string_delete(&temp); 1009 if (!success) 1010 { 1011 break; 1012 } 1013 } 1014 else 1015 { 1016 string param; 1017 string* s; 1018 1019 /* otherwise, value parameter */ 1020 old_p = *mangled; 1021 is_pointer = 0; 1022 is_real = 0; 1023 is_integral = 0; 1024 is_char = 0; 1025 is_bool = 0; 1026 done = 0; 1027 /* temp is initialized in do_type */ 1028 success = do_type (work, mangled, &temp); 1029 /* 1030 if (success) 1031 { 1032 string_appends (s, &temp); 1033 } 1034 */ 1035 string_delete(&temp); 1036 if (!success) 1037 { 1038 break; 1039 } 1040 /* 1041 string_append (s, "="); 1042 */ 1043 1044 if (!is_type) 1045 { 1046 s = ¶m; 1047 string_init (s); 1048 } 1049 else 1050 s = tname; 1051 1052 while (*old_p && !done) 1053 { 1054 switch (*old_p) 1055 { 1056 case 'P': 1057 case 'p': 1058 case 'R': 1059 done = is_pointer = 1; 1060 break; 1061 case 'C': /* const */ 1062 case 'S': /* explicitly signed [char] */ 1063 case 'U': /* unsigned */ 1064 case 'V': /* volatile */ 1065 case 'F': /* function */ 1066 case 'M': /* member function */ 1067 case 'O': /* ??? */ 1068 case 'J': /* complex */ 1069 old_p++; 1070 continue; 1071 case 'Q': /* qualified name */ 1072 done = is_integral = 1; 1073 break; 1074 case 'T': /* remembered type */ 1075 abort (); 1076 break; 1077 case 'v': /* void */ 1078 abort (); 1079 break; 1080 case 'x': /* long long */ 1081 case 'l': /* long */ 1082 case 'i': /* int */ 1083 case 's': /* short */ 1084 case 'w': /* wchar_t */ 1085 done = is_integral = 1; 1086 break; 1087 case 'b': /* bool */ 1088 done = is_bool = 1; 1089 break; 1090 case 'c': /* char */ 1091 done = is_char = 1; 1092 break; 1093 case 'r': /* long double */ 1094 case 'd': /* double */ 1095 case 'f': /* float */ 1096 done = is_real = 1; 1097 break; 1098 default: 1099 /* it's probably user defined type, let's assume 1100 it's integral, it seems hard to figure out 1101 what it really is */ 1102 done = is_integral = 1; 1103 } 1104 } 1105 if (**mangled == 'Y') 1106 { 1107 /* The next argument is a template parameter. */ 1108 int idx; 1109 1110 (*mangled)++; 1111 idx = consume_count_with_underscores (mangled); 1112 if (idx == -1 1113 || (work->tmpl_argvec && idx >= work->ntmpl_args) 1114 || consume_count_with_underscores (mangled) == -1) 1115 { 1116 success = 0; 1117 if (!is_type) 1118 string_delete (s); 1119 break; 1120 } 1121 if (work->tmpl_argvec) 1122 string_append (s, work->tmpl_argvec[idx]); 1123 else 1124 { 1125 char buf[10]; 1126 sprintf(buf, "T%d", idx); 1127 string_append (s, buf); 1128 } 1129 } 1130 else if (is_integral) 1131 { 1132 if (**mangled == 'm') 1133 { 1134 string_appendn (s, "-", 1); 1135 (*mangled)++; 1136 } 1137 while (isdigit (**mangled)) 1138 { 1139 string_appendn (s, *mangled, 1); 1140 (*mangled)++; 1141 } 1142 } 1143 else if (is_char) 1144 { 1145 char tmp[2]; 1146 int val; 1147 if (**mangled == 'm') 1148 { 1149 string_appendn (s, "-", 1); 1150 (*mangled)++; 1151 } 1152 string_appendn (s, "'", 1); 1153 val = consume_count(mangled); 1154 if (val == 0) 1155 { 1156 success = 0; 1157 if (!is_type) 1158 string_delete (s); 1159 break; 1160 } 1161 tmp[0] = (char)val; 1162 tmp[1] = '\0'; 1163 string_appendn (s, &tmp[0], 1); 1164 string_appendn (s, "'", 1); 1165 } 1166 else if (is_bool) 1167 { 1168 int val = consume_count (mangled); 1169 if (val == 0) 1170 string_appendn (s, "false", 5); 1171 else if (val == 1) 1172 string_appendn (s, "true", 4); 1173 else 1174 success = 0; 1175 } 1176 else if (is_real) 1177 { 1178 if (**mangled == 'm') 1179 { 1180 string_appendn (s, "-", 1); 1181 (*mangled)++; 1182 } 1183 while (isdigit (**mangled)) 1184 { 1185 string_appendn (s, *mangled, 1); 1186 (*mangled)++; 1187 } 1188 if (**mangled == '.') /* fraction */ 1189 { 1190 string_appendn (s, ".", 1); 1191 (*mangled)++; 1192 while (isdigit (**mangled)) 1193 { 1194 string_appendn (s, *mangled, 1); 1195 (*mangled)++; 1196 } 1197 } 1198 if (**mangled == 'e') /* exponent */ 1199 { 1200 string_appendn (s, "e", 1); 1201 (*mangled)++; 1202 while (isdigit (**mangled)) 1203 { 1204 string_appendn (s, *mangled, 1); 1205 (*mangled)++; 1206 } 1207 } 1208 } 1209 else if (is_pointer) 1210 { 1211 symbol_len = consume_count (mangled); 1212 if (symbol_len == 0) 1213 { 1214 success = 0; 1215 if (!is_type) 1216 string_delete (s); 1217 break; 1218 } 1219 if (symbol_len == 0) 1220 string_appendn (s, "0", 1); 1221 else 1222 { 1223 char *p = xmalloc (symbol_len + 1), *q; 1224 strncpy (p, *mangled, symbol_len); 1225 p [symbol_len] = '\0'; 1226 q = cplus_demangle (p, work->options); 1227 string_appendn (s, "&", 1); 1228 if (q) 1229 { 1230 string_append (s, q); 1231 free (q); 1232 } 1233 else 1234 string_append (s, p); 1235 free (p); 1236 } 1237 *mangled += symbol_len; 1238 } 1239 if (!is_type) 1240 { 1241 int len = s->p - s->b; 1242 work->tmpl_argvec[i] = xmalloc (len + 1); 1243 memcpy (work->tmpl_argvec[i], s->b, len); 1244 work->tmpl_argvec[i][len] = '\0'; 1245 1246 string_appends (tname, s); 1247 string_delete (s); 1248 } 1249 } 1250 need_comma = 1; 1251 } 1252 if (is_java_array) 1253 { 1254 string_append (tname, "[]"); 1255 } 1256 else 1257 { 1258 if (tname->p[-1] == '>') 1259 string_append (tname, " "); 1260 string_append (tname, ">"); 1261 } 1262 1263 /* 1264 if (work -> static_type) 1265 { 1266 string_append (declp, *mangled + 1); 1267 *mangled += strlen (*mangled); 1268 success = 1; 1269 } 1270 else 1271 { 1272 success = demangle_args (work, mangled, declp); 1273 } 1274 } 1275 */ 1276 return (success); 1277} 1278 1279static int 1280arm_pt (work, mangled, n, anchor, args) 1281 struct work_stuff *work; 1282 const char *mangled; 1283 int n; 1284 const char **anchor, **args; 1285{ 1286 /* ARM template? */ 1287 if (ARM_DEMANGLING && (*anchor = mystrstr (mangled, "__pt__"))) 1288 { 1289 int len; 1290 *args = *anchor + 6; 1291 len = consume_count (args); 1292 if (*args + len == mangled + n && **args == '_') 1293 { 1294 ++*args; 1295 return 1; 1296 } 1297 } 1298 return 0; 1299} 1300 1301static void 1302demangle_arm_pt (work, mangled, n, declp) 1303 struct work_stuff *work; 1304 const char **mangled; 1305 int n; 1306 string *declp; 1307{ 1308 const char *p; 1309 const char *args; 1310 const char *e = *mangled + n; 1311 1312 /* ARM template? */ 1313 if (arm_pt (work, *mangled, n, &p, &args)) 1314 { 1315 string arg; 1316 string_init (&arg); 1317 string_appendn (declp, *mangled, p - *mangled); 1318 string_append (declp, "<"); 1319 /* should do error checking here */ 1320 while (args < e) { 1321 string_clear (&arg); 1322 do_type (work, &args, &arg); 1323 string_appends (declp, &arg); 1324 string_append (declp, ","); 1325 } 1326 string_delete (&arg); 1327 --declp->p; 1328 string_append (declp, ">"); 1329 } 1330 else 1331 { 1332 string_appendn (declp, *mangled, n); 1333 } 1334 *mangled += n; 1335} 1336 1337static int 1338demangle_class_name (work, mangled, declp) 1339 struct work_stuff *work; 1340 const char **mangled; 1341 string *declp; 1342{ 1343 int n; 1344 int success = 0; 1345 1346 n = consume_count (mangled); 1347 if (strlen (*mangled) >= n) 1348 { 1349 demangle_arm_pt (work, mangled, n, declp); 1350 success = 1; 1351 } 1352 1353 return (success); 1354} 1355 1356/* 1357 1358LOCAL FUNCTION 1359 1360 demangle_class -- demangle a mangled class sequence 1361 1362SYNOPSIS 1363 1364 static int 1365 demangle_class (struct work_stuff *work, const char **mangled, 1366 strint *declp) 1367 1368DESCRIPTION 1369 1370 DECLP points to the buffer into which demangling is being done. 1371 1372 *MANGLED points to the current token to be demangled. On input, 1373 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) 1374 On exit, it points to the next token after the mangled class on 1375 success, or the first unconsumed token on failure. 1376 1377 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then 1378 we are demangling a constructor or destructor. In this case 1379 we prepend "class::class" or "class::~class" to DECLP. 1380 1381 Otherwise, we prepend "class::" to the current DECLP. 1382 1383 Reset the constructor/destructor flags once they have been 1384 "consumed". This allows demangle_class to be called later during 1385 the same demangling, to do normal class demangling. 1386 1387 Returns 1 if demangling is successful, 0 otherwise. 1388 1389*/ 1390 1391static int 1392demangle_class (work, mangled, declp) 1393 struct work_stuff *work; 1394 const char **mangled; 1395 string *declp; 1396{ 1397 int success = 0; 1398 string class_name; 1399 1400 string_init (&class_name); 1401 if (demangle_class_name (work, mangled, &class_name)) 1402 { 1403 if ((work->constructor & 1) || (work->destructor & 1)) 1404 { 1405 string_prepends (declp, &class_name); 1406 if (work -> destructor & 1) 1407 { 1408 string_prepend (declp, "~"); 1409 work -> destructor -= 1; 1410 } 1411 else 1412 { 1413 work -> constructor -= 1; 1414 } 1415 } 1416 string_prepend (declp, (work -> options & DMGL_JAVA) ? "." : "::"); 1417 string_prepends (declp, &class_name); 1418 success = 1; 1419 } 1420 string_delete (&class_name); 1421 return (success); 1422} 1423 1424/* 1425 1426LOCAL FUNCTION 1427 1428 demangle_prefix -- consume the mangled name prefix and find signature 1429 1430SYNOPSIS 1431 1432 static int 1433 demangle_prefix (struct work_stuff *work, const char **mangled, 1434 string *declp); 1435 1436DESCRIPTION 1437 1438 Consume and demangle the prefix of the mangled name. 1439 1440 DECLP points to the string buffer into which demangled output is 1441 placed. On entry, the buffer is empty. On exit it contains 1442 the root function name, the demangled operator name, or in some 1443 special cases either nothing or the completely demangled result. 1444 1445 MANGLED points to the current pointer into the mangled name. As each 1446 token of the mangled name is consumed, it is updated. Upon entry 1447 the current mangled name pointer points to the first character of 1448 the mangled name. Upon exit, it should point to the first character 1449 of the signature if demangling was successful, or to the first 1450 unconsumed character if demangling of the prefix was unsuccessful. 1451 1452 Returns 1 on success, 0 otherwise. 1453 */ 1454 1455static int 1456demangle_prefix (work, mangled, declp) 1457 struct work_stuff *work; 1458 const char **mangled; 1459 string *declp; 1460{ 1461 int success = 1; 1462 const char *scan; 1463 int i; 1464 1465 if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) 1466 { 1467 char *marker = strchr (cplus_markers, (*mangled)[8]); 1468 if (marker != NULL && *marker == (*mangled)[10]) 1469 { 1470 if ((*mangled)[9] == 'D') 1471 { 1472 /* it's a GNU global destructor to be executed at program exit */ 1473 (*mangled) += 11; 1474 work->destructor = 2; 1475 if (gnu_special (work, mangled, declp)) 1476 return success; 1477 } 1478 else if ((*mangled)[9] == 'I') 1479 { 1480 /* it's a GNU global constructor to be executed at program init */ 1481 (*mangled) += 11; 1482 work->constructor = 2; 1483 if (gnu_special (work, mangled, declp)) 1484 return success; 1485 } 1486 } 1487 } 1488 else if (ARM_DEMANGLING && strncmp(*mangled, "__std__", 7) == 0) 1489 { 1490 /* it's a ARM global destructor to be executed at program exit */ 1491 (*mangled) += 7; 1492 work->destructor = 2; 1493 } 1494 else if (ARM_DEMANGLING && strncmp(*mangled, "__sti__", 7) == 0) 1495 { 1496 /* it's a ARM global constructor to be executed at program initial */ 1497 (*mangled) += 7; 1498 work->constructor = 2; 1499 } 1500 1501 /* This block of code is a reduction in strength time optimization 1502 of: 1503 scan = mystrstr (*mangled, "__"); */ 1504 1505 { 1506 scan = *mangled; 1507 1508 do { 1509 scan = strchr (scan, '_'); 1510 } while (scan != NULL && *++scan != '_'); 1511 1512 if (scan != NULL) --scan; 1513 } 1514 1515 if (scan != NULL) 1516 { 1517 /* We found a sequence of two or more '_', ensure that we start at 1518 the last pair in the sequence. */ 1519 i = strspn (scan, "_"); 1520 if (i > 2) 1521 { 1522 scan += (i - 2); 1523 } 1524 } 1525 1526 if (scan == NULL) 1527 { 1528 success = 0; 1529 } 1530 else if (work -> static_type) 1531 { 1532 if (!isdigit (scan[0]) && (scan[0] != 't')) 1533 { 1534 success = 0; 1535 } 1536 } 1537 else if ((scan == *mangled) 1538 && (isdigit (scan[2]) || (scan[2] == 'Q') || (scan[2] == 't') 1539 || (scan[2] == 'H'))) 1540 { 1541 /* The ARM says nothing about the mangling of local variables. 1542 But cfront mangles local variables by prepending __<nesting_level> 1543 to them. As an extension to ARM demangling we handle this case. */ 1544 if ((LUCID_DEMANGLING || ARM_DEMANGLING) && isdigit (scan[2])) 1545 { 1546 *mangled = scan + 2; 1547 consume_count (mangled); 1548 string_append (declp, *mangled); 1549 *mangled += strlen (*mangled); 1550 success = 1; 1551 } 1552 else 1553 { 1554 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses 1555 names like __Q2_3foo3bar for nested type names. So don't accept 1556 this style of constructor for cfront demangling. A GNU 1557 style member-template constructor starts with 'H'. */ 1558 if (!(LUCID_DEMANGLING || ARM_DEMANGLING)) 1559 work -> constructor += 1; 1560 *mangled = scan + 2; 1561 } 1562 } 1563 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't')) 1564 { 1565 /* Mangled name starts with "__". Skip over any leading '_' characters, 1566 then find the next "__" that separates the prefix from the signature. 1567 */ 1568 if (!(ARM_DEMANGLING || LUCID_DEMANGLING) 1569 || (arm_special (work, mangled, declp) == 0)) 1570 { 1571 while (*scan == '_') 1572 { 1573 scan++; 1574 } 1575 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) 1576 { 1577 /* No separator (I.E. "__not_mangled"), or empty signature 1578 (I.E. "__not_mangled_either__") */ 1579 success = 0; 1580 } 1581 else 1582 { 1583 demangle_function_name (work, mangled, declp, scan); 1584 } 1585 } 1586 } 1587 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') 1588 { 1589 /* Cfront-style parameterized type. Handled later as a signature. */ 1590 success = 1; 1591 1592 /* ARM template? */ 1593 demangle_arm_pt (work, mangled, strlen (*mangled), declp); 1594 } 1595 else if (*(scan + 2) != '\0') 1596 { 1597 /* Mangled name does not start with "__" but does have one somewhere 1598 in there with non empty stuff after it. Looks like a global 1599 function name. */ 1600 demangle_function_name (work, mangled, declp, scan); 1601 } 1602 else 1603 { 1604 /* Doesn't look like a mangled name */ 1605 success = 0; 1606 } 1607 1608 if (!success && (work->constructor == 2 || work->destructor == 2)) 1609 { 1610 string_append (declp, *mangled); 1611 *mangled += strlen (*mangled); 1612 success = 1; 1613 } 1614 return (success); 1615} 1616 1617/* 1618 1619LOCAL FUNCTION 1620 1621 gnu_special -- special handling of gnu mangled strings 1622 1623SYNOPSIS 1624 1625 static int 1626 gnu_special (struct work_stuff *work, const char **mangled, 1627 string *declp); 1628 1629 1630DESCRIPTION 1631 1632 Process some special GNU style mangling forms that don't fit 1633 the normal pattern. For example: 1634 1635 _$_3foo (destructor for class foo) 1636 _vt$foo (foo virtual table) 1637 _vt$foo$bar (foo::bar virtual table) 1638 __vt_foo (foo virtual table, new style with thunks) 1639 _3foo$varname (static data member) 1640 _Q22rs2tu$vw (static data member) 1641 __t6vector1Zii (constructor with template) 1642 __thunk_4__$_7ostream (virtual function thunk) 1643 */ 1644 1645static int 1646gnu_special (work, mangled, declp) 1647 struct work_stuff *work; 1648 const char **mangled; 1649 string *declp; 1650{ 1651 int n; 1652 int success = 1; 1653 const char *p; 1654 1655 if ((*mangled)[0] == '_' 1656 && strchr (cplus_markers, (*mangled)[1]) != NULL 1657 && (*mangled)[2] == '_') 1658 { 1659 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */ 1660 (*mangled) += 3; 1661 work -> destructor += 1; 1662 } 1663 else if ((*mangled)[0] == '_' 1664 && (((*mangled)[1] == '_' 1665 && (*mangled)[2] == 'v' 1666 && (*mangled)[3] == 't' 1667 && (*mangled)[4] == '_') 1668 || ((*mangled)[1] == 'v' 1669 && (*mangled)[2] == 't' 1670 && strchr (cplus_markers, (*mangled)[3]) != NULL))) 1671 { 1672 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>" 1673 and create the decl. Note that we consume the entire mangled 1674 input string, which means that demangle_signature has no work 1675 to do. */ 1676 if ((*mangled)[2] == 'v') 1677 (*mangled) += 5; /* New style, with thunks: "__vt_" */ 1678 else 1679 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */ 1680 while (**mangled != '\0') 1681 { 1682 p = strpbrk (*mangled, cplus_markers); 1683 switch (**mangled) 1684 { 1685 case 'Q': 1686 success = demangle_qualified (work, mangled, declp, 0, 1); 1687 break; 1688 case 't': 1689 success = demangle_template (work, mangled, declp, 0, 1); 1690 break; 1691 default: 1692 if (isdigit(*mangled[0])) 1693 { 1694 n = consume_count(mangled); 1695 /* We may be seeing a too-large size, or else a 1696 ".<digits>" indicating a static local symbol. In 1697 any case, declare victory and move on; *don't* try 1698 to use n to allocate. */ 1699 if (n >= strlen (*mangled)) 1700 { 1701 success = 1; 1702 break; 1703 } 1704 } 1705 else 1706 { 1707 n = strcspn (*mangled, cplus_markers); 1708 } 1709 string_appendn (declp, *mangled, n); 1710 (*mangled) += n; 1711 } 1712 1713 if (success && ((p == NULL) || (p == *mangled))) 1714 { 1715 if (p != NULL) 1716 { 1717 string_append (declp, 1718 (work -> options & DMGL_JAVA) ? "." : "::"); 1719 (*mangled)++; 1720 } 1721 } 1722 else 1723 { 1724 success = 0; 1725 break; 1726 } 1727 } 1728 if (success) 1729 string_append (declp, " virtual table"); 1730 } 1731 else if ((*mangled)[0] == '_' 1732 && (strchr("0123456789Qt", (*mangled)[1]) != NULL) 1733 && (p = strpbrk (*mangled, cplus_markers)) != NULL) 1734 { 1735 /* static data member, "_3foo$varname" for example */ 1736 (*mangled)++; 1737 switch (**mangled) 1738 { 1739 case 'Q': 1740 success = demangle_qualified (work, mangled, declp, 0, 1); 1741 break; 1742 case 't': 1743 success = demangle_template (work, mangled, declp, 0, 1); 1744 break; 1745 default: 1746 n = consume_count (mangled); 1747 string_appendn (declp, *mangled, n); 1748 (*mangled) += n; 1749 } 1750 if (success && (p == *mangled)) 1751 { 1752 /* Consumed everything up to the cplus_marker, append the 1753 variable name. */ 1754 (*mangled)++; 1755 string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::"); 1756 n = strlen (*mangled); 1757 string_appendn (declp, *mangled, n); 1758 (*mangled) += n; 1759 } 1760 else 1761 { 1762 success = 0; 1763 } 1764 } 1765 else if (strncmp (*mangled, "__thunk_", 8) == 0) 1766 { 1767 int delta = ((*mangled) += 8, consume_count (mangled)); 1768 char *method = cplus_demangle (++*mangled, work->options); 1769 if (method) 1770 { 1771 char buf[50]; 1772 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); 1773 string_append (declp, buf); 1774 string_append (declp, method); 1775 free (method); 1776 n = strlen (*mangled); 1777 (*mangled) += n; 1778 } 1779 else 1780 { 1781 success = 0; 1782 } 1783 } 1784 else if (strncmp (*mangled, "__t", 3) == 0 1785 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) 1786 { 1787 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; 1788 (*mangled) += 4; 1789 switch (**mangled) 1790 { 1791 case 'Q': 1792 success = demangle_qualified (work, mangled, declp, 0, 1); 1793 break; 1794 case 't': 1795 success = demangle_template (work, mangled, declp, 0, 1); 1796 break; 1797 default: 1798 success = demangle_fund_type (work, mangled, declp); 1799 break; 1800 } 1801 if (success && **mangled != '\0') 1802 success = 0; 1803 if (success) 1804 string_append (declp, p); 1805 } 1806 else 1807 { 1808 success = 0; 1809 } 1810 return (success); 1811} 1812 1813/* 1814 1815LOCAL FUNCTION 1816 1817 arm_special -- special handling of ARM/lucid mangled strings 1818 1819SYNOPSIS 1820 1821 static int 1822 arm_special (struct work_stuff *work, const char **mangled, 1823 string *declp); 1824 1825 1826DESCRIPTION 1827 1828 Process some special ARM style mangling forms that don't fit 1829 the normal pattern. For example: 1830 1831 __vtbl__3foo (foo virtual table) 1832 __vtbl__3foo__3bar (bar::foo virtual table) 1833 1834 */ 1835 1836static int 1837arm_special (work, mangled, declp) 1838 struct work_stuff *work; 1839 const char **mangled; 1840 string *declp; 1841{ 1842 int n; 1843 int success = 1; 1844 const char *scan; 1845 1846 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) 1847 { 1848 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING 1849 and create the decl. Note that we consume the entire mangled 1850 input string, which means that demangle_signature has no work 1851 to do. */ 1852 scan = *mangled + ARM_VTABLE_STRLEN; 1853 while (*scan != '\0') /* first check it can be demangled */ 1854 { 1855 n = consume_count (&scan); 1856 if (n==0) 1857 { 1858 return (0); /* no good */ 1859 } 1860 scan += n; 1861 if (scan[0] == '_' && scan[1] == '_') 1862 { 1863 scan += 2; 1864 } 1865 } 1866 (*mangled) += ARM_VTABLE_STRLEN; 1867 while (**mangled != '\0') 1868 { 1869 n = consume_count (mangled); 1870 string_prependn (declp, *mangled, n); 1871 (*mangled) += n; 1872 if ((*mangled)[0] == '_' && (*mangled)[1] == '_') 1873 { 1874 string_prepend (declp, "::"); 1875 (*mangled) += 2; 1876 } 1877 } 1878 string_append (declp, " virtual table"); 1879 } 1880 else 1881 { 1882 success = 0; 1883 } 1884 return (success); 1885} 1886 1887/* 1888 1889LOCAL FUNCTION 1890 1891 demangle_qualified -- demangle 'Q' qualified name strings 1892 1893SYNOPSIS 1894 1895 static int 1896 demangle_qualified (struct work_stuff *, const char *mangled, 1897 string *result, int isfuncname, int append); 1898 1899DESCRIPTION 1900 1901 Demangle a qualified name, such as "Q25Outer5Inner" which is 1902 the mangled form of "Outer::Inner". The demangled output is 1903 prepended or appended to the result string according to the 1904 state of the append flag. 1905 1906 If isfuncname is nonzero, then the qualified name we are building 1907 is going to be used as a member function name, so if it is a 1908 constructor or destructor function, append an appropriate 1909 constructor or destructor name. I.E. for the above example, 1910 the result for use as a constructor is "Outer::Inner::Inner" 1911 and the result for use as a destructor is "Outer::Inner::~Inner". 1912 1913BUGS 1914 1915 Numeric conversion is ASCII dependent (FIXME). 1916 1917 */ 1918 1919static int 1920demangle_qualified (work, mangled, result, isfuncname, append) 1921 struct work_stuff *work; 1922 const char **mangled; 1923 string *result; 1924 int isfuncname; 1925 int append; 1926{ 1927 int qualifiers; 1928 int namelength; 1929 int success = 1; 1930 const char *p; 1931 char num[2]; 1932 string temp; 1933 1934 string_init (&temp); 1935 switch ((*mangled)[1]) 1936 { 1937 case '_': 1938 /* GNU mangled name with more than 9 classes. The count is preceded 1939 by an underscore (to distinguish it from the <= 9 case) and followed 1940 by an underscore. */ 1941 p = *mangled + 2; 1942 qualifiers = atoi (p); 1943 if (!isdigit (*p) || *p == '0') 1944 success = 0; 1945 1946 /* Skip the digits. */ 1947 while (isdigit (*p)) 1948 ++p; 1949 1950 if (*p != '_') 1951 success = 0; 1952 1953 *mangled = p + 1; 1954 break; 1955 1956 case '1': 1957 case '2': 1958 case '3': 1959 case '4': 1960 case '5': 1961 case '6': 1962 case '7': 1963 case '8': 1964 case '9': 1965 /* The count is in a single digit. */ 1966 num[0] = (*mangled)[1]; 1967 num[1] = '\0'; 1968 qualifiers = atoi (num); 1969 1970 /* If there is an underscore after the digit, skip it. This is 1971 said to be for ARM-qualified names, but the ARM makes no 1972 mention of such an underscore. Perhaps cfront uses one. */ 1973 if ((*mangled)[2] == '_') 1974 { 1975 (*mangled)++; 1976 } 1977 (*mangled) += 2; 1978 break; 1979 1980 case '0': 1981 default: 1982 success = 0; 1983 } 1984 1985 if (!success) 1986 return success; 1987 1988 /* Pick off the names and collect them in the temp buffer in the order 1989 in which they are found, separated by '::'. */ 1990 1991 while (qualifiers-- > 0) 1992 { 1993 if (*mangled[0] == '_') 1994 *mangled = *mangled + 1; 1995 if (*mangled[0] == 't') 1996 { 1997 success = demangle_template(work, mangled, &temp, 0, 1); 1998 if (!success) break; 1999 } 2000 else if (*mangled[0] == 'X') 2001 { 2002 success = do_type (work, mangled, &temp); 2003 if (!success) break; 2004 } 2005 else 2006 { 2007 namelength = consume_count (mangled); 2008 if (strlen (*mangled) < namelength) 2009 { 2010 /* Simple sanity check failed */ 2011 success = 0; 2012 break; 2013 } 2014 string_appendn (&temp, *mangled, namelength); 2015 *mangled += namelength; 2016 } 2017 if (qualifiers > 0) 2018 { 2019 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::"); 2020 } 2021 } 2022 2023 /* If we are using the result as a function name, we need to append 2024 the appropriate '::' separated constructor or destructor name. 2025 We do this here because this is the most convenient place, where 2026 we already have a pointer to the name and the length of the name. */ 2027 2028 if (isfuncname && (work->constructor & 1 || work->destructor & 1)) 2029 { 2030 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::"); 2031 if (work -> destructor & 1) 2032 { 2033 string_append (&temp, "~"); 2034 } 2035 string_appendn (&temp, (*mangled) - namelength, namelength); 2036 } 2037 2038 /* Now either prepend the temp buffer to the result, or append it, 2039 depending upon the state of the append flag. */ 2040 2041 if (append) 2042 { 2043 string_appends (result, &temp); 2044 } 2045 else 2046 { 2047 if (!STRING_EMPTY (result)) 2048 { 2049 string_append (&temp, (work -> options & DMGL_JAVA) ? "." : "::"); 2050 } 2051 string_prepends (result, &temp); 2052 } 2053 2054 string_delete (&temp); 2055 return (success); 2056} 2057 2058/* 2059 2060LOCAL FUNCTION 2061 2062 get_count -- convert an ascii count to integer, consuming tokens 2063 2064SYNOPSIS 2065 2066 static int 2067 get_count (const char **type, int *count) 2068 2069DESCRIPTION 2070 2071 Return 0 if no conversion is performed, 1 if a string is converted. 2072*/ 2073 2074static int 2075get_count (type, count) 2076 const char **type; 2077 int *count; 2078{ 2079 const char *p; 2080 int n; 2081 2082 if (!isdigit (**type)) 2083 { 2084 return (0); 2085 } 2086 else 2087 { 2088 *count = **type - '0'; 2089 (*type)++; 2090 if (isdigit (**type)) 2091 { 2092 p = *type; 2093 n = *count; 2094 do 2095 { 2096 n *= 10; 2097 n += *p - '0'; 2098 p++; 2099 } 2100 while (isdigit (*p)); 2101 if (*p == '_') 2102 { 2103 *type = p + 1; 2104 *count = n; 2105 } 2106 } 2107 } 2108 return (1); 2109} 2110 2111/* result will be initialised here; it will be freed on failure */ 2112 2113static int 2114do_type (work, mangled, result) 2115 struct work_stuff *work; 2116 const char **mangled; 2117 string *result; 2118{ 2119 int n; 2120 int done; 2121 int success; 2122 string decl; 2123 const char *remembered_type; 2124 int constp; 2125 int volatilep; 2126 2127 string_init (&decl); 2128 string_init (result); 2129 2130 done = 0; 2131 success = 1; 2132 while (success && !done) 2133 { 2134 int member; 2135 switch (**mangled) 2136 { 2137 2138 /* A pointer type */ 2139 case 'P': 2140 case 'p': 2141 (*mangled)++; 2142 if (! (work -> options & DMGL_JAVA)) 2143 string_prepend (&decl, "*"); 2144 break; 2145 2146 /* A reference type */ 2147 case 'R': 2148 (*mangled)++; 2149 string_prepend (&decl, "&"); 2150 break; 2151 2152 /* An array */ 2153 case 'A': 2154 { 2155 const char *p = ++(*mangled); 2156 2157 string_prepend (&decl, "("); 2158 string_append (&decl, ")["); 2159 /* Copy anything up until the next underscore (the size of the 2160 array). */ 2161 while (**mangled && **mangled != '_') 2162 ++(*mangled); 2163 if (**mangled == '_') 2164 { 2165 string_appendn (&decl, p, *mangled - p); 2166 string_append (&decl, "]"); 2167 *mangled += 1; 2168 } 2169 else 2170 success = 0; 2171 break; 2172 } 2173 2174 /* A back reference to a previously seen type */ 2175 case 'T': 2176 (*mangled)++; 2177 if (!get_count (mangled, &n) || n >= work -> ntypes) 2178 { 2179 success = 0; 2180 } 2181 else 2182 { 2183 remembered_type = work -> typevec[n]; 2184 mangled = &remembered_type; 2185 } 2186 break; 2187 2188 /* A function */ 2189 case 'F': 2190 (*mangled)++; 2191 if (!STRING_EMPTY (&decl) && decl.b[0] == '*') 2192 { 2193 string_prepend (&decl, "("); 2194 string_append (&decl, ")"); 2195 } 2196 /* After picking off the function args, we expect to either find the 2197 function return type (preceded by an '_') or the end of the 2198 string. */ 2199 if (!demangle_args (work, mangled, &decl) 2200 || (**mangled != '_' && **mangled != '\0')) 2201 { 2202 success = 0; 2203 } 2204 if (success && (**mangled == '_')) 2205 { 2206 (*mangled)++; 2207 } 2208 break; 2209 2210 case 'M': 2211 case 'O': 2212 { 2213 constp = 0; 2214 volatilep = 0; 2215 2216 member = **mangled == 'M'; 2217 (*mangled)++; 2218 if (!isdigit (**mangled) && **mangled != 't') 2219 { 2220 success = 0; 2221 break; 2222 } 2223 2224 string_append (&decl, ")"); 2225 string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::"); 2226 if (isdigit (**mangled)) 2227 { 2228 n = consume_count (mangled); 2229 if (strlen (*mangled) < n) 2230 { 2231 success = 0; 2232 break; 2233 } 2234 string_prependn (&decl, *mangled, n); 2235 *mangled += n; 2236 } 2237 else 2238 { 2239 string temp; 2240 string_init (&temp); 2241 success = demangle_template (work, mangled, &temp, NULL, 1); 2242 if (success) 2243 { 2244 string_prependn (&decl, temp.b, temp.p - temp.b); 2245 string_clear (&temp); 2246 } 2247 else 2248 break; 2249 } 2250 string_prepend (&decl, "("); 2251 if (member) 2252 { 2253 if (**mangled == 'C') 2254 { 2255 (*mangled)++; 2256 constp = 1; 2257 } 2258 if (**mangled == 'V') 2259 { 2260 (*mangled)++; 2261 volatilep = 1; 2262 } 2263 if (*(*mangled)++ != 'F') 2264 { 2265 success = 0; 2266 break; 2267 } 2268 } 2269 if ((member && !demangle_args (work, mangled, &decl)) 2270 || **mangled != '_') 2271 { 2272 success = 0; 2273 break; 2274 } 2275 (*mangled)++; 2276 if (! PRINT_ANSI_QUALIFIERS) 2277 { 2278 break; 2279 } 2280 if (constp) 2281 { 2282 APPEND_BLANK (&decl); 2283 string_append (&decl, "const"); 2284 } 2285 if (volatilep) 2286 { 2287 APPEND_BLANK (&decl); 2288 string_append (&decl, "volatile"); 2289 } 2290 break; 2291 } 2292 case 'G': 2293 (*mangled)++; 2294 break; 2295 2296 case 'C': 2297 (*mangled)++; 2298 /* 2299 if ((*mangled)[1] == 'P') 2300 { 2301 */ 2302 if (PRINT_ANSI_QUALIFIERS) 2303 { 2304 if (!STRING_EMPTY (&decl)) 2305 { 2306 string_prepend (&decl, " "); 2307 } 2308 string_prepend (&decl, "const"); 2309 } 2310 break; 2311 /* 2312 } 2313 */ 2314 2315 /* fall through */ 2316 default: 2317 done = 1; 2318 break; 2319 } 2320 } 2321 2322 switch (**mangled) 2323 { 2324 /* A qualified name, such as "Outer::Inner". */ 2325 case 'Q': 2326 success = demangle_qualified (work, mangled, result, 0, 1); 2327 break; 2328 2329 case 'X': 2330 case 'Y': 2331 /* A template parm. We substitute the corresponding argument. */ 2332 { 2333 int idx; 2334 int lvl; 2335 2336 (*mangled)++; 2337 idx = consume_count_with_underscores (mangled); 2338 2339 if (idx == -1 2340 || (work->tmpl_argvec && idx >= work->ntmpl_args) 2341 || consume_count_with_underscores (mangled) == -1) 2342 { 2343 success = 0; 2344 break; 2345 } 2346 2347 if (work->tmpl_argvec) 2348 string_append (result, work->tmpl_argvec[idx]); 2349 else 2350 { 2351 char buf[10]; 2352 sprintf(buf, "T%d", idx); 2353 string_append (result, buf); 2354 } 2355 2356 success = 1; 2357 } 2358 break; 2359 2360 default: 2361 success = demangle_fund_type (work, mangled, result); 2362 break; 2363 } 2364 2365 if (success) 2366 { 2367 if (!STRING_EMPTY (&decl)) 2368 { 2369 string_append (result, " "); 2370 string_appends (result, &decl); 2371 } 2372 } 2373 else 2374 { 2375 string_delete (result); 2376 } 2377 string_delete (&decl); 2378 return (success); 2379} 2380 2381/* Given a pointer to a type string that represents a fundamental type 2382 argument (int, long, unsigned int, etc) in TYPE, a pointer to the 2383 string in which the demangled output is being built in RESULT, and 2384 the WORK structure, decode the types and add them to the result. 2385 2386 For example: 2387 2388 "Ci" => "const int" 2389 "Sl" => "signed long" 2390 "CUs" => "const unsigned short" 2391 2392 */ 2393 2394static int 2395demangle_fund_type (work, mangled, result) 2396 struct work_stuff *work; 2397 const char **mangled; 2398 string *result; 2399{ 2400 int done = 0; 2401 int success = 1; 2402 2403 /* First pick off any type qualifiers. There can be more than one. */ 2404 2405 while (!done) 2406 { 2407 switch (**mangled) 2408 { 2409 case 'C': 2410 (*mangled)++; 2411 if (PRINT_ANSI_QUALIFIERS) 2412 { 2413 APPEND_BLANK (result); 2414 string_append (result, "const"); 2415 } 2416 break; 2417 case 'U': 2418 (*mangled)++; 2419 APPEND_BLANK (result); 2420 string_append (result, "unsigned"); 2421 break; 2422 case 'S': /* signed char only */ 2423 (*mangled)++; 2424 APPEND_BLANK (result); 2425 string_append (result, "signed"); 2426 break; 2427 case 'V': 2428 (*mangled)++; 2429 if (PRINT_ANSI_QUALIFIERS) 2430 { 2431 APPEND_BLANK (result); 2432 string_append (result, "volatile"); 2433 } 2434 break; 2435 case 'J': 2436 (*mangled)++; 2437 APPEND_BLANK (result); 2438 string_append (result, "__complex"); 2439 break; 2440 default: 2441 done = 1; 2442 break; 2443 } 2444 } 2445 2446 /* Now pick off the fundamental type. There can be only one. */ 2447 2448 switch (**mangled) 2449 { 2450 case '\0': 2451 case '_': 2452 break; 2453 case 'v': 2454 (*mangled)++; 2455 APPEND_BLANK (result); 2456 string_append (result, "void"); 2457 break; 2458 case 'x': 2459 (*mangled)++; 2460 APPEND_BLANK (result); 2461 string_append (result, "long long"); 2462 break; 2463 case 'l': 2464 (*mangled)++; 2465 APPEND_BLANK (result); 2466 string_append (result, "long"); 2467 break; 2468 case 'i': 2469 (*mangled)++; 2470 APPEND_BLANK (result); 2471 string_append (result, "int"); 2472 break; 2473 case 's': 2474 (*mangled)++; 2475 APPEND_BLANK (result); 2476 string_append (result, "short"); 2477 break; 2478 case 'b': 2479 (*mangled)++; 2480 APPEND_BLANK (result); 2481 string_append (result, "bool"); 2482 break; 2483 case 'c': 2484 (*mangled)++; 2485 APPEND_BLANK (result); 2486 string_append (result, "char"); 2487 break; 2488 case 'w': 2489 (*mangled)++; 2490 APPEND_BLANK (result); 2491 string_append (result, "wchar_t"); 2492 break; 2493 case 'r': 2494 (*mangled)++; 2495 APPEND_BLANK (result); 2496 string_append (result, "long double"); 2497 break; 2498 case 'd': 2499 (*mangled)++; 2500 APPEND_BLANK (result); 2501 string_append (result, "double"); 2502 break; 2503 case 'f': 2504 (*mangled)++; 2505 APPEND_BLANK (result); 2506 string_append (result, "float"); 2507 break; 2508 case 'G': 2509 (*mangled)++; 2510 if (!isdigit (**mangled)) 2511 { 2512 success = 0; 2513 break; 2514 } 2515 /* fall through */ 2516 /* An explicit type, such as "6mytype" or "7integer" */ 2517 case '0': 2518 case '1': 2519 case '2': 2520 case '3': 2521 case '4': 2522 case '5': 2523 case '6': 2524 case '7': 2525 case '8': 2526 case '9': 2527 APPEND_BLANK (result); 2528 if (!demangle_class_name (work, mangled, result)) { 2529 --result->p; 2530 success = 0; 2531 } 2532 break; 2533 case 't': 2534 success = demangle_template(work,mangled, result, 0, 1); 2535 break; 2536 default: 2537 success = 0; 2538 break; 2539 } 2540 2541 return (success); 2542} 2543 2544/* `result' will be initialized in do_type; it will be freed on failure */ 2545 2546static int 2547do_arg (work, mangled, result) 2548 struct work_stuff *work; 2549 const char **mangled; 2550 string *result; 2551{ 2552 const char *start = *mangled; 2553 2554 if (!do_type (work, mangled, result)) 2555 { 2556 return (0); 2557 } 2558 else 2559 { 2560 remember_type (work, start, *mangled - start); 2561 return (1); 2562 } 2563} 2564 2565static void 2566remember_type (work, start, len) 2567 struct work_stuff *work; 2568 const char *start; 2569 int len; 2570{ 2571 char *tem; 2572 2573 if (work -> ntypes >= work -> typevec_size) 2574 { 2575 if (work -> typevec_size == 0) 2576 { 2577 work -> typevec_size = 3; 2578 work -> typevec 2579 = (char **) xmalloc (sizeof (char *) * work -> typevec_size); 2580 } 2581 else 2582 { 2583 work -> typevec_size *= 2; 2584 work -> typevec 2585 = (char **) xrealloc ((char *)work -> typevec, 2586 sizeof (char *) * work -> typevec_size); 2587 } 2588 } 2589 tem = xmalloc (len + 1); 2590 memcpy (tem, start, len); 2591 tem[len] = '\0'; 2592 work -> typevec[work -> ntypes++] = tem; 2593} 2594 2595/* Forget the remembered types, but not the type vector itself. */ 2596 2597static void 2598forget_types (work) 2599 struct work_stuff *work; 2600{ 2601 int i; 2602 2603 while (work -> ntypes > 0) 2604 { 2605 i = --(work -> ntypes); 2606 if (work -> typevec[i] != NULL) 2607 { 2608 free (work -> typevec[i]); 2609 work -> typevec[i] = NULL; 2610 } 2611 } 2612} 2613 2614/* Process the argument list part of the signature, after any class spec 2615 has been consumed, as well as the first 'F' character (if any). For 2616 example: 2617 2618 "__als__3fooRT0" => process "RT0" 2619 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" 2620 2621 DECLP must be already initialised, usually non-empty. It won't be freed 2622 on failure. 2623 2624 Note that g++ differs significantly from ARM and lucid style mangling 2625 with regards to references to previously seen types. For example, given 2626 the source fragment: 2627 2628 class foo { 2629 public: 2630 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); 2631 }; 2632 2633 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 2634 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } 2635 2636 g++ produces the names: 2637 2638 __3fooiRT0iT2iT2 2639 foo__FiR3fooiT1iT1 2640 2641 while lcc (and presumably other ARM style compilers as well) produces: 2642 2643 foo__FiR3fooT1T2T1T2 2644 __ct__3fooFiR3fooT1T2T1T2 2645 2646 Note that g++ bases it's type numbers starting at zero and counts all 2647 previously seen types, while lucid/ARM bases it's type numbers starting 2648 at one and only considers types after it has seen the 'F' character 2649 indicating the start of the function args. For lucid/ARM style, we 2650 account for this difference by discarding any previously seen types when 2651 we see the 'F' character, and subtracting one from the type number 2652 reference. 2653 2654 */ 2655 2656static int 2657demangle_args (work, mangled, declp) 2658 struct work_stuff *work; 2659 const char **mangled; 2660 string *declp; 2661{ 2662 string arg; 2663 int need_comma = 0; 2664 int r; 2665 int t; 2666 const char *tem; 2667 char temptype; 2668 2669 if (PRINT_ARG_TYPES) 2670 { 2671 string_append (declp, "("); 2672 if (**mangled == '\0') 2673 { 2674 string_append (declp, "void"); 2675 } 2676 } 2677 2678 while (**mangled != '_' && **mangled != '\0' && **mangled != 'e') 2679 { 2680 if ((**mangled == 'N') || (**mangled == 'T')) 2681 { 2682 temptype = *(*mangled)++; 2683 2684 if (temptype == 'N') 2685 { 2686 if (!get_count (mangled, &r)) 2687 { 2688 return (0); 2689 } 2690 } 2691 else 2692 { 2693 r = 1; 2694 } 2695 if (ARM_DEMANGLING && work -> ntypes >= 10) 2696 { 2697 /* If we have 10 or more types we might have more than a 1 digit 2698 index so we'll have to consume the whole count here. This 2699 will lose if the next thing is a type name preceded by a 2700 count but it's impossible to demangle that case properly 2701 anyway. Eg if we already have 12 types is T12Pc "(..., type1, 2702 Pc, ...)" or "(..., type12, char *, ...)" */ 2703 if ((t = consume_count(mangled)) == 0) 2704 { 2705 return (0); 2706 } 2707 } 2708 else 2709 { 2710 if (!get_count (mangled, &t)) 2711 { 2712 return (0); 2713 } 2714 } 2715 if (LUCID_DEMANGLING || ARM_DEMANGLING) 2716 { 2717 t--; 2718 } 2719 /* Validate the type index. Protect against illegal indices from 2720 malformed type strings. */ 2721 if ((t < 0) || (t >= work -> ntypes)) 2722 { 2723 return (0); 2724 } 2725 while (--r >= 0) 2726 { 2727 tem = work -> typevec[t]; 2728 if (need_comma && PRINT_ARG_TYPES) 2729 { 2730 string_append (declp, ", "); 2731 } 2732 if (!do_arg (work, &tem, &arg)) 2733 { 2734 return (0); 2735 } 2736 if (PRINT_ARG_TYPES) 2737 { 2738 string_appends (declp, &arg); 2739 } 2740 string_delete (&arg); 2741 need_comma = 1; 2742 } 2743 } 2744 else 2745 { 2746 if (need_comma & PRINT_ARG_TYPES) 2747 { 2748 string_append (declp, ", "); 2749 } 2750 if (!do_arg (work, mangled, &arg)) 2751 { 2752 return (0); 2753 } 2754 if (PRINT_ARG_TYPES) 2755 { 2756 string_appends (declp, &arg); 2757 } 2758 string_delete (&arg); 2759 need_comma = 1; 2760 } 2761 } 2762 2763 if (**mangled == 'e') 2764 { 2765 (*mangled)++; 2766 if (PRINT_ARG_TYPES) 2767 { 2768 if (need_comma) 2769 { 2770 string_append (declp, ","); 2771 } 2772 string_append (declp, "..."); 2773 } 2774 } 2775 2776 if (PRINT_ARG_TYPES) 2777 { 2778 string_append (declp, ")"); 2779 } 2780 return (1); 2781} 2782 2783static void 2784demangle_function_name (work, mangled, declp, scan) 2785 struct work_stuff *work; 2786 const char **mangled; 2787 string *declp; 2788 const char *scan; 2789{ 2790 int i; 2791 int len; 2792 string type; 2793 const char *tem; 2794 2795 string_appendn (declp, (*mangled), scan - (*mangled)); 2796 string_need (declp, 1); 2797 *(declp -> p) = '\0'; 2798 2799 /* Consume the function name, including the "__" separating the name 2800 from the signature. We are guaranteed that SCAN points to the 2801 separator. */ 2802 2803 (*mangled) = scan + 2; 2804 2805 if (LUCID_DEMANGLING || ARM_DEMANGLING) 2806 { 2807 2808 /* See if we have an ARM style constructor or destructor operator. 2809 If so, then just record it, clear the decl, and return. 2810 We can't build the actual constructor/destructor decl until later, 2811 when we recover the class name from the signature. */ 2812 2813 if (strcmp (declp -> b, "__ct") == 0) 2814 { 2815 work -> constructor += 1; 2816 string_clear (declp); 2817 return; 2818 } 2819 else if (strcmp (declp -> b, "__dt") == 0) 2820 { 2821 work -> destructor += 1; 2822 string_clear (declp); 2823 return; 2824 } 2825 } 2826 2827 if (declp->p - declp->b >= 3 2828 && declp->b[0] == 'o' 2829 && declp->b[1] == 'p' 2830 && strchr (cplus_markers, declp->b[2]) != NULL) 2831 { 2832 /* see if it's an assignment expression */ 2833 if (declp->p - declp->b >= 10 /* op$assign_ */ 2834 && memcmp (declp->b + 3, "assign_", 7) == 0) 2835 { 2836 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 2837 { 2838 len = declp->p - declp->b - 10; 2839 if (strlen (optable[i].in) == len 2840 && memcmp (optable[i].in, declp->b + 10, len) == 0) 2841 { 2842 string_clear (declp); 2843 string_append (declp, "operator"); 2844 string_append (declp, optable[i].out); 2845 string_append (declp, "="); 2846 break; 2847 } 2848 } 2849 } 2850 else 2851 { 2852 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 2853 { 2854 int len = declp->p - declp->b - 3; 2855 if (strlen (optable[i].in) == len 2856 && memcmp (optable[i].in, declp->b + 3, len) == 0) 2857 { 2858 string_clear (declp); 2859 string_append (declp, "operator"); 2860 string_append (declp, optable[i].out); 2861 break; 2862 } 2863 } 2864 } 2865 } 2866 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 2867 && strchr (cplus_markers, declp->b[4]) != NULL) 2868 { 2869 /* type conversion operator */ 2870 tem = declp->b + 5; 2871 if (do_type (work, &tem, &type)) 2872 { 2873 string_clear (declp); 2874 string_append (declp, "operator "); 2875 string_appends (declp, &type); 2876 string_delete (&type); 2877 } 2878 } 2879 else if (declp->b[0] == '_' && declp->b[1] == '_' 2880 && declp->b[2] == 'o' && declp->b[3] == 'p') 2881 { 2882 /* ANSI. */ 2883 /* type conversion operator. */ 2884 tem = declp->b + 4; 2885 if (do_type (work, &tem, &type)) 2886 { 2887 string_clear (declp); 2888 string_append (declp, "operator "); 2889 string_appends (declp, &type); 2890 string_delete (&type); 2891 } 2892 } 2893 else if (declp->b[0] == '_' && declp->b[1] == '_' 2894 && declp->b[2] >= 'a' && declp->b[2] <= 'z' 2895 && declp->b[3] >= 'a' && declp->b[3] <= 'z') 2896 { 2897 if (declp->b[4] == '\0') 2898 { 2899 /* Operator. */ 2900 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 2901 { 2902 if (strlen (optable[i].in) == 2 2903 && memcmp (optable[i].in, declp->b + 2, 2) == 0) 2904 { 2905 string_clear (declp); 2906 string_append (declp, "operator"); 2907 string_append (declp, optable[i].out); 2908 break; 2909 } 2910 } 2911 } 2912 else 2913 { 2914 if (declp->b[2] == 'a' && declp->b[5] == '\0') 2915 { 2916 /* Assignment. */ 2917 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) 2918 { 2919 if (strlen (optable[i].in) == 3 2920 && memcmp (optable[i].in, declp->b + 2, 3) == 0) 2921 { 2922 string_clear (declp); 2923 string_append (declp, "operator"); 2924 string_append (declp, optable[i].out); 2925 break; 2926 } 2927 } 2928 } 2929 } 2930 } 2931} 2932 2933/* a mini string-handling package */ 2934 2935static void 2936string_need (s, n) 2937 string *s; 2938 int n; 2939{ 2940 int tem; 2941 2942 if (s->b == NULL) 2943 { 2944 if (n < 32) 2945 { 2946 n = 32; 2947 } 2948 s->p = s->b = xmalloc (n); 2949 s->e = s->b + n; 2950 } 2951 else if (s->e - s->p < n) 2952 { 2953 tem = s->p - s->b; 2954 n += tem; 2955 n *= 2; 2956 s->b = xrealloc (s->b, n); 2957 s->p = s->b + tem; 2958 s->e = s->b + n; 2959 } 2960} 2961 2962static void 2963string_delete (s) 2964 string *s; 2965{ 2966 if (s->b != NULL) 2967 { 2968 free (s->b); 2969 s->b = s->e = s->p = NULL; 2970 } 2971} 2972 2973static void 2974string_init (s) 2975 string *s; 2976{ 2977 s->b = s->p = s->e = NULL; 2978} 2979 2980static void 2981string_clear (s) 2982 string *s; 2983{ 2984 s->p = s->b; 2985} 2986 2987#if 0 2988 2989static int 2990string_empty (s) 2991 string *s; 2992{ 2993 return (s->b == s->p); 2994} 2995 2996#endif 2997 2998static void 2999string_append (p, s) 3000 string *p; 3001 const char *s; 3002{ 3003 int n; 3004 if (s == NULL || *s == '\0') 3005 return; 3006 n = strlen (s); 3007 string_need (p, n); 3008 memcpy (p->p, s, n); 3009 p->p += n; 3010} 3011 3012static void 3013string_appends (p, s) 3014 string *p, *s; 3015{ 3016 int n; 3017 3018 if (s->b != s->p) 3019 { 3020 n = s->p - s->b; 3021 string_need (p, n); 3022 memcpy (p->p, s->b, n); 3023 p->p += n; 3024 } 3025} 3026 3027static void 3028string_appendn (p, s, n) 3029 string *p; 3030 const char *s; 3031 int n; 3032{ 3033 if (n != 0) 3034 { 3035 string_need (p, n); 3036 memcpy (p->p, s, n); 3037 p->p += n; 3038 } 3039} 3040 3041static void 3042string_prepend (p, s) 3043 string *p; 3044 const char *s; 3045{ 3046 if (s != NULL && *s != '\0') 3047 { 3048 string_prependn (p, s, strlen (s)); 3049 } 3050} 3051 3052static void 3053string_prepends (p, s) 3054 string *p, *s; 3055{ 3056 if (s->b != s->p) 3057 { 3058 string_prependn (p, s->b, s->p - s->b); 3059 } 3060} 3061 3062static void 3063string_prependn (p, s, n) 3064 string *p; 3065 const char *s; 3066 int n; 3067{ 3068 char *q; 3069 3070 if (n != 0) 3071 { 3072 string_need (p, n); 3073 for (q = p->p - 1; q >= p->b; q--) 3074 { 3075 q[n] = q[0]; 3076 } 3077 memcpy (p->b, s, n); 3078 p->p += n; 3079 } 3080} 3081 3082/* To generate a standalone demangler program for testing purposes, 3083 just compile and link this file with -DMAIN and libiberty.a. When 3084 run, it demangles each command line arg, or each stdin string, and 3085 prints the result on stdout. */ 3086 3087#ifdef MAIN 3088 3089#include "getopt.h" 3090 3091static char *program_name; 3092static char *program_version = VERSION; 3093static int flags = DMGL_PARAMS | DMGL_ANSI; 3094 3095static void demangle_it PARAMS ((char *)); 3096static void usage PARAMS ((FILE *, int)); 3097static void fatal PARAMS ((char *)); 3098 3099static void 3100demangle_it (mangled_name) 3101 char *mangled_name; 3102{ 3103 char *result; 3104 3105 result = cplus_demangle (mangled_name, flags); 3106 if (result == NULL) 3107 { 3108 printf ("%s\n", mangled_name); 3109 } 3110 else 3111 { 3112 printf ("%s\n", result); 3113 free (result); 3114 } 3115} 3116 3117static void 3118usage (stream, status) 3119 FILE *stream; 3120 int status; 3121{ 3122 fprintf (stream, "\ 3123Usage: %s [-_] [-n] [-s {gnu,lucid,arm}] [--strip-underscores]\n\ 3124 [--no-strip-underscores] [--format={gnu,lucid,arm}]\n\ 3125 [--help] [--version] [arg...]\n", 3126 program_name); 3127 exit (status); 3128} 3129 3130#define MBUF_SIZE 512 3131char mbuffer[MBUF_SIZE]; 3132 3133/* Defined in the automatically-generated underscore.c. */ 3134extern int prepends_underscore; 3135 3136int strip_underscore = 0; 3137 3138static struct option long_options[] = { 3139 {"strip-underscores", no_argument, 0, '_'}, 3140 {"format", required_argument, 0, 's'}, 3141 {"help", no_argument, 0, 'h'}, 3142 {"java", no_argument, 0, 'j'}, 3143 {"no-strip-underscores", no_argument, 0, 'n'}, 3144 {"version", no_argument, 0, 'v'}, 3145 {0, no_argument, 0, 0} 3146}; 3147 3148int 3149main (argc, argv) 3150 int argc; 3151 char **argv; 3152{ 3153 char *result; 3154 int c; 3155 3156 program_name = argv[0]; 3157 3158 strip_underscore = prepends_underscore; 3159 3160 while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF) 3161 { 3162 switch (c) 3163 { 3164 case '?': 3165 usage (stderr, 1); 3166 break; 3167 case 'h': 3168 usage (stdout, 0); 3169 case 'n': 3170 strip_underscore = 0; 3171 break; 3172 case 'v': 3173 printf ("GNU %s version %s\n", program_name, program_version); 3174 exit (0); 3175 case '_': 3176 strip_underscore = 1; 3177 break; 3178 case 'j': 3179 flags |= DMGL_JAVA; 3180 break; 3181 case 's': 3182 if (strcmp (optarg, "gnu") == 0) 3183 { 3184 current_demangling_style = gnu_demangling; 3185 } 3186 else if (strcmp (optarg, "lucid") == 0) 3187 { 3188 current_demangling_style = lucid_demangling; 3189 } 3190 else if (strcmp (optarg, "arm") == 0) 3191 { 3192 current_demangling_style = arm_demangling; 3193 } 3194 else 3195 { 3196 fprintf (stderr, "%s: unknown demangling style `%s'\n", 3197 program_name, optarg); 3198 exit (1); 3199 } 3200 break; 3201 } 3202 } 3203 3204 if (optind < argc) 3205 { 3206 for ( ; optind < argc; optind++) 3207 { 3208 demangle_it (argv[optind]); 3209 } 3210 } 3211 else 3212 { 3213 for (;;) 3214 { 3215 int i = 0; 3216 c = getchar (); 3217 /* Try to read a label. */ 3218 while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.')) 3219 { 3220 if (i >= MBUF_SIZE-1) 3221 break; 3222 mbuffer[i++] = c; 3223 c = getchar (); 3224 } 3225 if (i > 0) 3226 { 3227 int skip_first = 0; 3228 3229 if (mbuffer[0] == '.') 3230 ++skip_first; 3231 if (strip_underscore && mbuffer[skip_first] == '_') 3232 ++skip_first; 3233 3234 if (skip_first > i) 3235 skip_first = i; 3236 3237 mbuffer[i] = 0; 3238 3239 result = cplus_demangle (mbuffer + skip_first, flags); 3240 if (result) 3241 { 3242 if (mbuffer[0] == '.') 3243 putc ('.', stdout); 3244 fputs (result, stdout); 3245 free (result); 3246 } 3247 else 3248 fputs (mbuffer, stdout); 3249 3250 fflush (stdout); 3251 } 3252 if (c == EOF) 3253 break; 3254 putchar (c); 3255 } 3256 } 3257 3258 exit (0); 3259} 3260 3261static void 3262fatal (str) 3263 char *str; 3264{ 3265 fprintf (stderr, "%s: %s\n", program_name, str); 3266 exit (1); 3267} 3268 3269char * malloc (); 3270char * realloc (); 3271 3272char * 3273xmalloc (size) 3274 unsigned size; 3275{ 3276 register char *value = (char *) malloc (size); 3277 if (value == 0) 3278 fatal ("virtual memory exhausted"); 3279 return value; 3280} 3281 3282char * 3283xrealloc (ptr, size) 3284 char *ptr; 3285 unsigned size; 3286{ 3287 register char *value = (char *) realloc (ptr, size); 3288 if (value == 0) 3289 fatal ("virtual memory exhausted"); 3290 return value; 3291} 3292#endif /* main */ 3293