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