cp-demangle.c revision 68765
1/* Demangler for IA64 / g++ standard C++ ABI. 2 Copyright (C) 2000 CodeSourcery LLC. 3 Written by Alex Samuel <samuel@codesourcery.com>. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18*/ 19 20/* This file implements demangling of C++ names mangled according to 21 the IA64 / g++ standard C++ ABI. Use the cp_demangle function to 22 demangle a mangled name, or compile with the preprocessor macro 23 STANDALONE_DEMANGLER defined to create a demangling filter 24 executable. */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include <sys/types.h> 31 32#ifdef HAVE_STDLIB_H 33#include <stdlib.h> 34#endif 35 36#include <stdio.h> 37 38#ifdef HAVE_STRING_H 39#include <string.h> 40#endif 41 42#include "ansidecl.h" 43#include "libiberty.h" 44#include "dyn-string.h" 45#include "demangle.h" 46 47/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation, 48 and other debugging output, will be generated. */ 49#ifdef CP_DEMANGLE_DEBUG 50#define DEMANGLE_TRACE(PRODUCTION, DM) \ 51 fprintf (stderr, " -> %-24s at position %3d\n", \ 52 (PRODUCTION), current_position (DM)); 53#else 54#define DEMANGLE_TRACE(PRODUCTION, DM) 55#endif 56 57/* Don't include <ctype.h>, to prevent additional unresolved symbols 58 from being dragged into the C++ runtime library. */ 59#define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9') 60#define IS_ALPHA(CHAR) \ 61 (((CHAR) >= 'a' && (CHAR) <= 'z') \ 62 || ((CHAR) >= 'A' && (CHAR) <= 'Z')) 63 64/* If flag_verbose is zero, some simplifications will be made to the 65 output to make it easier to read and supress details that are 66 generally not of interest to the average C++ programmer. 67 Otherwise, the demangled representation will attempt to convey as 68 much information as the mangled form. */ 69static int flag_verbose; 70 71/* If flag_strict is non-zero, demangle strictly according to the 72 specification -- don't demangle special g++ manglings. */ 73static int flag_strict; 74 75/* String_list_t is an extended form of dyn_string_t which provides a link 76 field. A string_list_t may safely be cast to and used as a 77 dyn_string_t. */ 78 79struct string_list_def 80{ 81 struct dyn_string string; 82 struct string_list_def *next; 83}; 84 85typedef struct string_list_def *string_list_t; 86 87/* Data structure representing a potential substitution. */ 88 89struct substitution_def 90{ 91 /* The demangled text of the substitution. */ 92 dyn_string_t text; 93 94 /* The template parameter that this represents, indexed from zero. 95 If this is not a template paramter number, the value is 96 NOT_TEMPLATE_PARM. */ 97 int template_parm_number; 98 99 /* Whether this substitution represents a template item. */ 100 int template_p : 1; 101}; 102 103#define NOT_TEMPLATE_PARM (-1) 104 105/* Data structure representing a template argument list. */ 106 107struct template_arg_list_def 108{ 109 /* The next (lower) template argument list in the stack of currently 110 active template arguments. */ 111 struct template_arg_list_def *next; 112 113 /* The first element in the list of template arguments in 114 left-to-right order. */ 115 string_list_t first_argument; 116 117 /* The last element in the arguments lists. */ 118 string_list_t last_argument; 119}; 120 121typedef struct template_arg_list_def *template_arg_list_t; 122 123/* Data structure to maintain the state of the current demangling. */ 124 125struct demangling_def 126{ 127 /* The full mangled name being mangled. */ 128 const char *name; 129 130 /* Pointer into name at the current position. */ 131 const char *next; 132 133 /* Stack for strings containing demangled result generated so far. 134 Text is emitted to the topmost (first) string. */ 135 string_list_t result; 136 137 /* The number of presently available substitutions. */ 138 int num_substitutions; 139 140 /* The allocated size of the substitutions array. */ 141 int substitutions_allocated; 142 143 /* An array of available substitutions. The number of elements in 144 the array is given by num_substitions, and the allocated array 145 size in substitutions_size. 146 147 The most recent substition is at the end, so 148 149 - `S_' corresponds to substititutions[num_substitutions - 1] 150 - `S0_' corresponds to substititutions[num_substitutions - 2] 151 152 etc. */ 153 struct substitution_def *substitutions; 154 155 /* The stack of template argument lists. */ 156 template_arg_list_t template_arg_lists; 157 158 /* The most recently demangled source-name. */ 159 dyn_string_t last_source_name; 160}; 161 162typedef struct demangling_def *demangling_t; 163 164/* This type is the standard return code from most functions. Values 165 other than STATUS_OK contain descriptive messages. */ 166typedef const char *status_t; 167 168/* Special values that can be used as a status_t. */ 169#define STATUS_OK NULL 170#define STATUS_ERROR "Error." 171#define STATUS_UNIMPLEMENTED "Unimplemented." 172#define STATUS_INTERNAL_ERROR "Internal error." 173 174/* This status code indicates a failure in malloc or realloc. */ 175static const char* const status_allocation_failed = "Allocation failed."; 176#define STATUS_ALLOCATION_FAILED status_allocation_failed 177 178/* Non-zero if STATUS indicates that no error has occurred. */ 179#define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK) 180 181/* Evaluate EXPR, which must produce a status_t. If the status code 182 indicates an error, return from the current function with that 183 status code. */ 184#define RETURN_IF_ERROR(EXPR) \ 185 do \ 186 { \ 187 status_t s = EXPR; \ 188 if (!STATUS_NO_ERROR (s)) \ 189 return s; \ 190 } \ 191 while (0) 192 193static status_t int_to_dyn_string 194 PARAMS ((int, dyn_string_t)); 195static string_list_t string_list_new 196 PARAMS ((int)); 197static void string_list_delete 198 PARAMS ((string_list_t)); 199static status_t result_close_template_list 200 PARAMS ((demangling_t)); 201static status_t result_push 202 PARAMS ((demangling_t)); 203static string_list_t result_pop 204 PARAMS ((demangling_t)); 205static int substitution_start 206 PARAMS ((demangling_t)); 207static status_t substitution_add 208 PARAMS ((demangling_t, int, int, int)); 209static dyn_string_t substitution_get 210 PARAMS ((demangling_t, int, int *)); 211#ifdef CP_DEMANGLE_DEBUG 212static void substitutions_print 213 PARAMS ((demangling_t, FILE *)); 214#endif 215static template_arg_list_t template_arg_list_new 216 PARAMS ((void)); 217static void template_arg_list_delete 218 PARAMS ((template_arg_list_t)); 219static void template_arg_list_add_arg 220 PARAMS ((template_arg_list_t, string_list_t)); 221static string_list_t template_arg_list_get_arg 222 PARAMS ((template_arg_list_t, int)); 223static void push_template_arg_list 224 PARAMS ((demangling_t, template_arg_list_t)); 225static void pop_to_template_arg_list 226 PARAMS ((demangling_t, template_arg_list_t)); 227#ifdef CP_DEMANGLE_DEBUG 228static void template_arg_list_print 229 PARAMS ((template_arg_list_t, FILE *)); 230#endif 231static template_arg_list_t current_template_arg_list 232 PARAMS ((demangling_t)); 233static demangling_t demangling_new 234 PARAMS ((const char *)); 235static void demangling_delete 236 PARAMS ((demangling_t)); 237 238/* The last character of DS. Warning: DS is evaluated twice. */ 239#define dyn_string_last_char(DS) \ 240 (dyn_string_buf (DS)[dyn_string_length (DS) - 1]) 241 242/* Append a space character (` ') to DS if it does not already end 243 with one. Evaluates to 1 on success, or 0 on allocation failure. */ 244#define dyn_string_append_space(DS) \ 245 ((dyn_string_length (DS) > 0 \ 246 && dyn_string_last_char (DS) != ' ') \ 247 ? dyn_string_append_char ((DS), ' ') \ 248 : 1) 249 250/* Returns the index of the current position in the mangled name. */ 251#define current_position(DM) ((DM)->next - (DM)->name) 252 253/* Returns the character at the current position of the mangled name. */ 254#define peek_char(DM) (*((DM)->next)) 255 256/* Returns the character one past the current position of the mangled 257 name. */ 258#define peek_char_next(DM) \ 259 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1))) 260 261/* Returns the character at the current position, and advances the 262 current position to the next character. */ 263#define next_char(DM) (*((DM)->next)++) 264 265/* Returns non-zero if the current position is the end of the mangled 266 name, i.e. one past the last character. */ 267#define end_of_name_p(DM) (peek_char (DM) == '\0') 268 269/* Advances the current position by one character. */ 270#define advance_char(DM) (++(DM)->next) 271 272/* Returns the string containing the current demangled result. */ 273#define result_string(DM) (&(DM)->result->string) 274 275/* Appends a dyn_string_t to the demangled result. */ 276#define result_append_string(DM, STRING) \ 277 (dyn_string_append (&(DM)->result->string, (STRING)) \ 278 ? STATUS_OK : STATUS_ALLOCATION_FAILED) 279 280/* Appends NUL-terminated string CSTR to the demangled result. */ 281#define result_append(DM, CSTR) \ 282 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \ 283 ? STATUS_OK : STATUS_ALLOCATION_FAILED) 284 285/* Appends character CHAR to the demangled result. */ 286#define result_append_char(DM, CHAR) \ 287 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \ 288 ? STATUS_OK : STATUS_ALLOCATION_FAILED) 289 290/* The length of the current demangled result. */ 291#define result_length(DM) \ 292 dyn_string_length (&(DM)->result->string) 293 294/* Appends a space to the demangled result if the last character is 295 not a space. */ 296#define result_append_space(DM) \ 297 (dyn_string_append_space (&(DM)->result->string) \ 298 ? STATUS_OK : STATUS_ALLOCATION_FAILED) 299 300/* Appends a base 10 representation of VALUE to DS. STATUS_OK on 301 success. On failure, deletes DS and returns an error code. */ 302 303static status_t 304int_to_dyn_string (value, ds) 305 int value; 306 dyn_string_t ds; 307{ 308 int i; 309 int mask = 1; 310 311 /* Handle zero up front. */ 312 if (value == 0) 313 { 314 if (!dyn_string_append_char (ds, '0')) 315 return STATUS_ALLOCATION_FAILED; 316 return STATUS_OK; 317 } 318 319 /* For negative numbers, emit a minus sign. */ 320 if (value < 0) 321 { 322 if (!dyn_string_append_char (ds, '-')) 323 return STATUS_ALLOCATION_FAILED; 324 value = -value; 325 } 326 327 /* Find the power of 10 of the first digit. */ 328 i = value; 329 while (i > 9) 330 { 331 mask *= 10; 332 i /= 10; 333 } 334 335 /* Write the digits. */ 336 while (mask > 0) 337 { 338 int digit = value / mask; 339 340 if (!dyn_string_append_char (ds, '0' + digit)) 341 return STATUS_ALLOCATION_FAILED; 342 343 value -= digit * mask; 344 mask /= 10; 345 } 346 347 return STATUS_OK; 348} 349 350/* Creates a new string list node. The contents of the string are 351 empty, but the initial buffer allocation is LENGTH. The string 352 list node should be deleted with string_list_delete. Returns NULL 353 if allocation fails. */ 354 355static string_list_t 356string_list_new (length) 357 int length; 358{ 359 string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def)); 360 if (s == NULL) 361 return NULL; 362 if (!dyn_string_init ((dyn_string_t) s, length)) 363 return NULL; 364 return s; 365} 366 367/* Deletes the entire string list starting at NODE. */ 368 369static void 370string_list_delete (node) 371 string_list_t node; 372{ 373 while (node != NULL) 374 { 375 string_list_t next = node->next; 376 free (node); 377 node = next; 378 } 379} 380 381/* Appends a greater-than character to the demangled result. If the 382 last character is a greater-than character, a space is inserted 383 first, so that the two greater-than characters don't look like a 384 right shift token. */ 385 386static status_t 387result_close_template_list (dm) 388 demangling_t dm; 389{ 390 dyn_string_t s = &dm->result->string; 391 392 /* Add a space if the last character is already a closing angle 393 bracket, so that a nested template arg list doesn't look like 394 it's closed with a right-shift operator. */ 395 if (dyn_string_last_char (s) == '>') 396 { 397 if (!dyn_string_append_char (s, ' ')) 398 return STATUS_ALLOCATION_FAILED; 399 } 400 401 /* Add closing angle brackets. */ 402 if (!dyn_string_append_char (s, '>')) 403 return STATUS_ALLOCATION_FAILED; 404 405 return STATUS_OK; 406} 407 408/* Allocates and pushes a new string onto the demangled results stack 409 for DM. Subsequent demangling with DM will emit to the new string. 410 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on 411 allocation failure. */ 412 413static status_t 414result_push (dm) 415 demangling_t dm; 416{ 417 string_list_t new_string = string_list_new (0); 418 if (new_string == NULL) 419 /* Allocation failed. */ 420 return STATUS_ALLOCATION_FAILED; 421 422 /* Link the new string to the front of the list of result strings. */ 423 new_string->next = (string_list_t) dm->result; 424 dm->result = new_string; 425 return STATUS_OK; 426} 427 428/* Removes and returns the topmost element on the demangled results 429 stack for DM. The caller assumes ownership for the returned 430 string. */ 431 432static string_list_t 433result_pop (dm) 434 demangling_t dm; 435{ 436 string_list_t top = dm->result; 437 dm->result = top->next; 438 return top; 439} 440 441/* Returns the start position of a fragment of the demangled result 442 that will be a substitution candidate. Should be called at the 443 start of productions that can add substitutions. */ 444 445static int 446substitution_start (dm) 447 demangling_t dm; 448{ 449 return result_length (dm); 450} 451 452/* Adds the suffix of the current demangled result of DM starting at 453 START_POSITION as a potential substitution. If TEMPLATE_P is 454 non-zero, this potential substitution is a template-id. 455 456 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution 457 is for that particular <template-param>, and is distinct from other 458 otherwise-identical types and other <template-param>s with 459 different indices. */ 460 461static status_t 462substitution_add (dm, start_position, template_p, template_parm_number) 463 demangling_t dm; 464 int start_position; 465 int template_p; 466 int template_parm_number; 467{ 468 dyn_string_t result = result_string (dm); 469 dyn_string_t substitution = dyn_string_new (0); 470 int i; 471 472 if (substitution == NULL) 473 return STATUS_ALLOCATION_FAILED; 474 475 /* Extract the substring of the current demangling result that 476 represents the subsitution candidate. */ 477 if (!dyn_string_substring (substitution, 478 result, start_position, result_length (dm))) 479 { 480 dyn_string_delete (substitution); 481 return STATUS_ALLOCATION_FAILED; 482 } 483 484 /* Check whether SUBSTITUTION already occurs. */ 485 for (i = 0; i < dm->num_substitutions; ++i) 486 if (dyn_string_eq (dm->substitutions[i].text, substitution) 487 && dm->substitutions[i].template_parm_number == template_parm_number) 488 /* Found SUBSTITUTION already present. */ 489 { 490 /* Callers expect this function to take ownership of 491 SUBSTITUTION, so delete it. */ 492 dyn_string_delete (substitution); 493 return STATUS_OK; 494 } 495 496 /* If there's no room for the new entry, grow the array. */ 497 if (dm->substitutions_allocated == dm->num_substitutions) 498 { 499 size_t new_array_size; 500 dm->substitutions_allocated *= 2; 501 new_array_size = 502 sizeof (struct substitution_def) * dm->substitutions_allocated; 503 504 dm->substitutions = (struct substitution_def *) 505 realloc (dm->substitutions, new_array_size); 506 if (dm->substitutions == NULL) 507 /* Realloc failed. */ 508 { 509 dyn_string_delete (substitution); 510 return STATUS_ALLOCATION_FAILED; 511 } 512 } 513 514 /* Add the substitution to the array. */ 515 dm->substitutions[i].text = substitution; 516 dm->substitutions[i].template_p = template_p; 517 dm->substitutions[i].template_parm_number = template_parm_number; 518 ++dm->num_substitutions; 519 520#ifdef CP_DEMANGLE_DEBUG 521 substitutions_print (dm, stderr); 522#endif 523 524 return STATUS_OK; 525} 526 527/* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to 528 non-zero if the substitution is a template-id, zero otherwise. 529 N is numbered from zero. DM retains ownership of the returned 530 string. If N is negative, or equal to or greater than the current 531 number of substitution candidates, returns NULL. */ 532 533static dyn_string_t 534substitution_get (dm, n, template_p) 535 demangling_t dm; 536 int n; 537 int *template_p; 538{ 539 struct substitution_def *sub; 540 541 /* Make sure N is in the valid range. */ 542 if (n < 0 || n >= dm->num_substitutions) 543 return NULL; 544 545 sub = &(dm->substitutions[n]); 546 *template_p = sub->template_p; 547 return sub->text; 548} 549 550#ifdef CP_DEMANGLE_DEBUG 551/* Debugging routine to print the current substitutions to FP. */ 552 553static void 554substitutions_print (dm, fp) 555 demangling_t dm; 556 FILE *fp; 557{ 558 int seq_id; 559 int num = dm->num_substitutions; 560 561 fprintf (fp, "SUBSTITUTIONS:\n"); 562 for (seq_id = -1; seq_id < num - 1; ++seq_id) 563 { 564 int template_p; 565 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p); 566 567 if (seq_id == -1) 568 fprintf (fp, " S_ "); 569 else 570 fprintf (fp, " S%d_", seq_id); 571 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text)); 572 } 573} 574 575#endif /* CP_DEMANGLE_DEBUG */ 576 577/* Creates a new template argument list. Returns NULL if allocation 578 fails. */ 579 580static template_arg_list_t 581template_arg_list_new () 582{ 583 template_arg_list_t new_list = 584 (template_arg_list_t) malloc (sizeof (struct template_arg_list_def)); 585 if (new_list == NULL) 586 return NULL; 587 /* Initialize the new list to have no arguments. */ 588 new_list->first_argument = NULL; 589 new_list->last_argument = NULL; 590 /* Return the new list. */ 591 return new_list; 592} 593 594/* Deletes a template argument list and the template arguments it 595 contains. */ 596 597static void 598template_arg_list_delete (list) 599 template_arg_list_t list; 600{ 601 /* If there are any arguments on LIST, delete them. */ 602 if (list->first_argument != NULL) 603 string_list_delete (list->first_argument); 604 /* Delete LIST. */ 605 free (list); 606} 607 608/* Adds ARG to the template argument list ARG_LIST. */ 609 610static void 611template_arg_list_add_arg (arg_list, arg) 612 template_arg_list_t arg_list; 613 string_list_t arg; 614{ 615 if (arg_list->first_argument == NULL) 616 /* If there were no arguments before, ARG is the first one. */ 617 arg_list->first_argument = arg; 618 else 619 /* Make ARG the last argument on the list. */ 620 arg_list->last_argument->next = arg; 621 /* Make ARG the last on the list. */ 622 arg_list->last_argument = arg; 623 arg->next = NULL; 624} 625 626/* Returns the template arugment at position INDEX in template 627 argument list ARG_LIST. */ 628 629static string_list_t 630template_arg_list_get_arg (arg_list, index) 631 template_arg_list_t arg_list; 632 int index; 633{ 634 string_list_t arg = arg_list->first_argument; 635 /* Scan down the list of arguments to find the one at position 636 INDEX. */ 637 while (index--) 638 { 639 arg = arg->next; 640 if (arg == NULL) 641 /* Ran out of arguments before INDEX hit zero. That's an 642 error. */ 643 return NULL; 644 } 645 /* Return the argument at position INDEX. */ 646 return arg; 647} 648 649/* Pushes ARG_LIST onto the top of the template argument list stack. */ 650 651static void 652push_template_arg_list (dm, arg_list) 653 demangling_t dm; 654 template_arg_list_t arg_list; 655{ 656 arg_list->next = dm->template_arg_lists; 657 dm->template_arg_lists = arg_list; 658#ifdef CP_DEMANGLE_DEBUG 659 fprintf (stderr, " ** pushing template arg list\n"); 660 template_arg_list_print (arg_list, stderr); 661#endif 662} 663 664/* Pops and deletes elements on the template argument list stack until 665 arg_list is the topmost element. If arg_list is NULL, all elements 666 are popped and deleted. */ 667 668static void 669pop_to_template_arg_list (dm, arg_list) 670 demangling_t dm; 671 template_arg_list_t arg_list; 672{ 673 while (dm->template_arg_lists != arg_list) 674 { 675 template_arg_list_t top = dm->template_arg_lists; 676 /* Disconnect the topmost element from the list. */ 677 dm->template_arg_lists = top->next; 678 /* Delete the popped element. */ 679 template_arg_list_delete (top); 680#ifdef CP_DEMANGLE_DEBUG 681 fprintf (stderr, " ** removing template arg list\n"); 682#endif 683 } 684} 685 686#ifdef CP_DEMANGLE_DEBUG 687 688/* Prints the contents of ARG_LIST to FP. */ 689 690static void 691template_arg_list_print (arg_list, fp) 692 template_arg_list_t arg_list; 693 FILE *fp; 694{ 695 string_list_t arg; 696 int index = -1; 697 698 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n"); 699 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next) 700 { 701 if (index == -1) 702 fprintf (fp, " T_ : "); 703 else 704 fprintf (fp, " T%d_ : ", index); 705 ++index; 706 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg)); 707 } 708} 709 710#endif /* CP_DEMANGLE_DEBUG */ 711 712/* Returns the topmost element on the stack of template argument 713 lists. If there is no list of template arguments, returns NULL. */ 714 715static template_arg_list_t 716current_template_arg_list (dm) 717 demangling_t dm; 718{ 719 return dm->template_arg_lists; 720} 721 722/* Allocates a demangling_t object for demangling mangled NAME. A new 723 result must be pushed before the returned object can be used. 724 Returns NULL if allocation fails. */ 725 726static demangling_t 727demangling_new (name) 728 const char *name; 729{ 730 demangling_t dm; 731 dm = (demangling_t) malloc (sizeof (struct demangling_def)); 732 if (dm == NULL) 733 return NULL; 734 735 dm->name = name; 736 dm->next = name; 737 dm->result = NULL; 738 dm->num_substitutions = 0; 739 dm->substitutions_allocated = 10; 740 dm->template_arg_lists = NULL; 741 dm->last_source_name = dyn_string_new (0); 742 if (dm->last_source_name == NULL) 743 return NULL; 744 dm->substitutions = (struct substitution_def *) 745 malloc (dm->substitutions_allocated * sizeof (struct substitution_def)); 746 if (dm->substitutions == NULL) 747 { 748 dyn_string_delete (dm->last_source_name); 749 return NULL; 750 } 751 752 return dm; 753} 754 755/* Deallocates a demangling_t object and all memory associated with 756 it. */ 757 758static void 759demangling_delete (dm) 760 demangling_t dm; 761{ 762 int i; 763 template_arg_list_t arg_list = dm->template_arg_lists; 764 765 /* Delete the stack of template argument lists. */ 766 while (arg_list != NULL) 767 { 768 template_arg_list_t next = arg_list->next; 769 template_arg_list_delete (arg_list); 770 arg_list = next; 771 } 772 /* Delete the list of substitutions. */ 773 for (i = dm->num_substitutions; --i >= 0; ) 774 dyn_string_delete (dm->substitutions[i].text); 775 free (dm->substitutions); 776 /* Delete the demangled result. */ 777 string_list_delete (dm->result); 778 /* Delete the stored identifier name. */ 779 dyn_string_delete (dm->last_source_name); 780 /* Delete the context object itself. */ 781 free (dm); 782} 783 784/* These functions demangle an alternative of the corresponding 785 production in the mangling spec. The first argument of each is a 786 demangling context structure for the current demangling 787 operation. Most emit demangled text directly to the topmost result 788 string on the result string stack in the demangling context 789 structure. */ 790 791static status_t demangle_char 792 PARAMS ((demangling_t, int)); 793static status_t demangle_mangled_name 794 PARAMS ((demangling_t)); 795static status_t demangle_encoding 796 PARAMS ((demangling_t)); 797static status_t demangle_name 798 PARAMS ((demangling_t, int *)); 799static status_t demangle_nested_name 800 PARAMS ((demangling_t, int *)); 801static status_t demangle_prefix 802 PARAMS ((demangling_t, int *)); 803static status_t demangle_unqualified_name 804 PARAMS ((demangling_t)); 805static status_t demangle_source_name 806 PARAMS ((demangling_t)); 807static status_t demangle_number 808 PARAMS ((demangling_t, int *, int, int)); 809static status_t demangle_number_literally 810 PARAMS ((demangling_t, dyn_string_t, int, int)); 811static status_t demangle_identifier 812 PARAMS ((demangling_t, int, dyn_string_t)); 813static status_t demangle_operator_name 814 PARAMS ((demangling_t, int, int *)); 815static status_t demangle_special_name 816 PARAMS ((demangling_t)); 817static status_t demangle_ctor_dtor_name 818 PARAMS ((demangling_t)); 819static status_t demangle_type_ptr 820 PARAMS ((demangling_t)); 821static status_t demangle_type 822 PARAMS ((demangling_t)); 823static status_t demangle_CV_qualifiers 824 PARAMS ((demangling_t, dyn_string_t)); 825static status_t demangle_builtin_type 826 PARAMS ((demangling_t)); 827static status_t demangle_function_type 828 PARAMS ((demangling_t, int)); 829static status_t demangle_bare_function_type 830 PARAMS ((demangling_t, int)); 831static status_t demangle_class_enum_type 832 PARAMS ((demangling_t, int *)); 833static status_t demangle_array_type 834 PARAMS ((demangling_t)); 835static status_t demangle_template_param 836 PARAMS ((demangling_t, int *)); 837static status_t demangle_template_args 838 PARAMS ((demangling_t)); 839static status_t demangle_literal 840 PARAMS ((demangling_t)); 841static status_t demangle_template_arg 842 PARAMS ((demangling_t)); 843static status_t demangle_expression 844 PARAMS ((demangling_t)); 845static status_t demangle_scope_expression 846 PARAMS ((demangling_t)); 847static status_t demangle_expr_primary 848 PARAMS ((demangling_t)); 849static status_t demangle_substitution 850 PARAMS ((demangling_t, int *, int *)); 851static status_t demangle_local_name 852 PARAMS ((demangling_t)); 853static status_t demangle_discriminator 854 PARAMS ((demangling_t, int)); 855static status_t cp_demangle 856 PARAMS ((const char *, dyn_string_t)); 857static status_t cp_demangle_type 858 PARAMS ((const char*, dyn_string_t)); 859 860/* When passed to demangle_bare_function_type, indicates that the 861 function's return type is not encoded before its parameter types. */ 862#define BFT_NO_RETURN_TYPE -1 863 864/* Check that the next character is C. If so, consume it. If not, 865 return an error. */ 866 867static status_t 868demangle_char (dm, c) 869 demangling_t dm; 870 int c; 871{ 872 static char *error_message = NULL; 873 874 if (peek_char (dm) == c) 875 { 876 advance_char (dm); 877 return STATUS_OK; 878 } 879 else 880 { 881 if (error_message == NULL) 882 error_message = strdup ("Expected ?"); 883 error_message[9] = c; 884 return error_message; 885 } 886} 887 888/* Demangles and emits a <mangled-name>. 889 890 <mangled-name> ::= _Z <encoding> */ 891 892static status_t 893demangle_mangled_name (dm) 894 demangling_t dm; 895{ 896 DEMANGLE_TRACE ("mangled-name", dm); 897 RETURN_IF_ERROR (demangle_char (dm, '_')); 898 RETURN_IF_ERROR (demangle_char (dm, 'Z')); 899 RETURN_IF_ERROR (demangle_encoding (dm)); 900 return STATUS_OK; 901} 902 903/* Demangles and emits an <encoding>. 904 905 <encoding> ::= <function name> <bare-function-type> 906 ::= <data name> 907 ::= <special-name> */ 908 909static status_t 910demangle_encoding (dm) 911 demangling_t dm; 912{ 913 int template_p; 914 int start_position; 915 template_arg_list_t old_arg_list = current_template_arg_list (dm); 916 char peek = peek_char (dm); 917 918 DEMANGLE_TRACE ("encoding", dm); 919 920 /* Remember where the name starts. If it turns out to be a template 921 function, we'll have to insert the return type here. */ 922 start_position = result_length (dm); 923 924 if (peek == 'G' || peek == 'T') 925 RETURN_IF_ERROR (demangle_special_name (dm)); 926 else 927 { 928 /* Now demangle the name. */ 929 RETURN_IF_ERROR (demangle_name (dm, &template_p)); 930 931 /* If there's anything left, the name was a function name, with 932 maybe its return type, and its parameters types, following. */ 933 if (!end_of_name_p (dm) 934 && peek_char (dm) != 'E') 935 { 936 if (template_p) 937 /* Template functions have their return type encoded. The 938 return type should be inserted at start_position. */ 939 RETURN_IF_ERROR 940 (demangle_bare_function_type (dm, start_position)); 941 else 942 /* Non-template functions don't have their return type 943 encoded. */ 944 RETURN_IF_ERROR 945 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE)); 946 } 947 } 948 949 /* Pop off template argument lists that were built during the 950 mangling of this name, to restore the old template context. */ 951 pop_to_template_arg_list (dm, old_arg_list); 952 953 return STATUS_OK; 954} 955 956/* Demangles and emits a <name>. 957 958 <name> ::= <unscoped-name> 959 ::= <unscoped-template-name> <template-args> 960 ::= <nested-name> 961 ::= <local-name> 962 963 <unscoped-name> ::= <unqualified-name> 964 ::= St <unqualified-name> # ::std:: 965 966 <unscoped-template-name> 967 ::= <unscoped-name> 968 ::= <substitution> */ 969 970static status_t 971demangle_name (dm, template_p) 972 demangling_t dm; 973 int *template_p; 974{ 975 int special_std_substitution; 976 int start = substitution_start (dm); 977 978 DEMANGLE_TRACE ("name", dm); 979 980 switch (peek_char (dm)) 981 { 982 case 'N': 983 /* This is a <nested-name>. */ 984 RETURN_IF_ERROR (demangle_nested_name (dm, template_p)); 985 break; 986 987 case 'Z': 988 RETURN_IF_ERROR (demangle_local_name (dm)); 989 break; 990 991 case 'S': 992 /* The `St' substitution allows a name nested in std:: to appear 993 without being enclosed in a nested name. */ 994 if (peek_char_next (dm) == 't') 995 { 996 (void) next_char (dm); 997 (void) next_char (dm); 998 RETURN_IF_ERROR (result_append (dm, "std::")); 999 RETURN_IF_ERROR (demangle_unqualified_name (dm)); 1000 } 1001 else 1002 { 1003 RETURN_IF_ERROR (demangle_substitution (dm, template_p, 1004 &special_std_substitution)); 1005 if (special_std_substitution) 1006 { 1007 /* This was the magic `std::' substitution. We can have 1008 a <nested-name> or one of the unscoped names 1009 following. */ 1010 RETURN_IF_ERROR (result_append (dm, "::")); 1011 RETURN_IF_ERROR (demangle_name (dm, template_p)); 1012 } 1013 } 1014 /* Check if a template argument list immediately follows. 1015 If so, then we just demangled an <unqualified-template-name>. */ 1016 if (peek_char (dm) == 'I') 1017 { 1018 RETURN_IF_ERROR (substitution_add (dm, start, 0, 1019 NOT_TEMPLATE_PARM)); 1020 RETURN_IF_ERROR (demangle_template_args (dm)); 1021 } 1022 break; 1023 1024 default: 1025 /* This is an <unscoped-name> or <unscoped-template-name>. */ 1026 RETURN_IF_ERROR (demangle_unqualified_name (dm)); 1027 1028 /* If the <unqualified-name> is followed by template args, this 1029 is an <unscoped-template-name>. */ 1030 if (peek_char (dm) == 'I') 1031 { 1032 /* Add a substitution for the unqualified template name. */ 1033 RETURN_IF_ERROR (substitution_add (dm, start, 0, 1034 NOT_TEMPLATE_PARM)); 1035 1036 RETURN_IF_ERROR (demangle_template_args (dm)); 1037 *template_p = 1; 1038 } 1039 else 1040 *template_p = 0; 1041 1042 break; 1043 } 1044 1045 return STATUS_OK; 1046} 1047 1048/* Demangles and emits a <nested-name>. 1049 1050 <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */ 1051 1052static status_t 1053demangle_nested_name (dm, template_p) 1054 demangling_t dm; 1055 int *template_p; 1056{ 1057 char peek; 1058 1059 DEMANGLE_TRACE ("nested-name", dm); 1060 1061 RETURN_IF_ERROR (demangle_char (dm, 'N')); 1062 1063 peek = peek_char (dm); 1064 if (peek == 'r' || peek == 'V' || peek == 'K') 1065 { 1066 status_t status; 1067 1068 /* Snarf up and emit CV qualifiers. */ 1069 dyn_string_t cv_qualifiers = dyn_string_new (24); 1070 if (cv_qualifiers == NULL) 1071 return STATUS_ALLOCATION_FAILED; 1072 1073 demangle_CV_qualifiers (dm, cv_qualifiers); 1074 status = result_append_string (dm, cv_qualifiers); 1075 dyn_string_delete (cv_qualifiers); 1076 RETURN_IF_ERROR (status); 1077 RETURN_IF_ERROR (result_append_space (dm)); 1078 } 1079 1080 RETURN_IF_ERROR (demangle_prefix (dm, template_p)); 1081 /* No need to demangle the final <component>; demangle_prefix will 1082 handle it. */ 1083 RETURN_IF_ERROR (demangle_char (dm, 'E')); 1084 1085 return STATUS_OK; 1086} 1087 1088/* Demangles and emits a <prefix>. 1089 1090 <prefix> ::= <prefix> <component> 1091 ::= <template-prefix> <template-args> 1092 ::= # empty 1093 ::= <substitution> 1094 1095 <template-prefix> ::= <prefix> 1096 ::= <substitution> 1097 1098 <component> ::= <unqualified-name> 1099 ::= <local-name> */ 1100 1101static status_t 1102demangle_prefix (dm, template_p) 1103 demangling_t dm; 1104 int *template_p; 1105{ 1106 int start = substitution_start (dm); 1107 int nested = 0; 1108 1109 /* TEMPLATE_P is updated as we decend the nesting chain. After 1110 <template-args>, it is set to non-zero; after everything else it 1111 is set to zero. */ 1112 1113 DEMANGLE_TRACE ("prefix", dm); 1114 1115 while (1) 1116 { 1117 char peek; 1118 int unused; 1119 1120 if (end_of_name_p (dm)) 1121 return "Unexpected end of name in <compound-name>."; 1122 1123 peek = peek_char (dm); 1124 1125 if (IS_DIGIT ((unsigned char) peek) 1126 || (peek >= 'a' && peek <= 'z') 1127 || peek == 'C' || peek == 'D' 1128 || peek == 'S') 1129 { 1130 /* We have another level of scope qualification. */ 1131 if (nested) 1132 RETURN_IF_ERROR (result_append (dm, "::")); 1133 else 1134 nested = 1; 1135 1136 if (peek == 'S') 1137 /* The substitution determines whether this is a 1138 template-id. */ 1139 RETURN_IF_ERROR (demangle_substitution (dm, template_p, 1140 &unused)); 1141 else 1142 { 1143 RETURN_IF_ERROR (demangle_unqualified_name (dm)); 1144 *template_p = 0; 1145 } 1146 } 1147 else if (peek == 'Z') 1148 RETURN_IF_ERROR (demangle_local_name (dm)); 1149 else if (peek == 'I') 1150 { 1151 if (*template_p) 1152 return STATUS_INTERNAL_ERROR; 1153 /* The template name is a substitution candidate. */ 1154 RETURN_IF_ERROR (substitution_add (dm, start, 0, NOT_TEMPLATE_PARM)); 1155 RETURN_IF_ERROR (demangle_template_args (dm)); 1156 *template_p = 1; 1157 } 1158 else if (peek == 'E') 1159 /* All done. */ 1160 return STATUS_OK; 1161 else 1162 return "Unexpected character in <compound-name>."; 1163 1164 /* Add a new substitution for the prefix thus far. */ 1165 RETURN_IF_ERROR (substitution_add (dm, start, *template_p, 1166 NOT_TEMPLATE_PARM)); 1167 } 1168} 1169 1170/* Demangles and emits an <unqualified-name>. If the 1171 <unqualified-name> is a function and the first element in the 1172 argument list should be taken to be its return type, 1173 ENCODE_RETURN_TYPE is non-zero. 1174 1175 <unqualified-name> ::= <operator-name> 1176 ::= <special-name> 1177 ::= <source-name> */ 1178 1179static status_t 1180demangle_unqualified_name (dm) 1181 demangling_t dm; 1182{ 1183 char peek = peek_char (dm); 1184 1185 DEMANGLE_TRACE ("unqualified-name", dm); 1186 1187 if (IS_DIGIT ((unsigned char) peek)) 1188 RETURN_IF_ERROR (demangle_source_name (dm)); 1189 else if (peek >= 'a' && peek <= 'z') 1190 { 1191 int num_args; 1192 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args)); 1193 } 1194 else if (peek == 'C' || peek == 'D') 1195 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm)); 1196 else 1197 return "Unexpected character in <unqualified-name>."; 1198 1199 return STATUS_OK; 1200} 1201 1202/* Demangles and emits <source-name>. 1203 1204 <source-name> ::= <length number> <identifier> */ 1205 1206static status_t 1207demangle_source_name (dm) 1208 demangling_t dm; 1209{ 1210 int length; 1211 1212 DEMANGLE_TRACE ("source-name", dm); 1213 1214 /* Decode the length of the identifier. */ 1215 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0)); 1216 if (length == 0) 1217 return "Zero length in <source-name>."; 1218 1219 /* Now the identifier itself. It's placed into last_source_name, 1220 where it can be used to build a constructor or destructor name. */ 1221 RETURN_IF_ERROR (demangle_identifier (dm, length, 1222 dm->last_source_name)); 1223 1224 /* Emit it. */ 1225 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); 1226 1227 return STATUS_OK; 1228} 1229 1230/* Demangles a number, either a <number> or a <positive-number> at the 1231 current position, consuming all consecutive digit characters. Sets 1232 *VALUE to the resulting numberand returns STATUS_OK. The number is 1233 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED 1234 is non-zero, negative numbers -- prefixed with `n' -- are accepted. 1235 1236 <number> ::= [n] <positive-number> 1237 1238 <positive-number> ::= <decimal integer> */ 1239 1240static status_t 1241demangle_number (dm, value, base, is_signed) 1242 demangling_t dm; 1243 int *value; 1244 int base; 1245 int is_signed; 1246{ 1247 dyn_string_t number = dyn_string_new (10); 1248 1249 DEMANGLE_TRACE ("number", dm); 1250 1251 if (number == NULL) 1252 return STATUS_ALLOCATION_FAILED; 1253 1254 demangle_number_literally (dm, number, base, is_signed); 1255 *value = strtol (dyn_string_buf (number), NULL, base); 1256 dyn_string_delete (number); 1257 1258 return STATUS_OK; 1259} 1260 1261/* Demangles a number at the current position. The digits (and minus 1262 sign, if present) that make up the number are appended to STR. 1263 Only base-BASE digits are accepted; BASE must be either 10 or 36. 1264 If IS_SIGNED, negative numbers -- prefixed with `n' -- are 1265 accepted. Does not consume a trailing underscore or other 1266 terminating character. */ 1267 1268static status_t 1269demangle_number_literally (dm, str, base, is_signed) 1270 demangling_t dm; 1271 dyn_string_t str; 1272 int base; 1273 int is_signed; 1274{ 1275 DEMANGLE_TRACE ("number*", dm); 1276 1277 if (base != 10 && base != 36) 1278 return STATUS_INTERNAL_ERROR; 1279 1280 /* An `n' denotes a negative number. */ 1281 if (is_signed && peek_char (dm) == 'n') 1282 { 1283 /* Skip past the n. */ 1284 advance_char (dm); 1285 /* The normal way to write a negative number is with a minus 1286 sign. */ 1287 if (!dyn_string_append_char (str, '-')) 1288 return STATUS_ALLOCATION_FAILED; 1289 } 1290 1291 /* Loop until we hit a non-digit. */ 1292 while (1) 1293 { 1294 char peek = peek_char (dm); 1295 if (IS_DIGIT ((unsigned char) peek) 1296 || (base == 36 && peek >= 'A' && peek <= 'Z')) 1297 { 1298 /* Accumulate digits. */ 1299 if (!dyn_string_append_char (str, next_char (dm))) 1300 return STATUS_ALLOCATION_FAILED; 1301 } 1302 else 1303 /* Not a digit? All done. */ 1304 break; 1305 } 1306 1307 return STATUS_OK; 1308} 1309 1310/* Demangles an identifier at the current position of LENGTH 1311 characters and places it in IDENTIFIER. */ 1312 1313static status_t 1314demangle_identifier (dm, length, identifier) 1315 demangling_t dm; 1316 int length; 1317 dyn_string_t identifier; 1318{ 1319 DEMANGLE_TRACE ("identifier", dm); 1320 1321 dyn_string_clear (identifier); 1322 if (!dyn_string_resize (identifier, length)) 1323 return STATUS_ALLOCATION_FAILED; 1324 1325 while (length-- > 0) 1326 { 1327 if (end_of_name_p (dm)) 1328 return "Unexpected end of name in <identifier>."; 1329 if (!dyn_string_append_char (identifier, next_char (dm))) 1330 return STATUS_ALLOCATION_FAILED; 1331 } 1332 1333 return STATUS_OK; 1334} 1335 1336/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero, 1337 the short form is emitted; otherwise the full source form 1338 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of 1339 operands that the operator takes. 1340 1341 <operator-name> 1342 ::= nw # new 1343 ::= na # new[] 1344 ::= dl # delete 1345 ::= da # delete[] 1346 ::= ps # + (unary) 1347 ::= ng # - (unary) 1348 ::= ad # & (unary) 1349 ::= de # * (unary) 1350 ::= co # ~ 1351 ::= pl # + 1352 ::= mi # - 1353 ::= ml # * 1354 ::= dv # / 1355 ::= rm # % 1356 ::= an # & 1357 ::= or # | 1358 ::= eo # ^ 1359 ::= aS # = 1360 ::= pL # += 1361 ::= mI # -= 1362 ::= mL # *= 1363 ::= dV # /= 1364 ::= rM # %= 1365 ::= aN # &= 1366 ::= oR # |= 1367 ::= eO # ^= 1368 ::= ls # << 1369 ::= rs # >> 1370 ::= lS # <<= 1371 ::= rS # >>= 1372 ::= eq # == 1373 ::= ne # != 1374 ::= lt # < 1375 ::= gt # > 1376 ::= le # <= 1377 ::= ge # >= 1378 ::= nt # ! 1379 ::= aa # && 1380 ::= oo # || 1381 ::= pp # ++ 1382 ::= mm # -- 1383 ::= cm # , 1384 ::= pm # ->* 1385 ::= pt # -> 1386 ::= cl # () 1387 ::= ix # [] 1388 ::= qu # ? 1389 ::= sz # sizeof 1390 ::= cv <type> # cast 1391 ::= vx <source-name> # vendor extended operator */ 1392 1393static status_t 1394demangle_operator_name (dm, short_name, num_args) 1395 demangling_t dm; 1396 int short_name; 1397 int *num_args; 1398{ 1399 struct operator_code 1400 { 1401 /* The mangled code for this operator. */ 1402 const char *code; 1403 /* The source name of this operator. */ 1404 const char *name; 1405 /* The number of arguments this operator takes. */ 1406 int num_args; 1407 }; 1408 1409 static const struct operator_code operators[] = 1410 { 1411 { "aN", "&=" , 2 }, 1412 { "aS", "=" , 2 }, 1413 { "aa", "&&" , 2 }, 1414 { "ad", "&" , 1 }, 1415 { "an", "&" , 2 }, 1416 { "cl", "()" , 0 }, 1417 { "cm", "," , 2 }, 1418 { "co", "~" , 1 }, 1419 { "dV", "/=" , 2 }, 1420 { "da", " delete[]", 1 }, 1421 { "de", "*" , 1 }, 1422 { "dl", " delete" , 1 }, 1423 { "dv", "/" , 2 }, 1424 { "eO", "^=" , 2 }, 1425 { "eo", "^" , 2 }, 1426 { "eq", "==" , 2 }, 1427 { "ge", ">=" , 2 }, 1428 { "gt", ">" , 2 }, 1429 { "ix", "[]" , 2 }, 1430 { "lS", "<<=" , 2 }, 1431 { "le", "<=" , 2 }, 1432 { "ls", "<<" , 2 }, 1433 { "lt", "<" , 2 }, 1434 { "mI", "-=" , 2 }, 1435 { "mL", "*=" , 2 }, 1436 { "mi", "-" , 2 }, 1437 { "ml", "*" , 2 }, 1438 { "mm", "--" , 1 }, 1439 { "na", " new[]" , 1 }, 1440 { "ne", "!=" , 2 }, 1441 { "ng", "-" , 1 }, 1442 { "nt", "!" , 1 }, 1443 { "nw", " new" , 1 }, 1444 { "oR", "|=" , 2 }, 1445 { "oo", "||" , 2 }, 1446 { "or", "|" , 2 }, 1447 { "pL", "+=" , 2 }, 1448 { "pl", "+" , 2 }, 1449 { "pm", "->*" , 2 }, 1450 { "pp", "++" , 1 }, 1451 { "ps", "+" , 1 }, 1452 { "qu", "?" , 3 }, 1453 { "rM", "%=" , 2 }, 1454 { "rS", ">>=" , 2 }, 1455 { "rm", "%" , 2 }, 1456 { "rs", ">>" , 2 }, 1457 { "sz", " sizeof" , 1 } 1458 }; 1459 1460 const int num_operators = 1461 sizeof (operators) / sizeof (struct operator_code); 1462 1463 int c0 = next_char (dm); 1464 int c1 = next_char (dm); 1465 const struct operator_code* p1 = operators; 1466 const struct operator_code* p2 = operators + num_operators; 1467 1468 DEMANGLE_TRACE ("operator-name", dm); 1469 1470 /* Is this a vendor extended operator? */ 1471 if (c0 == 'v' && c1 == 'x') 1472 { 1473 RETURN_IF_ERROR (result_append (dm, "operator")); 1474 RETURN_IF_ERROR (demangle_source_name (dm)); 1475 *num_args = 0; 1476 return STATUS_OK; 1477 } 1478 1479 /* Is this a conversion operator? */ 1480 if (c0 == 'c' && c1 == 'v') 1481 { 1482 RETURN_IF_ERROR (result_append (dm, "operator ")); 1483 /* Demangle the converted-to type. */ 1484 RETURN_IF_ERROR (demangle_type (dm)); 1485 *num_args = 0; 1486 return STATUS_OK; 1487 } 1488 1489 /* Perform a binary search for the operator code. */ 1490 while (1) 1491 { 1492 const struct operator_code* p = p1 + (p2 - p1) / 2; 1493 char match0 = p->code[0]; 1494 char match1 = p->code[1]; 1495 1496 if (c0 == match0 && c1 == match1) 1497 /* Found it. */ 1498 { 1499 if (!short_name) 1500 RETURN_IF_ERROR (result_append (dm, "operator")); 1501 RETURN_IF_ERROR (result_append (dm, p->name)); 1502 *num_args = p->num_args; 1503 1504 return STATUS_OK; 1505 } 1506 1507 if (p == p1) 1508 /* Couldn't find it. */ 1509 return "Unknown code in <operator-name>."; 1510 1511 /* Try again. */ 1512 if (c0 < match0 || (c0 == match0 && c1 < match1)) 1513 p2 = p; 1514 else 1515 p1 = p; 1516 } 1517} 1518 1519/* Demangles and emits a <special-name>. 1520 1521 <special-name> ::= GV <object name> # Guard variable 1522 ::= Th[n] <offset number> _ <base name> <base encoding> 1523 # non-virtual base override thunk 1524 ::= Tv[n] <offset number> _ <vcall offset number> 1525 _ <base encoding> 1526 # virtual base override thunk 1527 ::= TV <type> # virtual table 1528 ::= TT <type> # VTT 1529 ::= TI <type> # typeinfo structure 1530 ::= TS <type> # typeinfo name 1531 1532 Also demangles the special g++ manglings, 1533 1534 <special-name> ::= CT <type> <offset number> _ <base type> 1535 # construction vtable 1536 ::= TF <type> # typeinfo function (old ABI only) 1537 ::= TJ <type> # java Class structure */ 1538 1539static status_t 1540demangle_special_name (dm) 1541 demangling_t dm; 1542{ 1543 dyn_string_t number; 1544 int unused; 1545 char peek = peek_char (dm); 1546 1547 DEMANGLE_TRACE ("special-name", dm); 1548 1549 if (peek == 'G') 1550 { 1551 /* A guard variable name. Consume the G. */ 1552 advance_char (dm); 1553 RETURN_IF_ERROR (demangle_char (dm, 'V')); 1554 RETURN_IF_ERROR (result_append (dm, "guard variable for ")); 1555 RETURN_IF_ERROR (demangle_name (dm, &unused)); 1556 } 1557 else if (peek == 'T') 1558 { 1559 status_t status = STATUS_OK; 1560 1561 /* Other C++ implementation miscellania. Consume the T. */ 1562 advance_char (dm); 1563 1564 switch (peek_char (dm)) 1565 { 1566 case 'V': 1567 /* Virtual table. */ 1568 advance_char (dm); 1569 RETURN_IF_ERROR (result_append (dm, "vtable for ")); 1570 RETURN_IF_ERROR (demangle_type (dm)); 1571 break; 1572 1573 case 'T': 1574 /* VTT structure. */ 1575 advance_char (dm); 1576 RETURN_IF_ERROR (result_append (dm, "VTT for ")); 1577 RETURN_IF_ERROR (demangle_type (dm)); 1578 break; 1579 1580 case 'I': 1581 /* Typeinfo structure. */ 1582 advance_char (dm); 1583 RETURN_IF_ERROR (result_append (dm, "typeinfo for ")); 1584 RETURN_IF_ERROR (demangle_type (dm)); 1585 break; 1586 1587 case 'F': 1588 /* Typeinfo function. Used only in old ABI with new mangling. */ 1589 advance_char (dm); 1590 RETURN_IF_ERROR (result_append (dm, "typeinfo fn for ")); 1591 RETURN_IF_ERROR (demangle_type (dm)); 1592 break; 1593 1594 case 'S': 1595 /* Character string containing type name, used in typeinfo. */ 1596 advance_char (dm); 1597 RETURN_IF_ERROR (result_append (dm, "typeinfo name for ")); 1598 RETURN_IF_ERROR (demangle_type (dm)); 1599 break; 1600 1601 case 'J': 1602 /* The java Class variable corresponding to a C++ class. */ 1603 advance_char (dm); 1604 RETURN_IF_ERROR (result_append (dm, "java Class for ")); 1605 RETURN_IF_ERROR (demangle_type (dm)); 1606 break; 1607 1608 case 'h': 1609 /* Non-virtual thunk. */ 1610 advance_char (dm); 1611 RETURN_IF_ERROR (result_append (dm, "non-virtual thunk")); 1612 /* Demangle and emit the offset. */ 1613 number = dyn_string_new (4); 1614 if (number == NULL) 1615 return STATUS_ALLOCATION_FAILED; 1616 demangle_number_literally (dm, number, 10, 1); 1617 /* Don't display the offset unless in verbose mode. */ 1618 if (flag_verbose) 1619 { 1620 status = result_append_char (dm, ' '); 1621 if (STATUS_NO_ERROR (status)) 1622 status = result_append_string (dm, number); 1623 } 1624 dyn_string_delete (number); 1625 RETURN_IF_ERROR (status); 1626 /* Demangle the separator. */ 1627 RETURN_IF_ERROR (demangle_char (dm, '_')); 1628 /* Demangle and emit the target name and function type. */ 1629 RETURN_IF_ERROR (result_append (dm, " to ")); 1630 RETURN_IF_ERROR (demangle_encoding (dm)); 1631 break; 1632 1633 case 'v': 1634 /* Virtual thunk. */ 1635 advance_char (dm); 1636 RETURN_IF_ERROR (result_append (dm, "virtual thunk ")); 1637 /* Demangle and emit the offset. */ 1638 number = dyn_string_new (4); 1639 if (number == NULL) 1640 return STATUS_ALLOCATION_FAILED; 1641 demangle_number_literally (dm, number, 10, 1); 1642 /* Don't display the offset unless in verbose mode. */ 1643 if (flag_verbose) 1644 { 1645 status = result_append_string (dm, number); 1646 if (STATUS_NO_ERROR (status)) 1647 result_append_char (dm, ' '); 1648 } 1649 dyn_string_delete (number); 1650 RETURN_IF_ERROR (status); 1651 /* Demangle the separator. */ 1652 RETURN_IF_ERROR (demangle_char (dm, '_')); 1653 /* Demangle and emit the vcall offset. */ 1654 number = dyn_string_new (4); 1655 if (number == NULL) 1656 return STATUS_ALLOCATION_FAILED; 1657 demangle_number_literally (dm, number, 10, 1); 1658 /* Don't display the vcall offset unless in verbose mode. */ 1659 if (flag_verbose) 1660 { 1661 status = result_append_string (dm, number); 1662 if (STATUS_NO_ERROR (status)) 1663 status = result_append_char (dm, ' '); 1664 } 1665 dyn_string_delete (number); 1666 RETURN_IF_ERROR (status); 1667 /* Demangle the separator. */ 1668 RETURN_IF_ERROR (demangle_char (dm, '_')); 1669 /* Demangle and emit the target function. */ 1670 RETURN_IF_ERROR (result_append (dm, "to ")); 1671 RETURN_IF_ERROR (demangle_encoding (dm)); 1672 break; 1673 1674 case 'C': 1675 /* TC is a special g++ mangling for a construction vtable. */ 1676 if (!flag_strict) 1677 { 1678 dyn_string_t derived_type; 1679 1680 advance_char (dm); 1681 RETURN_IF_ERROR (result_append (dm, "construction vtable for ")); 1682 1683 /* Demangle the derived type off to the side. */ 1684 RETURN_IF_ERROR (result_push (dm)); 1685 RETURN_IF_ERROR (demangle_type (dm)); 1686 derived_type = (dyn_string_t) result_pop (dm); 1687 1688 /* Demangle the offset. */ 1689 number = dyn_string_new (4); 1690 if (number == NULL) 1691 { 1692 dyn_string_delete (derived_type); 1693 return STATUS_ALLOCATION_FAILED; 1694 } 1695 demangle_number_literally (dm, number, 10, 1); 1696 /* Demangle the underscore separator. */ 1697 status = demangle_char (dm, '_'); 1698 1699 /* Demangle the base type. */ 1700 if (STATUS_NO_ERROR (status)) 1701 status = demangle_type (dm); 1702 1703 /* Emit the derived type. */ 1704 if (STATUS_NO_ERROR (status)) 1705 status = result_append (dm, "-in-"); 1706 if (STATUS_NO_ERROR (status)) 1707 status = result_append_string (dm, derived_type); 1708 dyn_string_delete (derived_type); 1709 1710 /* Don't display the offset unless in verbose mode. */ 1711 if (flag_verbose) 1712 { 1713 status = result_append_char (dm, ' '); 1714 if (STATUS_NO_ERROR (status)) 1715 result_append_string (dm, number); 1716 } 1717 dyn_string_delete (number); 1718 RETURN_IF_ERROR (status); 1719 break; 1720 } 1721 /* If flag_strict, fall through. */ 1722 1723 default: 1724 return "Unrecognized <special-name>."; 1725 } 1726 } 1727 else 1728 return STATUS_ERROR; 1729 1730 return STATUS_OK; 1731} 1732 1733/* Demangles and emits a <ctor-dtor-name>. 1734 1735 <ctor-dtor-name> 1736 ::= C1 # complete object (in-charge) ctor 1737 ::= C2 # base object (not-in-charge) ctor 1738 ::= C3 # complete object (in-charge) allocating ctor 1739 ::= C4 # base object (not-in-charge) allocating ctor 1740 ::= D0 # deleting (in-charge) dtor 1741 ::= D1 # complete object (in-charge) dtor 1742 ::= D2 # base object (not-in-charge) dtor */ 1743 1744static status_t 1745demangle_ctor_dtor_name (dm) 1746 demangling_t dm; 1747{ 1748 static const char *const ctor_flavors[] = 1749 { 1750 "in-charge", 1751 "not-in-charge", 1752 "in-charge allocating", 1753 "not-in-charge allocating" 1754 }; 1755 static const char *const dtor_flavors[] = 1756 { 1757 "in-charge deleting", 1758 "in-charge", 1759 "not-in-charge" 1760 }; 1761 1762 int flavor; 1763 char peek = peek_char (dm); 1764 1765 DEMANGLE_TRACE ("ctor-dtor-name", dm); 1766 1767 if (peek == 'C') 1768 { 1769 /* A constructor name. Consume the C. */ 1770 advance_char (dm); 1771 if (peek_char (dm) < '1' || peek_char (dm) > '4') 1772 return "Unrecognized constructor."; 1773 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); 1774 /* Print the flavor of the constructor if in verbose mode. */ 1775 flavor = next_char (dm) - '1'; 1776 if (flag_verbose) 1777 { 1778 RETURN_IF_ERROR (result_append (dm, "[")); 1779 RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor])); 1780 RETURN_IF_ERROR (result_append_char (dm, ']')); 1781 } 1782 } 1783 else if (peek == 'D') 1784 { 1785 /* A destructor name. Consume the D. */ 1786 advance_char (dm); 1787 if (peek_char (dm) < '0' || peek_char (dm) > '2') 1788 return "Unrecognized destructor."; 1789 RETURN_IF_ERROR (result_append_char (dm, '~')); 1790 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); 1791 /* Print the flavor of the destructor if in verbose mode. */ 1792 flavor = next_char (dm) - '0'; 1793 if (flag_verbose) 1794 { 1795 RETURN_IF_ERROR (result_append (dm, " [")); 1796 RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor])); 1797 RETURN_IF_ERROR (result_append_char (dm, ']')); 1798 } 1799 } 1800 else 1801 return STATUS_ERROR; 1802 1803 return STATUS_OK; 1804} 1805 1806/* Handle pointer, reference, and pointer-to-member cases for 1807 demangle_type. All consecutive `P's, `R's, and 'M's are joined to 1808 build a pointer/reference type. We snarf all these, plus the 1809 following <type>, all at once since we need to know whether we have 1810 a pointer to data or pointer to function to construct the right 1811 output syntax. C++'s pointer syntax is hairy. 1812 1813 <type> ::= P <type> 1814 ::= R <type> 1815 ::= <pointer-to-member-type> 1816 1817 <pointer-to-member-type> ::= M </class/ type> </member/ type> */ 1818 1819static status_t 1820demangle_type_ptr (dm) 1821 demangling_t dm; 1822{ 1823 char next; 1824 status_t status; 1825 1826 /* Collect pointer symbols into this string. */ 1827 dyn_string_t symbols = dyn_string_new (10); 1828 1829 DEMANGLE_TRACE ("type*", dm); 1830 1831 if (symbols == NULL) 1832 return STATUS_ALLOCATION_FAILED; 1833 1834 /* Scan forward, collecting pointers and references into symbols, 1835 until we hit something else. Then emit the type. */ 1836 while (1) 1837 { 1838 next = peek_char (dm); 1839 if (next == 'P') 1840 { 1841 if (!dyn_string_append_char (symbols, '*')) 1842 return STATUS_ALLOCATION_FAILED; 1843 advance_char (dm); 1844 } 1845 else if (next == 'R') 1846 { 1847 if (!dyn_string_append_char (symbols, '&')) 1848 return STATUS_ALLOCATION_FAILED; 1849 advance_char (dm); 1850 } 1851 else if (next == 'M') 1852 { 1853 /* Pointer-to-member. */ 1854 dyn_string_t class_type; 1855 1856 /* Eat the 'M'. */ 1857 advance_char (dm); 1858 1859 /* Capture the type of which this is a pointer-to-member. */ 1860 RETURN_IF_ERROR (result_push (dm)); 1861 RETURN_IF_ERROR (demangle_type (dm)); 1862 class_type = (dyn_string_t) result_pop (dm); 1863 1864 /* Build the pointer-to-member notation. It comes before 1865 other pointer and reference qualifiers -- */ 1866 if (!dyn_string_prepend_cstr (symbols, "::*")) 1867 return STATUS_ALLOCATION_FAILED; 1868 if (!dyn_string_prepend (symbols, class_type)) 1869 return STATUS_ALLOCATION_FAILED; 1870 dyn_string_delete (class_type); 1871 1872 if (peek_char (dm) == 'F') 1873 continue; 1874 1875 /* Demangle the type of the pointed-to member. */ 1876 status = demangle_type (dm); 1877 /* Make it pretty. */ 1878 if (STATUS_NO_ERROR (status)) 1879 status = result_append_space (dm); 1880 /* Add the pointer-to-member syntax, and other pointer and 1881 reference symbols. */ 1882 if (STATUS_NO_ERROR (status)) 1883 status = result_append_string (dm, symbols); 1884 /* Clean up. */ 1885 dyn_string_delete (symbols); 1886 1887 RETURN_IF_ERROR (status); 1888 return STATUS_OK; 1889 } 1890 else if (next == 'F') 1891 { 1892 /* Ooh, tricky, a pointer-to-function. */ 1893 int position = result_length (dm); 1894 status = result_append_char (dm, '('); 1895 if (STATUS_NO_ERROR (status)) 1896 status = result_append_string (dm, symbols); 1897 if (STATUS_NO_ERROR (status)) 1898 status = result_append_char (dm, ')'); 1899 dyn_string_delete (symbols); 1900 RETURN_IF_ERROR (status); 1901 1902 RETURN_IF_ERROR (demangle_function_type (dm, position)); 1903 return STATUS_OK; 1904 } 1905 else 1906 { 1907 /* No more pointe or reference tokens. Finish up. */ 1908 status = demangle_type (dm); 1909 1910 if (STATUS_NO_ERROR (status)) 1911 status = result_append_string (dm, symbols); 1912 dyn_string_delete (symbols); 1913 RETURN_IF_ERROR (status); 1914 1915 RETURN_IF_ERROR (status); 1916 return STATUS_OK; 1917 } 1918 } 1919} 1920 1921/* Demangles and emits a <type>. 1922 1923 <type> ::= <builtin-type> 1924 ::= <function-type> 1925 ::= <class-enum-type> 1926 ::= <array-type> 1927 ::= <pointer-to-member-type> 1928 ::= <template-param> 1929 ::= <CV-qualifiers> <type> 1930 ::= P <type> # pointer-to 1931 ::= R <type> # reference-to 1932 ::= C <type> # complex pair (C 2000) 1933 ::= G <type> # imaginary (C 2000) 1934 ::= U <source-name> <type> # vendor extended type qualifier 1935 ::= <substitution> */ 1936 1937static status_t 1938demangle_type (dm) 1939 demangling_t dm; 1940{ 1941 int start = substitution_start (dm); 1942 char peek = peek_char (dm); 1943 char peek_next; 1944 int template_p = 0; 1945 int special_std_substitution; 1946 int is_builtin_type = 0; 1947 template_arg_list_t old_arg_list = current_template_arg_list (dm); 1948 int template_parm = NOT_TEMPLATE_PARM; 1949 1950 DEMANGLE_TRACE ("type", dm); 1951 1952 /* A <class-enum-type> can start with a digit (a <source-name>), an 1953 N (a <nested-name>), or a Z (a <local-name>). */ 1954 if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z') 1955 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p)); 1956 else if (peek >= 'a' && peek <= 'z') 1957 { 1958 RETURN_IF_ERROR (demangle_builtin_type (dm)); 1959 is_builtin_type = 1; 1960 } 1961 else 1962 switch (peek) 1963 { 1964 case 'r': 1965 case 'V': 1966 case 'K': 1967 { 1968 status_t status; 1969 dyn_string_t cv_qualifiers = dyn_string_new (24); 1970 1971 if (cv_qualifiers == NULL) 1972 return STATUS_ALLOCATION_FAILED; 1973 1974 demangle_CV_qualifiers (dm, cv_qualifiers); 1975 1976 /* If the qualifiers apply to a pointer or reference, they 1977 need to come after the whole qualified type. */ 1978 if (peek_char (dm) == 'P' || peek_char (dm) == 'R') 1979 { 1980 status = demangle_type (dm); 1981 if (STATUS_NO_ERROR (status)) 1982 status = result_append_space (dm); 1983 if (STATUS_NO_ERROR (status)) 1984 status = result_append_string (dm, cv_qualifiers); 1985 } 1986 /* Otherwise, the qualifiers come first. */ 1987 else 1988 { 1989 status = result_append_string (dm, cv_qualifiers); 1990 if (STATUS_NO_ERROR (status)) 1991 status = result_append_space (dm); 1992 if (STATUS_NO_ERROR (status)) 1993 status = demangle_type (dm); 1994 } 1995 1996 dyn_string_delete (cv_qualifiers); 1997 RETURN_IF_ERROR (status); 1998 } 1999 break; 2000 2001 case 'F': 2002 return "Non-pointer or -reference function type."; 2003 2004 case 'A': 2005 RETURN_IF_ERROR (demangle_array_type (dm)); 2006 break; 2007 2008 case 'T': 2009 RETURN_IF_ERROR (demangle_template_param (dm, &template_parm)); 2010 break; 2011 2012 case 'S': 2013 /* First check if this is a special substitution. If it is, 2014 this is a <class-enum-type>. Special substitutions have a 2015 letter following the `S'; other substitutions have a digit 2016 or underscore. */ 2017 peek_next = peek_char_next (dm); 2018 if (IS_DIGIT (peek_next) || peek_next == '_') 2019 RETURN_IF_ERROR (demangle_substitution (dm, &template_p, 2020 &special_std_substitution)); 2021 else 2022 demangle_class_enum_type (dm, &template_p); 2023 break; 2024 2025 case 'P': 2026 case 'R': 2027 case 'M': 2028 RETURN_IF_ERROR (demangle_type_ptr (dm)); 2029 break; 2030 2031 case 'C': 2032 /* A C99 complex type. */ 2033 RETURN_IF_ERROR (result_append (dm, "complex ")); 2034 advance_char (dm); 2035 RETURN_IF_ERROR (demangle_type (dm)); 2036 break; 2037 2038 case 'G': 2039 /* A C99 imaginary type. */ 2040 RETURN_IF_ERROR (result_append (dm, "imaginary ")); 2041 advance_char (dm); 2042 RETURN_IF_ERROR (demangle_type (dm)); 2043 break; 2044 2045 case 'U': 2046 /* Vendor extended type qualifier. */ 2047 advance_char (dm); 2048 RETURN_IF_ERROR (demangle_source_name (dm)); 2049 RETURN_IF_ERROR (result_append_char (dm, ' ')); 2050 RETURN_IF_ERROR (demangle_type (dm)); 2051 break; 2052 2053 default: 2054 return "Unexpected character in <type>."; 2055 } 2056 2057 /* Unqualified builin types are not substitution candidates. */ 2058 if (!is_builtin_type) 2059 /* Add a new substitution for the type. If this type was a 2060 <template-param>, pass its index since from the point of 2061 substitutions, a <template-param> token is a substitution 2062 candidate distinct from the type that is substituted for it. */ 2063 RETURN_IF_ERROR (substitution_add (dm, start, template_p, template_parm)); 2064 2065 /* Pop off template argument lists added during mangling of this 2066 type. */ 2067 pop_to_template_arg_list (dm, old_arg_list); 2068 2069 return STATUS_OK; 2070} 2071 2072/* C++ source names of builtin types, indexed by the mangled code 2073 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */ 2074static const char *const builtin_type_names[26] = 2075{ 2076 "signed char", /* a */ 2077 "bool", /* b */ 2078 "char", /* c */ 2079 "double", /* d */ 2080 "long double", /* e */ 2081 "float", /* f */ 2082 "__float128", /* g */ 2083 "unsigned char", /* h */ 2084 "int", /* i */ 2085 "unsigned", /* j */ 2086 NULL, /* k */ 2087 "long", /* l */ 2088 "unsigned long", /* m */ 2089 "__int128", /* n */ 2090 "unsigned __int128", /* o */ 2091 NULL, /* p */ 2092 NULL, /* q */ 2093 NULL, /* r */ 2094 "short", /* s */ 2095 "unsigned short", /* t */ 2096 NULL, /* u */ 2097 "void", /* v */ 2098 "wchar_t", /* w */ 2099 "long long", /* x */ 2100 "unsigned long long", /* y */ 2101 "..." /* z */ 2102}; 2103 2104/* Demangles and emits a <builtin-type>. 2105 2106 <builtin-type> ::= v # void 2107 ::= w # wchar_t 2108 ::= b # bool 2109 ::= c # char 2110 ::= a # signed char 2111 ::= h # unsigned char 2112 ::= s # short 2113 ::= t # unsigned short 2114 ::= i # int 2115 ::= j # unsigned int 2116 ::= l # long 2117 ::= m # unsigned long 2118 ::= x # long long, __int64 2119 ::= y # unsigned long long, __int64 2120 ::= n # __int128 2121 ::= o # unsigned __int128 2122 ::= f # float 2123 ::= d # double 2124 ::= e # long double, __float80 2125 ::= g # __float128 2126 ::= z # ellipsis 2127 ::= u <source-name> # vendor extended type */ 2128 2129static status_t 2130demangle_builtin_type (dm) 2131 demangling_t dm; 2132{ 2133 2134 char code = peek_char (dm); 2135 2136 DEMANGLE_TRACE ("builtin-type", dm); 2137 2138 if (code == 'u') 2139 { 2140 advance_char (dm); 2141 RETURN_IF_ERROR (demangle_source_name (dm)); 2142 return STATUS_OK; 2143 } 2144 else if (code >= 'a' && code <= 'z') 2145 { 2146 const char *type_name = builtin_type_names[code - 'a']; 2147 if (type_name == NULL) 2148 return "Unrecognized <builtin-type> code."; 2149 2150 RETURN_IF_ERROR (result_append (dm, type_name)); 2151 advance_char (dm); 2152 return STATUS_OK; 2153 } 2154 else 2155 return "Non-alphabetic <builtin-type> code."; 2156} 2157 2158/* Demangles all consecutive CV-qualifiers (const, volatile, and 2159 restrict) at the current position. The qualifiers are appended to 2160 QUALIFIERS. Returns STATUS_OK. */ 2161 2162static status_t 2163demangle_CV_qualifiers (dm, qualifiers) 2164 demangling_t dm; 2165 dyn_string_t qualifiers; 2166{ 2167 DEMANGLE_TRACE ("CV-qualifiers", dm); 2168 2169 while (1) 2170 { 2171 switch (peek_char (dm)) 2172 { 2173 case 'r': 2174 if (!dyn_string_append_space (qualifiers)) 2175 return STATUS_ALLOCATION_FAILED; 2176 if (!dyn_string_append_cstr (qualifiers, "restrict")) 2177 return STATUS_ALLOCATION_FAILED; 2178 break; 2179 2180 case 'V': 2181 if (!dyn_string_append_space (qualifiers)) 2182 return STATUS_ALLOCATION_FAILED; 2183 if (!dyn_string_append_cstr (qualifiers, "volatile")) 2184 return STATUS_ALLOCATION_FAILED; 2185 break; 2186 2187 case 'K': 2188 if (!dyn_string_append_space (qualifiers)) 2189 return STATUS_ALLOCATION_FAILED; 2190 if (!dyn_string_append_cstr (qualifiers, "const")) 2191 return STATUS_ALLOCATION_FAILED; 2192 break; 2193 2194 default: 2195 return STATUS_OK; 2196 } 2197 2198 advance_char (dm); 2199 } 2200} 2201 2202/* Demangles and emits a <function-type> FUNCTION_NAME_POS is the 2203 position in the result string of the start of the function 2204 identifier, at which the function's return type will be inserted. 2205 2206 <function-type> ::= F [Y] <bare-function-type> E */ 2207 2208static status_t 2209demangle_function_type (dm, function_name_pos) 2210 demangling_t dm; 2211 int function_name_pos; 2212{ 2213 DEMANGLE_TRACE ("function-type", dm); 2214 RETURN_IF_ERROR (demangle_char (dm, 'F')); 2215 if (peek_char (dm) == 'Y') 2216 { 2217 /* Indicate this function has C linkage if in verbose mode. */ 2218 if (flag_verbose) 2219 RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] ")); 2220 advance_char (dm); 2221 } 2222 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos)); 2223 RETURN_IF_ERROR (demangle_char (dm, 'E')); 2224 return STATUS_OK; 2225} 2226 2227/* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the 2228 position in the result string at which the function return type 2229 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the 2230 function's return type is assumed not to be encoded. 2231 2232 <bare-function-type> ::= <signature type>+ */ 2233 2234static status_t 2235demangle_bare_function_type (dm, return_type_pos) 2236 demangling_t dm; 2237 int return_type_pos; 2238{ 2239 /* Sequence is the index of the current function parameter, counting 2240 from zero. The value -1 denotes the return type. */ 2241 int sequence = 2242 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1); 2243 2244 DEMANGLE_TRACE ("bare-function-type", dm); 2245 2246 RETURN_IF_ERROR (result_append_char (dm, '(')); 2247 while (!end_of_name_p (dm) && peek_char (dm) != 'E') 2248 { 2249 if (sequence == -1) 2250 /* We're decoding the function's return type. */ 2251 { 2252 dyn_string_t return_type; 2253 status_t status = STATUS_OK; 2254 2255 /* Decode the return type off to the side. */ 2256 RETURN_IF_ERROR (result_push (dm)); 2257 RETURN_IF_ERROR (demangle_type (dm)); 2258 return_type = (dyn_string_t) result_pop (dm); 2259 2260 /* Add a space to the end of the type. Insert the return 2261 type where we've been asked to. */ 2262 if (!dyn_string_append_space (return_type) 2263 || !dyn_string_insert (result_string (dm), return_type_pos, 2264 return_type)) 2265 status = STATUS_ALLOCATION_FAILED; 2266 2267 dyn_string_delete (return_type); 2268 RETURN_IF_ERROR (status); 2269 } 2270 else 2271 { 2272 /* Skip `void' parameter types. One should only occur as 2273 the only type in a parameter list; in that case, we want 2274 to print `foo ()' instead of `foo (void)'. */ 2275 if (peek_char (dm) == 'v') 2276 { 2277 /* Consume the v. */ 2278 advance_char (dm); 2279 continue; 2280 } 2281 /* Separate parameter types by commas. */ 2282 if (sequence > 0) 2283 RETURN_IF_ERROR (result_append (dm, ", ")); 2284 /* Demangle the type. */ 2285 RETURN_IF_ERROR (demangle_type (dm)); 2286 } 2287 2288 ++sequence; 2289 } 2290 RETURN_IF_ERROR (result_append_char (dm, ')')); 2291 2292 return STATUS_OK; 2293} 2294 2295/* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to 2296 non-zero if the type is a template-id, zero otherwise. 2297 2298 <class-enum-type> ::= <name> */ 2299 2300static status_t 2301demangle_class_enum_type (dm, template_p) 2302 demangling_t dm; 2303 int *template_p; 2304{ 2305 DEMANGLE_TRACE ("class-enum-type", dm); 2306 2307 RETURN_IF_ERROR (demangle_name (dm, template_p)); 2308 return STATUS_OK; 2309} 2310 2311/* Demangles and emits an <array-type>. 2312 2313 <array-type> ::= A [<dimension number>] _ <element type> */ 2314 2315static status_t 2316demangle_array_type (dm) 2317 demangling_t dm; 2318{ 2319 status_t status; 2320 dyn_string_t array_size = dyn_string_new (10); 2321 2322 if (array_size == NULL) 2323 return STATUS_ALLOCATION_FAILED; 2324 2325 status = demangle_char (dm, 'A'); 2326 2327 /* Demangle the array size into array_size. */ 2328 if (STATUS_NO_ERROR (status)) 2329 status = demangle_number_literally (dm, array_size, 10, 0); 2330 2331 /* Demangle the base type of the array. */ 2332 if (STATUS_NO_ERROR (status)) 2333 status = demangle_char (dm, '_'); 2334 if (STATUS_NO_ERROR (status)) 2335 status = demangle_type (dm); 2336 2337 /* Emit the array dimension syntax. */ 2338 if (STATUS_NO_ERROR (status)) 2339 status = result_append_char (dm, '['); 2340 if (STATUS_NO_ERROR (status)) 2341 status = result_append_string (dm, array_size); 2342 if (STATUS_NO_ERROR (status)) 2343 status = result_append_char (dm, ']'); 2344 dyn_string_delete (array_size); 2345 2346 RETURN_IF_ERROR (status); 2347 2348 return STATUS_OK; 2349} 2350 2351/* Demangles and emits a <template-param>. The zero-indexed position 2352 in the parameter list is placed in *TEMPLATE_PARM_NUMBER. 2353 2354 <template-param> ::= T_ # first template parameter 2355 ::= T <parameter-2 number> _ */ 2356 2357static status_t 2358demangle_template_param (dm, template_parm_number) 2359 demangling_t dm; 2360 int *template_parm_number; 2361{ 2362 int parm_number; 2363 template_arg_list_t current_arg_list = current_template_arg_list (dm); 2364 string_list_t arg; 2365 2366 DEMANGLE_TRACE ("template-param", dm); 2367 2368 /* Make sure there is a template argmust list in which to look up 2369 this parameter reference. */ 2370 if (current_arg_list == NULL) 2371 return "Template parameter outside of template."; 2372 2373 RETURN_IF_ERROR (demangle_char (dm, 'T')); 2374 if (peek_char (dm) == '_') 2375 parm_number = 0; 2376 else 2377 { 2378 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0)); 2379 ++parm_number; 2380 } 2381 RETURN_IF_ERROR (demangle_char (dm, '_')); 2382 2383 arg = template_arg_list_get_arg (current_arg_list, parm_number); 2384 if (arg == NULL) 2385 /* parm_number exceeded the number of arguments in the current 2386 template argument list. */ 2387 return "Template parameter number out of bounds."; 2388 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg)); 2389 2390 if (peek_char (dm) == 'I') 2391 RETURN_IF_ERROR (demangle_template_args (dm)); 2392 2393 *template_parm_number = parm_number; 2394 return STATUS_OK; 2395} 2396 2397/* Demangles and emits a <template-args>. 2398 2399 <template-args> ::= I <template-arg>+ E */ 2400 2401static status_t 2402demangle_template_args (dm) 2403 demangling_t dm; 2404{ 2405 int first = 1; 2406 dyn_string_t old_last_source_name; 2407 template_arg_list_t arg_list = template_arg_list_new (); 2408 2409 if (arg_list == NULL) 2410 return STATUS_ALLOCATION_FAILED; 2411 2412 /* Preserve the most recently demangled source name. */ 2413 old_last_source_name = dm->last_source_name; 2414 dm->last_source_name = dyn_string_new (0); 2415 2416 DEMANGLE_TRACE ("template-args", dm); 2417 2418 if (dm->last_source_name == NULL) 2419 return STATUS_ALLOCATION_FAILED; 2420 2421 RETURN_IF_ERROR (demangle_char (dm, 'I')); 2422 RETURN_IF_ERROR (result_append_char (dm, '<')); 2423 do 2424 { 2425 string_list_t arg; 2426 2427 if (first) 2428 first = 0; 2429 else 2430 RETURN_IF_ERROR (result_append (dm, ", ")); 2431 2432 /* Capture the template arg. */ 2433 RETURN_IF_ERROR (result_push (dm)); 2434 RETURN_IF_ERROR (demangle_template_arg (dm)); 2435 arg = result_pop (dm); 2436 2437 /* Emit it in the demangled name. */ 2438 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg)); 2439 2440 /* Save it for use in expanding <template-param>s. */ 2441 template_arg_list_add_arg (arg_list, arg); 2442 } 2443 while (peek_char (dm) != 'E'); 2444 /* Append the '>'. */ 2445 RETURN_IF_ERROR (result_close_template_list (dm)); 2446 2447 /* Consume the 'E'. */ 2448 advance_char (dm); 2449 2450 /* Restore the most recent demangled source name. */ 2451 dyn_string_delete (dm->last_source_name); 2452 dm->last_source_name = old_last_source_name; 2453 2454 /* Push the list onto the top of the stack of template argument 2455 lists, so that arguments from it are used from now on when 2456 expanding <template-param>s. */ 2457 push_template_arg_list (dm, arg_list); 2458 2459 return STATUS_OK; 2460} 2461 2462/* This function, which does not correspond to a production in the 2463 mangling spec, handles the `literal' production for both 2464 <template-arg> and <expr-primary>. It does not expect or consume 2465 the initial `L' or final `E'. The demangling is given by: 2466 2467 <literal> ::= <type> </value/ number> 2468 2469 and the emitted output is `(type)number'. */ 2470 2471static status_t 2472demangle_literal (dm) 2473 demangling_t dm; 2474{ 2475 char peek = peek_char (dm); 2476 dyn_string_t value_string; 2477 status_t status; 2478 2479 DEMANGLE_TRACE ("literal", dm); 2480 2481 if (!flag_verbose && peek >= 'a' && peek <= 'z') 2482 { 2483 /* If not in verbose mode and this is a builtin type, see if we 2484 can produce simpler numerical output. In particular, for 2485 integer types shorter than `long', just write the number 2486 without type information; for bools, write `true' or `false'. 2487 Other refinements could be made here too. */ 2488 2489 /* This constant string is used to map from <builtin-type> codes 2490 (26 letters of the alphabet) to codes that determine how the 2491 value will be displayed. The codes are: 2492 b: display as bool 2493 i: display as int 2494 l: display as long 2495 A space means the value will be represented using cast 2496 notation. */ 2497 static const char *const code_map = "ibi iii ll ii i "; 2498 2499 char code = code_map[peek - 'a']; 2500 /* FIXME: Implement demangling of floats and doubles. */ 2501 if (code == 'u') 2502 return STATUS_UNIMPLEMENTED; 2503 if (code == 'b') 2504 { 2505 /* It's a boolean. */ 2506 char value; 2507 2508 /* Consume the b. */ 2509 advance_char (dm); 2510 /* Look at the next character. It should be 0 or 1, 2511 corresponding to false or true, respectively. */ 2512 value = peek_char (dm); 2513 if (value == '0') 2514 RETURN_IF_ERROR (result_append (dm, "false")); 2515 else if (value == '1') 2516 RETURN_IF_ERROR (result_append (dm, "true")); 2517 else 2518 return "Unrecognized bool constant."; 2519 /* Consume the 0 or 1. */ 2520 advance_char (dm); 2521 return STATUS_OK; 2522 } 2523 else if (code == 'i' || code == 'l') 2524 { 2525 /* It's an integer or long. */ 2526 2527 /* Consume the type character. */ 2528 advance_char (dm); 2529 2530 /* Demangle the number and write it out. */ 2531 value_string = dyn_string_new (0); 2532 status = demangle_number_literally (dm, value_string, 10, 1); 2533 if (STATUS_NO_ERROR (status)) 2534 status = result_append_string (dm, value_string); 2535 /* For long integers, append an l. */ 2536 if (code == 'l' && STATUS_NO_ERROR (status)) 2537 status = result_append_char (dm, code); 2538 dyn_string_delete (value_string); 2539 2540 RETURN_IF_ERROR (status); 2541 return STATUS_OK; 2542 } 2543 /* ...else code == ' ', so fall through to represent this 2544 literal's type explicitly using cast syntax. */ 2545 } 2546 2547 RETURN_IF_ERROR (result_append_char (dm, '(')); 2548 RETURN_IF_ERROR (demangle_type (dm)); 2549 RETURN_IF_ERROR (result_append_char (dm, ')')); 2550 2551 value_string = dyn_string_new (0); 2552 if (value_string == NULL) 2553 return STATUS_ALLOCATION_FAILED; 2554 2555 status = demangle_number_literally (dm, value_string, 10, 1); 2556 if (STATUS_NO_ERROR (status)) 2557 status = result_append_string (dm, value_string); 2558 dyn_string_delete (value_string); 2559 RETURN_IF_ERROR (status); 2560 2561 return STATUS_OK; 2562} 2563 2564/* Demangles and emits a <template-arg>. 2565 2566 <template-arg> ::= <type> # type 2567 ::= L <type> <value number> E # literal 2568 ::= LZ <encoding> E # external name 2569 ::= X <expression> E # expression */ 2570 2571static status_t 2572demangle_template_arg (dm) 2573 demangling_t dm; 2574{ 2575 DEMANGLE_TRACE ("template-arg", dm); 2576 2577 switch (peek_char (dm)) 2578 { 2579 case 'L': 2580 advance_char (dm); 2581 2582 if (peek_char (dm) == 'Z') 2583 { 2584 /* External name. */ 2585 advance_char (dm); 2586 /* FIXME: Standard is contradictory here. */ 2587 RETURN_IF_ERROR (demangle_encoding (dm)); 2588 } 2589 else 2590 RETURN_IF_ERROR (demangle_literal (dm)); 2591 RETURN_IF_ERROR (demangle_char (dm, 'E')); 2592 break; 2593 2594 case 'X': 2595 /* Expression. */ 2596 advance_char (dm); 2597 RETURN_IF_ERROR (demangle_expression (dm)); 2598 break; 2599 2600 default: 2601 RETURN_IF_ERROR (demangle_type (dm)); 2602 break; 2603 } 2604 2605 return STATUS_OK; 2606} 2607 2608/* Demangles and emits an <expression>. 2609 2610 <expression> ::= <unary operator-name> <expression> 2611 ::= <binary operator-name> <expression> <expression> 2612 ::= <expr-primary> 2613 ::= <scope-expression> */ 2614 2615static status_t 2616demangle_expression (dm) 2617 demangling_t dm; 2618{ 2619 char peek = peek_char (dm); 2620 2621 DEMANGLE_TRACE ("expression", dm); 2622 2623 if (peek == 'L' || peek == 'T') 2624 RETURN_IF_ERROR (demangle_expr_primary (dm)); 2625 else if (peek == 's' && peek_char_next (dm) == 'r') 2626 RETURN_IF_ERROR (demangle_scope_expression (dm)); 2627 else 2628 /* An operator expression. */ 2629 { 2630 int num_args; 2631 status_t status = STATUS_OK; 2632 dyn_string_t operator_name; 2633 2634 /* We have an operator name. Since we want to output binary 2635 operations in infix notation, capture the operator name 2636 first. */ 2637 RETURN_IF_ERROR (result_push (dm)); 2638 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args)); 2639 operator_name = (dyn_string_t) result_pop (dm); 2640 2641 /* If it's binary, do an operand first. */ 2642 if (num_args > 1) 2643 { 2644 status = result_append_char (dm, '('); 2645 if (STATUS_NO_ERROR (status)) 2646 status = demangle_expression (dm); 2647 if (STATUS_NO_ERROR (status)) 2648 status = result_append_char (dm, ')'); 2649 } 2650 2651 /* Emit the operator. */ 2652 if (STATUS_NO_ERROR (status)) 2653 status = result_append_string (dm, operator_name); 2654 dyn_string_delete (operator_name); 2655 RETURN_IF_ERROR (status); 2656 2657 /* Emit its second (if binary) or only (if unary) operand. */ 2658 RETURN_IF_ERROR (result_append_char (dm, '(')); 2659 RETURN_IF_ERROR (demangle_expression (dm)); 2660 RETURN_IF_ERROR (result_append_char (dm, ')')); 2661 2662 /* The ternary operator takes a third operand. */ 2663 if (num_args == 3) 2664 { 2665 RETURN_IF_ERROR (result_append (dm, ":(")); 2666 RETURN_IF_ERROR (demangle_expression (dm)); 2667 RETURN_IF_ERROR (result_append_char (dm, ')')); 2668 } 2669 } 2670 2671 return STATUS_OK; 2672} 2673 2674/* Demangles and emits a <scope-expression>. 2675 2676 <scope-expression> ::= sr <qualifying type> <source-name> 2677 ::= sr <qualifying type> <encoding> */ 2678 2679static status_t 2680demangle_scope_expression (dm) 2681 demangling_t dm; 2682{ 2683 RETURN_IF_ERROR (demangle_char (dm, 's')); 2684 RETURN_IF_ERROR (demangle_char (dm, 'r')); 2685 RETURN_IF_ERROR (demangle_type (dm)); 2686 RETURN_IF_ERROR (result_append (dm, "::")); 2687 RETURN_IF_ERROR (demangle_encoding (dm)); 2688 return STATUS_OK; 2689} 2690 2691/* Demangles and emits an <expr-primary>. 2692 2693 <expr-primary> ::= <template-param> 2694 ::= L <type> <value number> E # literal 2695 ::= L <mangled-name> E # external name */ 2696 2697static status_t 2698demangle_expr_primary (dm) 2699 demangling_t dm; 2700{ 2701 char peek = peek_char (dm); 2702 int unused; 2703 2704 DEMANGLE_TRACE ("expr-primary", dm); 2705 2706 if (peek == 'T') 2707 RETURN_IF_ERROR (demangle_template_param (dm, &unused)); 2708 else if (peek == 'L') 2709 { 2710 /* Consume the `L'. */ 2711 advance_char (dm); 2712 peek = peek_char (dm); 2713 2714 if (peek == '_') 2715 RETURN_IF_ERROR (demangle_mangled_name (dm)); 2716 else 2717 RETURN_IF_ERROR (demangle_literal (dm)); 2718 2719 RETURN_IF_ERROR (demangle_char (dm, 'E')); 2720 } 2721 else 2722 return STATUS_ERROR; 2723 2724 return STATUS_OK; 2725} 2726 2727/* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero 2728 if the substitution is the name of a template, zero otherwise. If 2729 the substitution token is St, which corresponds to the `::std::' 2730 namespace and can appear in a non-nested name, sets 2731 *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise. 2732 2733 <substitution> ::= S <seq-id> _ 2734 ::= S_ 2735 2736 ::= St # ::std:: 2737 ::= Sa # ::std::allocator 2738 ::= Sb # ::std::basic_string 2739 ::= Ss # ::std::basic_string<char, 2740 ::std::char_traits<char>, 2741 ::std::allocator<char> > 2742 ::= Si # ::std::basic_istream<char, 2743 std::char_traits<char> > 2744 ::= So # ::std::basic_ostream<char, 2745 std::char_traits<char> > 2746 ::= Sd # ::std::basic_iostream<char, 2747 std::char_traits<char> > 2748*/ 2749 2750static status_t 2751demangle_substitution (dm, template_p, special_std_substitution) 2752 demangling_t dm; 2753 int *template_p; 2754 int *special_std_substitution; 2755{ 2756 int seq_id; 2757 int peek; 2758 dyn_string_t text; 2759 2760 DEMANGLE_TRACE ("substitution", dm); 2761 2762 RETURN_IF_ERROR (demangle_char (dm, 'S')); 2763 *special_std_substitution = 0; 2764 2765 /* Scan the substitution sequence index. A missing number denotes 2766 the first index. */ 2767 peek = peek_char (dm); 2768 if (peek == '_') 2769 seq_id = -1; 2770 /* If the following character is 0-9 or a capital letter, interpret 2771 the sequence up to the next underscore as a base-36 substitution 2772 index. */ 2773 else if (IS_DIGIT ((unsigned char) peek) 2774 || (peek >= 'A' && peek <= 'Z')) 2775 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0)); 2776 else 2777 { 2778 const char *new_last_source_name = NULL; 2779 2780 switch (peek) 2781 { 2782 case 't': 2783 RETURN_IF_ERROR (result_append (dm, "std")); 2784 *special_std_substitution = 1; 2785 break; 2786 2787 case 'a': 2788 RETURN_IF_ERROR (result_append (dm, "std::allocator")); 2789 new_last_source_name = "allocator"; 2790 *template_p = 1; 2791 break; 2792 2793 case 'b': 2794 RETURN_IF_ERROR (result_append (dm, "std::basic_string")); 2795 new_last_source_name = "basic_string"; 2796 *template_p = 1; 2797 break; 2798 2799 case 's': 2800 if (!flag_verbose) 2801 { 2802 RETURN_IF_ERROR (result_append (dm, "std::string")); 2803 new_last_source_name = "string"; 2804 } 2805 else 2806 { 2807 RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >")); 2808 new_last_source_name = "basic_string"; 2809 } 2810 *template_p = 0; 2811 break; 2812 2813 case 'i': 2814 if (!flag_verbose) 2815 { 2816 RETURN_IF_ERROR (result_append (dm, "std::istream")); 2817 new_last_source_name = "istream"; 2818 } 2819 else 2820 { 2821 RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >")); 2822 new_last_source_name = "basic_istream"; 2823 } 2824 *template_p = 0; 2825 break; 2826 2827 case 'o': 2828 if (!flag_verbose) 2829 { 2830 RETURN_IF_ERROR (result_append (dm, "std::ostream")); 2831 new_last_source_name = "ostream"; 2832 } 2833 else 2834 { 2835 RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >")); 2836 new_last_source_name = "basic_ostream"; 2837 } 2838 *template_p = 0; 2839 break; 2840 2841 case 'd': 2842 if (!flag_verbose) 2843 { 2844 RETURN_IF_ERROR (result_append (dm, "std::iostream")); 2845 new_last_source_name = "iostream"; 2846 } 2847 else 2848 { 2849 RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >")); 2850 new_last_source_name = "basic_iostream"; 2851 } 2852 *template_p = 0; 2853 break; 2854 2855 default: 2856 return "Unrecognized <substitution>."; 2857 } 2858 2859 /* Consume the character we just processed. */ 2860 advance_char (dm); 2861 2862 if (new_last_source_name != NULL) 2863 { 2864 if (!dyn_string_copy_cstr (dm->last_source_name, 2865 new_last_source_name)) 2866 return STATUS_ALLOCATION_FAILED; 2867 } 2868 2869 return STATUS_OK; 2870 } 2871 2872 /* Look up the substitution text. Since `S_' is the most recent 2873 substitution, `S0_' is the second-most-recent, etc., shift the 2874 numbering by one. */ 2875 text = substitution_get (dm, seq_id + 1, template_p); 2876 if (text == NULL) 2877 return "Substitution number out of range."; 2878 2879 /* Emit the substitution text. */ 2880 RETURN_IF_ERROR (result_append_string (dm, text)); 2881 2882 RETURN_IF_ERROR (demangle_char (dm, '_')); 2883 return STATUS_OK; 2884} 2885 2886/* Demangles and emits a <local-name>. 2887 2888 <local-name> := Z <function encoding> E <entity name> [<discriminator>] 2889 := Z <function encoding> E s [<discriminator>] */ 2890 2891static status_t 2892demangle_local_name (dm) 2893 demangling_t dm; 2894{ 2895 DEMANGLE_TRACE ("local-name", dm); 2896 2897 RETURN_IF_ERROR (demangle_char (dm, 'Z')); 2898 RETURN_IF_ERROR (demangle_encoding (dm)); 2899 RETURN_IF_ERROR (demangle_char (dm, 'E')); 2900 RETURN_IF_ERROR (result_append (dm, "'s ")); 2901 2902 if (peek_char (dm) == 's') 2903 { 2904 /* Local character string literal. */ 2905 RETURN_IF_ERROR (result_append (dm, "string literal")); 2906 /* Consume the s. */ 2907 advance_char (dm); 2908 RETURN_IF_ERROR (demangle_discriminator (dm, 0)); 2909 } 2910 else 2911 { 2912 int unused; 2913 RETURN_IF_ERROR (result_append (dm, "local ")); 2914 /* Local name for some other entity. Demangle its name. */ 2915 RETURN_IF_ERROR (demangle_name (dm, &unused)); 2916 RETURN_IF_ERROR (demangle_discriminator (dm, 1)); 2917 } 2918 2919 return STATUS_OK; 2920 } 2921 2922 /* Optimonally demangles and emits a <discriminator>. If there is no 2923 <discriminator> at the current position in the mangled string, the 2924 descriminator is assumed to be zero. Emit the discriminator number 2925 in parentheses, unless SUPPRESS_FIRST is non-zero and the 2926 discriminator is zero. 2927 2928 <discriminator> ::= _ <number> */ 2929 2930static status_t 2931demangle_discriminator (dm, suppress_first) 2932 demangling_t dm; 2933 int suppress_first; 2934{ 2935 /* Output for <discriminator>s to the demangled name is completely 2936 supressed if not in verbose mode. */ 2937 2938 if (peek_char (dm) == '_') 2939 { 2940 /* Consume the underscore. */ 2941 advance_char (dm); 2942 if (flag_verbose) 2943 RETURN_IF_ERROR (result_append (dm, " [#")); 2944 /* Check if there's a number following the underscore. */ 2945 if (IS_DIGIT ((unsigned char) peek_char (dm))) 2946 { 2947 int discriminator; 2948 /* Demangle the number. */ 2949 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0)); 2950 if (flag_verbose) 2951 /* Write the discriminator. The mangled number is two 2952 less than the discriminator ordinal, counting from 2953 zero. */ 2954 RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2, 2955 (dyn_string_t) dm->result)); 2956 } 2957 else 2958 { 2959 if (flag_verbose) 2960 /* A missing digit correspond to one. */ 2961 RETURN_IF_ERROR (result_append_char (dm, '1')); 2962 } 2963 if (flag_verbose) 2964 RETURN_IF_ERROR (result_append_char (dm, ']')); 2965 } 2966 else if (!suppress_first) 2967 { 2968 if (flag_verbose) 2969 RETURN_IF_ERROR (result_append (dm, " [#0]")); 2970 } 2971 2972 return STATUS_OK; 2973} 2974 2975/* Demangle NAME into RESULT, which must be an initialized 2976 dyn_string_t. On success, returns STATUS_OK. On failure, returns 2977 an error message, and the contents of RESULT are unchanged. */ 2978 2979static status_t 2980cp_demangle (name, result) 2981 const char *name; 2982 dyn_string_t result; 2983{ 2984 status_t status; 2985 int length = strlen (name); 2986 2987 if (length > 2 && name[0] == '_' && name[1] == 'Z') 2988 { 2989 demangling_t dm = demangling_new (name); 2990 if (dm == NULL) 2991 return STATUS_ALLOCATION_FAILED; 2992 2993 status = result_push (dm); 2994 if (status != STATUS_OK) 2995 { 2996 demangling_delete (dm); 2997 return status; 2998 } 2999 3000 status = demangle_mangled_name (dm); 3001 if (STATUS_NO_ERROR (status)) 3002 { 3003 dyn_string_t demangled = (dyn_string_t) result_pop (dm); 3004 if (!dyn_string_copy (result, demangled)) 3005 return STATUS_ALLOCATION_FAILED; 3006 dyn_string_delete (demangled); 3007 } 3008 3009 demangling_delete (dm); 3010 } 3011 else 3012 { 3013 /* It's evidently not a mangled C++ name. It could be the name 3014 of something with C linkage, though, so just copy NAME into 3015 RESULT. */ 3016 if (!dyn_string_copy_cstr (result, name)) 3017 return STATUS_ALLOCATION_FAILED; 3018 status = STATUS_OK; 3019 } 3020 3021 return status; 3022} 3023 3024/* Demangle TYPE_NAME into RESULT, which must be an initialized 3025 dyn_string_t. On success, returns STATUS_OK. On failiure, returns 3026 an error message, and the contents of RESULT are unchanged. */ 3027 3028static status_t 3029cp_demangle_type (type_name, result) 3030 const char* type_name; 3031 dyn_string_t result; 3032{ 3033 status_t status; 3034 demangling_t dm = demangling_new (type_name); 3035 3036 if (dm == NULL) 3037 return STATUS_ALLOCATION_FAILED; 3038 3039 /* Demangle the type name. The demangled name is stored in dm. */ 3040 status = result_push (dm); 3041 if (status != STATUS_OK) 3042 { 3043 demangling_delete (dm); 3044 return status; 3045 } 3046 3047 status = demangle_type (dm); 3048 3049 if (STATUS_NO_ERROR (status)) 3050 { 3051 /* The demangling succeeded. Pop the result out of dm and copy 3052 it into RESULT. */ 3053 dyn_string_t demangled = (dyn_string_t) result_pop (dm); 3054 if (!dyn_string_copy (result, demangled)) 3055 return STATUS_ALLOCATION_FAILED; 3056 dyn_string_delete (demangled); 3057 } 3058 3059 /* Clean up. */ 3060 demangling_delete (dm); 3061 3062 return status; 3063} 3064 3065 3066#ifdef IN_LIBGCC2 3067 3068extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *)); 3069 3070/* ABI-mandated entry point in the C++ runtime library for performing 3071 demangling. MANGLED_NAME is a NUL-terminated character string 3072 containing the name to be demangled. 3073 3074 OUTPUT_BUFFER is a region of memory, allocated with malloc, of 3075 *LENGTH bytes, into which the demangled name is stored. If 3076 OUTPUT_BUFFER is not long enough, it is expanded using realloc. 3077 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name 3078 is placed in a region of memory allocated with malloc. 3079 3080 If LENGTH is non-NULL, the length of the buffer conaining the 3081 demangled name, is placed in *LENGTH. 3082 3083 The return value is a pointer to the start of the NUL-terminated 3084 demangled name, or NULL if the demangling fails. The caller is 3085 responsible for deallocating this memory using free. 3086 3087 *STATUS is set to one of the following values: 3088 0: The demangling operation succeeded. 3089 -1: A memory allocation failiure occurred. 3090 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules. 3091 -3: One of the arguments is invalid. 3092 3093 The demagling is performed using the C++ ABI mangling rules, with 3094 GNU extensions. */ 3095 3096char * 3097__cxa_demangle (mangled_name, output_buffer, length, status) 3098 const char *mangled_name; 3099 char *output_buffer; 3100 size_t *length; 3101 int *status; 3102{ 3103 struct dyn_string demangled_name; 3104 status_t result; 3105 3106 if (status == NULL) 3107 return NULL; 3108 3109 if (mangled_name == NULL) { 3110 *status = -3; 3111 return NULL; 3112 } 3113 3114 /* Did the caller provide a buffer for the demangled name? */ 3115 if (output_buffer == NULL) { 3116 /* No; dyn_string will malloc a buffer for us. */ 3117 if (!dyn_string_init (&demangled_name, 0)) 3118 { 3119 *status = -1; 3120 return NULL; 3121 } 3122 } 3123 else { 3124 /* Yes. Check that the length was provided. */ 3125 if (length == NULL) { 3126 *status = -3; 3127 return NULL; 3128 } 3129 /* Install the buffer into a dyn_string. */ 3130 demangled_name.allocated = *length; 3131 demangled_name.length = 0; 3132 demangled_name.s = output_buffer; 3133 } 3134 3135 if (mangled_name[0] == '_' && mangled_name[1] == 'Z') 3136 /* MANGLED_NAME apprears to be a function or variable name. 3137 Demangle it accordingly. */ 3138 result = cp_demangle (mangled_name, &demangled_name); 3139 else 3140 /* Try to demangled MANGLED_NAME as the name of a type. */ 3141 result = cp_demangle_type (mangled_name, &demangled_name); 3142 3143 if (result == STATUS_OK) 3144 /* The demangling succeeded. */ 3145 { 3146 /* If LENGTH isn't NULL, store the allocated buffer length 3147 there; the buffer may have been realloced by dyn_string 3148 functions. */ 3149 if (length != NULL) 3150 *length = demangled_name.allocated; 3151 /* The operation was a success. */ 3152 *status = 0; 3153 return dyn_string_buf (&demangled_name); 3154 } 3155 else if (result == STATUS_ALLOCATION_FAILED) 3156 /* A call to malloc or realloc failed during the demangling 3157 operation. */ 3158 { 3159 *status = -1; 3160 return NULL; 3161 } 3162 else 3163 /* The demangling failed for another reason, most probably because 3164 MANGLED_NAME isn't a valid mangled name. */ 3165 { 3166 /* If the buffer containing the demangled name wasn't provided 3167 by the caller, free it. */ 3168 if (output_buffer == NULL) 3169 free (dyn_string_buf (&demangled_name)); 3170 *status = -2; 3171 return NULL; 3172 } 3173} 3174 3175#else /* !IN_LIBGCC2 */ 3176 3177/* Variant entry point for integration with the existing cplus-dem 3178 demangler. Attempts to demangle MANGLED. If the demangling 3179 succeeds, returns a buffer, allocated with malloc, containing the 3180 demangled name. The caller must deallocate the buffer using free. 3181 If the demangling failes, returns NULL. */ 3182 3183char * 3184cplus_demangle_new_abi (mangled) 3185 const char* mangled; 3186{ 3187 /* Create a dyn_string to hold the demangled name. */ 3188 dyn_string_t demangled = dyn_string_new (0); 3189 /* Attempt the demangling. */ 3190 status_t status = cp_demangle ((char *) mangled, demangled); 3191 if (STATUS_NO_ERROR (status)) 3192 /* Demangling succeeded. */ 3193 { 3194 /* Grab the demangled result from the dyn_string. It was 3195 allocated with malloc, so we can return it directly. */ 3196 char *return_value = dyn_string_release (demangled); 3197 /* Hand back the demangled name. */ 3198 return return_value; 3199 } 3200 else if (status == STATUS_ALLOCATION_FAILED) 3201 { 3202 fprintf (stderr, "Memory allocation failed.\n"); 3203 abort (); 3204 } 3205 else 3206 /* Demangling failed. */ 3207 { 3208 dyn_string_delete (demangled); 3209 return NULL; 3210 } 3211} 3212 3213#endif /* IN_LIBGCC2 */ 3214 3215#ifdef STANDALONE_DEMANGLER 3216 3217#include "getopt.h" 3218 3219static void print_usage 3220 PARAMS ((FILE* fp, int exit_value)); 3221 3222/* Non-zero if CHAR is a character than can occur in a mangled name. */ 3223#define is_mangled_char(CHAR) \ 3224 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) || (CHAR) == '_') 3225 3226/* The name of this program, as invoked. */ 3227const char* program_name; 3228 3229/* Prints usage summary to FP and then exits with EXIT_VALUE. */ 3230 3231static void 3232print_usage (fp, exit_value) 3233 FILE* fp; 3234 int exit_value; 3235{ 3236 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name); 3237 fprintf (fp, "Options:\n", program_name); 3238 fprintf (fp, " -h,--help Display this message.\n"); 3239 fprintf (fp, " -s,--strict Demangle standard names only.\n"); 3240 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n"); 3241 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n"); 3242 3243 exit (exit_value); 3244} 3245 3246/* Option specification for getopt_long. */ 3247static struct option long_options[] = 3248{ 3249 { "help", no_argument, NULL, 'h' }, 3250 { "strict", no_argument, NULL, 's' }, 3251 { "verbose", no_argument, NULL, 'v' }, 3252 { NULL, no_argument, NULL, 0 }, 3253}; 3254 3255/* Main entry for a demangling filter executable. It will demangle 3256 its command line arguments, if any. If none are provided, it will 3257 filter stdin to stdout, replacing any recognized mangled C++ names 3258 with their demangled equivalents. */ 3259 3260int 3261main (argc, argv) 3262 int argc; 3263 char *argv[]; 3264{ 3265 status_t status; 3266 int i; 3267 int opt_char; 3268 3269 /* Use the program name of this program, as invoked. */ 3270 program_name = argv[0]; 3271 3272 /* Parse options. */ 3273 do 3274 { 3275 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL); 3276 switch (opt_char) 3277 { 3278 case '?': /* Unrecognized option. */ 3279 print_usage (stderr, 1); 3280 break; 3281 3282 case 'h': 3283 print_usage (stdout, 0); 3284 break; 3285 3286 case 's': 3287 flag_strict = 1; 3288 break; 3289 3290 case 'v': 3291 flag_verbose = 1; 3292 break; 3293 } 3294 } 3295 while (opt_char != -1); 3296 3297 if (optind == argc) 3298 /* No command line arguments were provided. Filter stdin. */ 3299 { 3300 dyn_string_t mangled = dyn_string_new (3); 3301 dyn_string_t demangled = dyn_string_new (0); 3302 status_t status; 3303 3304 /* Read all of input. */ 3305 while (!feof (stdin)) 3306 { 3307 char c = getchar (); 3308 3309 /* The first character of a mangled name is an underscore. */ 3310 if (feof (stdin)) 3311 break; 3312 if (c != '_') 3313 { 3314 /* It's not a mangled name. Print the character and go 3315 on. */ 3316 putchar (c); 3317 continue; 3318 } 3319 c = getchar (); 3320 3321 /* The second character of a mangled name is a capital `Z'. */ 3322 if (feof (stdin)) 3323 break; 3324 if (c != 'Z') 3325 { 3326 /* It's not a mangled name. Print the previous 3327 underscore, the `Z', and go on. */ 3328 putchar ('_'); 3329 putchar (c); 3330 continue; 3331 } 3332 3333 /* Start keeping track of the candidate mangled name. */ 3334 dyn_string_append_char (mangled, '_'); 3335 dyn_string_append_char (mangled, 'Z'); 3336 3337 /* Pile characters into mangled until we hit one that can't 3338 occur in a mangled name. */ 3339 c = getchar (); 3340 while (!feof (stdin) && is_mangled_char (c)) 3341 { 3342 dyn_string_append_char (mangled, c); 3343 if (feof (stdin)) 3344 break; 3345 c = getchar (); 3346 } 3347 3348 /* Attempt to demangle the name. */ 3349 status = cp_demangle (dyn_string_buf (mangled), demangled); 3350 3351 /* If the demangling succeeded, great! Print out the 3352 demangled version. */ 3353 if (STATUS_NO_ERROR (status)) 3354 fputs (dyn_string_buf (demangled), stdout); 3355 /* Abort on allocation failures. */ 3356 else if (status == STATUS_ALLOCATION_FAILED) 3357 { 3358 fprintf (stderr, "Memory allocation failed.\n"); 3359 abort (); 3360 } 3361 /* Otherwise, it might not have been a mangled name. Just 3362 print out the original text. */ 3363 else 3364 fputs (dyn_string_buf (mangled), stdout); 3365 3366 /* If we haven't hit EOF yet, we've read one character that 3367 can't occur in a mangled name, so print it out. */ 3368 if (!feof (stdin)) 3369 putchar (c); 3370 3371 /* Clear the candidate mangled name, to start afresh next 3372 time we hit a `_Z'. */ 3373 dyn_string_clear (mangled); 3374 } 3375 3376 dyn_string_delete (mangled); 3377 dyn_string_delete (demangled); 3378 } 3379 else 3380 /* Demangle command line arguments. */ 3381 { 3382 dyn_string_t result = dyn_string_new (0); 3383 3384 /* Loop over command line arguments. */ 3385 for (i = optind; i < argc; ++i) 3386 { 3387 /* Attempt to demangle. */ 3388 status = cp_demangle (argv[i], result); 3389 3390 /* If it worked, print the demangled name. */ 3391 if (STATUS_NO_ERROR (status)) 3392 printf ("%s\n", dyn_string_buf (result)); 3393 /* Abort on allocaiton failures. */ 3394 else if (status == STATUS_ALLOCATION_FAILED) 3395 { 3396 fprintf (stderr, "Memory allocaiton failed.\n"); 3397 abort (); 3398 } 3399 /* If not, print the error message to stderr instead. */ 3400 else 3401 fprintf (stderr, "%s\n", status); 3402 } 3403 dyn_string_delete (result); 3404 } 3405 3406 return 0; 3407} 3408 3409#endif /* STANDALONE_DEMANGLER */ 3410