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