1 /* Demangler for IA64 / g++ standard C++ ABI.
2 Copyright (C) 2000 CodeSourcery LLC.
3 Written by Alex Samuel <samuel@codesourcery.com>.
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.
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.
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.
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 (functionally similar to c++filt, but includes this
31 #include <sys/types.h>
44 #include "libiberty.h"
45 #include "dyn-string.h"
48 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
49 and other debugging output, will be generated. */
50 #ifdef CP_DEMANGLE_DEBUG
51 #define DEMANGLE_TRACE(PRODUCTION, DM) \
52 fprintf (stderr, " -> %-24s at position %3d\n", \
53 (PRODUCTION), current_position (DM));
55 #define DEMANGLE_TRACE(PRODUCTION, DM)
58 /* Don't include <ctype.h>, to prevent additional unresolved symbols
59 from being dragged into the C++ runtime library. */
60 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
61 #define IS_ALPHA(CHAR) \
62 (((CHAR) >= 'a' && (CHAR) <= 'z') \
63 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
65 /* The prefix prepended by GCC to an identifier represnting the
66 anonymous namespace. */
67 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
69 /* If flag_verbose is zero, some simplifications will be made to the
70 output to make it easier to read and supress details that are
71 generally not of interest to the average C++ programmer.
72 Otherwise, the demangled representation will attempt to convey as
73 much information as the mangled form. */
74 static int flag_verbose;
76 /* If flag_strict is non-zero, demangle strictly according to the
77 specification -- don't demangle special g++ manglings. */
78 static int flag_strict;
80 /* String_list_t is an extended form of dyn_string_t which provides a link
81 field. A string_list_t may safely be cast to and used as a
84 struct string_list_def
86 struct dyn_string string;
87 struct string_list_def *next;
90 typedef struct string_list_def *string_list_t;
92 /* Data structure representing a potential substitution. */
94 struct substitution_def
96 /* The demangled text of the substitution. */
99 /* Whether this substitution represents a template item. */
103 /* Data structure representing a template argument list. */
105 struct template_arg_list_def
107 /* The next (lower) template argument list in the stack of currently
108 active template arguments. */
109 struct template_arg_list_def *next;
111 /* The first element in the list of template arguments in
112 left-to-right order. */
113 string_list_t first_argument;
115 /* The last element in the arguments lists. */
116 string_list_t last_argument;
119 typedef struct template_arg_list_def *template_arg_list_t;
121 /* Data structure to maintain the state of the current demangling. */
123 struct demangling_def
125 /* The full mangled name being mangled. */
128 /* Pointer into name at the current position. */
131 /* Stack for strings containing demangled result generated so far.
132 Text is emitted to the topmost (first) string. */
133 string_list_t result;
135 /* The number of presently available substitutions. */
136 int num_substitutions;
138 /* The allocated size of the substitutions array. */
139 int substitutions_allocated;
141 /* An array of available substitutions. The number of elements in
142 the array is given by num_substitions, and the allocated array
143 size in substitutions_size.
145 The most recent substition is at the end, so
147 - `S_' corresponds to substititutions[num_substitutions - 1]
148 - `S0_' corresponds to substititutions[num_substitutions - 2]
151 struct substitution_def *substitutions;
153 /* The stack of template argument lists. */
154 template_arg_list_t template_arg_lists;
156 /* The most recently demangled source-name. */
157 dyn_string_t last_source_name;
160 typedef struct demangling_def *demangling_t;
162 /* This type is the standard return code from most functions. Values
163 other than STATUS_OK contain descriptive messages. */
164 typedef const char *status_t;
166 /* Special values that can be used as a status_t. */
167 #define STATUS_OK NULL
168 #define STATUS_ERROR "Error."
169 #define STATUS_UNIMPLEMENTED "Unimplemented."
170 #define STATUS_INTERNAL_ERROR "Internal error."
172 /* This status code indicates a failure in malloc or realloc. */
173 static const char* const status_allocation_failed = "Allocation failed.";
174 #define STATUS_ALLOCATION_FAILED status_allocation_failed
176 /* Non-zero if STATUS indicates that no error has occurred. */
177 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
179 /* Evaluate EXPR, which must produce a status_t. If the status code
180 indicates an error, return from the current function with that
182 #define RETURN_IF_ERROR(EXPR) \
186 if (!STATUS_NO_ERROR (s)) \
191 static status_t int_to_dyn_string
192 PARAMS ((int, dyn_string_t));
193 static string_list_t string_list_new
195 static void string_list_delete
196 PARAMS ((string_list_t));
197 static status_t result_add_separated_char
198 PARAMS ((demangling_t, int));
199 static status_t result_push
200 PARAMS ((demangling_t));
201 static string_list_t result_pop
202 PARAMS ((demangling_t));
203 static int substitution_start
204 PARAMS ((demangling_t));
205 static status_t substitution_add
206 PARAMS ((demangling_t, int, int));
207 static dyn_string_t substitution_get
208 PARAMS ((demangling_t, int, int *));
209 #ifdef CP_DEMANGLE_DEBUG
210 static void substitutions_print
211 PARAMS ((demangling_t, FILE *));
213 static template_arg_list_t template_arg_list_new
215 static void template_arg_list_delete
216 PARAMS ((template_arg_list_t));
217 static void template_arg_list_add_arg
218 PARAMS ((template_arg_list_t, string_list_t));
219 static string_list_t template_arg_list_get_arg
220 PARAMS ((template_arg_list_t, int));
221 static void push_template_arg_list
222 PARAMS ((demangling_t, template_arg_list_t));
223 static void pop_to_template_arg_list
224 PARAMS ((demangling_t, template_arg_list_t));
225 #ifdef CP_DEMANGLE_DEBUG
226 static void template_arg_list_print
227 PARAMS ((template_arg_list_t, FILE *));
229 static template_arg_list_t current_template_arg_list
230 PARAMS ((demangling_t));
231 static demangling_t demangling_new
232 PARAMS ((const char *));
233 static void demangling_delete
234 PARAMS ((demangling_t));
236 /* The last character of DS. Warning: DS is evaluated twice. */
237 #define dyn_string_last_char(DS) \
238 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
240 /* Append a space character (` ') to DS if it does not already end
241 with one. Evaluates to 1 on success, or 0 on allocation failure. */
242 #define dyn_string_append_space(DS) \
243 ((dyn_string_length (DS) > 0 \
244 && dyn_string_last_char (DS) != ' ') \
245 ? dyn_string_append_char ((DS), ' ') \
248 /* Returns the index of the current position in the mangled name. */
249 #define current_position(DM) ((DM)->next - (DM)->name)
251 /* Returns the character at the current position of the mangled name. */
252 #define peek_char(DM) (*((DM)->next))
254 /* Returns the character one past the current position of the mangled
256 #define peek_char_next(DM) \
257 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
259 /* Returns the character at the current position, and advances the
260 current position to the next character. */
261 #define next_char(DM) (*((DM)->next)++)
263 /* Returns non-zero if the current position is the end of the mangled
264 name, i.e. one past the last character. */
265 #define end_of_name_p(DM) (peek_char (DM) == '\0')
267 /* Advances the current position by one character. */
268 #define advance_char(DM) (++(DM)->next)
270 /* Returns the string containing the current demangled result. */
271 #define result_string(DM) (&(DM)->result->string)
273 /* Appends a dyn_string_t to the demangled result. */
274 #define result_append_string(DM, STRING) \
275 (dyn_string_append (&(DM)->result->string, (STRING)) \
276 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
278 /* Appends NUL-terminated string CSTR to the demangled result. */
279 #define result_append(DM, CSTR) \
280 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
281 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
283 /* Appends character CHAR to the demangled result. */
284 #define result_append_char(DM, CHAR) \
285 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \
286 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
288 /* Inserts a dyn_string_t to the demangled result at position POS. */
289 #define result_insert_string(DM, POS, STRING) \
290 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
291 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
293 /* Inserts NUL-terminated string CSTR to the demangled result at
295 #define result_insert(DM, POS, CSTR) \
296 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
297 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
299 /* Inserts character CHAR to the demangled result at position POS. */
300 #define result_insert_char(DM, POS, CHAR) \
301 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
302 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
304 /* The length of the current demangled result. */
305 #define result_length(DM) \
306 dyn_string_length (&(DM)->result->string)
308 /* Appends a space to the demangled result if the last character is
310 #define result_append_space(DM) \
311 (dyn_string_append_space (&(DM)->result->string) \
312 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
314 /* Appends a (less-than, greater-than) character to the result in DM
315 to (open, close) a template argument or parameter list. Appends a
316 space first if necessary to prevent spurious elision of angle
317 brackets with the previous character. */
318 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
319 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
321 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
322 success. On failure, deletes DS and returns an error code. */
325 int_to_dyn_string (value, ds)
332 /* Handle zero up front. */
335 if (!dyn_string_append_char (ds, '0'))
336 return STATUS_ALLOCATION_FAILED;
340 /* For negative numbers, emit a minus sign. */
343 if (!dyn_string_append_char (ds, '-'))
344 return STATUS_ALLOCATION_FAILED;
348 /* Find the power of 10 of the first digit. */
356 /* Write the digits. */
359 int digit = value / mask;
361 if (!dyn_string_append_char (ds, '0' + digit))
362 return STATUS_ALLOCATION_FAILED;
364 value -= digit * mask;
371 /* Creates a new string list node. The contents of the string are
372 empty, but the initial buffer allocation is LENGTH. The string
373 list node should be deleted with string_list_delete. Returns NULL
374 if allocation fails. */
377 string_list_new (length)
380 string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
383 if (!dyn_string_init ((dyn_string_t) s, length))
388 /* Deletes the entire string list starting at NODE. */
391 string_list_delete (node)
396 string_list_t next = node->next;
402 /* Appends CHARACTER to the demangled result. If the current trailing
403 character of the result is CHARACTER, a space is inserted first. */
406 result_add_separated_char (dm, character)
410 dyn_string_t s = &dm->result->string;
412 /* Add a space if the last character is already a closing angle
413 bracket, so that a nested template arg list doesn't look like
414 it's closed with a right-shift operator. */
415 if (dyn_string_last_char (s) == character)
417 if (!dyn_string_append_char (s, ' '))
418 return STATUS_ALLOCATION_FAILED;
421 /* Add closing angle brackets. */
422 if (!dyn_string_append_char (s, character))
423 return STATUS_ALLOCATION_FAILED;
428 /* Allocates and pushes a new string onto the demangled results stack
429 for DM. Subsequent demangling with DM will emit to the new string.
430 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
431 allocation failure. */
437 string_list_t new_string = string_list_new (0);
438 if (new_string == NULL)
439 /* Allocation failed. */
440 return STATUS_ALLOCATION_FAILED;
442 /* Link the new string to the front of the list of result strings. */
443 new_string->next = (string_list_t) dm->result;
444 dm->result = new_string;
448 /* Removes and returns the topmost element on the demangled results
449 stack for DM. The caller assumes ownership for the returned
456 string_list_t top = dm->result;
457 dm->result = top->next;
461 /* Returns the start position of a fragment of the demangled result
462 that will be a substitution candidate. Should be called at the
463 start of productions that can add substitutions. */
466 substitution_start (dm)
469 return result_length (dm);
472 /* Adds the suffix of the current demangled result of DM starting at
473 START_POSITION as a potential substitution. If TEMPLATE_P is
474 non-zero, this potential substitution is a template-id. */
477 substitution_add (dm, start_position, template_p)
482 dyn_string_t result = result_string (dm);
483 dyn_string_t substitution = dyn_string_new (0);
486 if (substitution == NULL)
487 return STATUS_ALLOCATION_FAILED;
489 /* Extract the substring of the current demangling result that
490 represents the subsitution candidate. */
491 if (!dyn_string_substring (substitution,
492 result, start_position, result_length (dm)))
494 dyn_string_delete (substitution);
495 return STATUS_ALLOCATION_FAILED;
498 /* If there's no room for the new entry, grow the array. */
499 if (dm->substitutions_allocated == dm->num_substitutions)
501 size_t new_array_size;
502 if (dm->substitutions_allocated > 0)
503 dm->substitutions_allocated *= 2;
505 dm->substitutions_allocated = 2;
507 sizeof (struct substitution_def) * dm->substitutions_allocated;
509 dm->substitutions = (struct substitution_def *)
510 realloc (dm->substitutions, new_array_size);
511 if (dm->substitutions == NULL)
512 /* Realloc failed. */
514 dyn_string_delete (substitution);
515 return STATUS_ALLOCATION_FAILED;
519 /* Add the substitution to the array. */
520 i = dm->num_substitutions++;
521 dm->substitutions[i].text = substitution;
522 dm->substitutions[i].template_p = template_p;
524 #ifdef CP_DEMANGLE_DEBUG
525 substitutions_print (dm, stderr);
531 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
532 non-zero if the substitution is a template-id, zero otherwise.
533 N is numbered from zero. DM retains ownership of the returned
534 string. If N is negative, or equal to or greater than the current
535 number of substitution candidates, returns NULL. */
538 substitution_get (dm, n, template_p)
543 struct substitution_def *sub;
545 /* Make sure N is in the valid range. */
546 if (n < 0 || n >= dm->num_substitutions)
549 sub = &(dm->substitutions[n]);
550 *template_p = sub->template_p;
554 #ifdef CP_DEMANGLE_DEBUG
555 /* Debugging routine to print the current substitutions to FP. */
558 substitutions_print (dm, fp)
563 int num = dm->num_substitutions;
565 fprintf (fp, "SUBSTITUTIONS:\n");
566 for (seq_id = -1; seq_id < num - 1; ++seq_id)
569 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
572 fprintf (fp, " S_ ");
574 fprintf (fp, " S%d_", seq_id);
575 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
579 #endif /* CP_DEMANGLE_DEBUG */
581 /* Creates a new template argument list. Returns NULL if allocation
584 static template_arg_list_t
585 template_arg_list_new ()
587 template_arg_list_t new_list =
588 (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
589 if (new_list == NULL)
591 /* Initialize the new list to have no arguments. */
592 new_list->first_argument = NULL;
593 new_list->last_argument = NULL;
594 /* Return the new list. */
598 /* Deletes a template argument list and the template arguments it
602 template_arg_list_delete (list)
603 template_arg_list_t list;
605 /* If there are any arguments on LIST, delete them. */
606 if (list->first_argument != NULL)
607 string_list_delete (list->first_argument);
612 /* Adds ARG to the template argument list ARG_LIST. */
615 template_arg_list_add_arg (arg_list, arg)
616 template_arg_list_t arg_list;
619 if (arg_list->first_argument == NULL)
620 /* If there were no arguments before, ARG is the first one. */
621 arg_list->first_argument = arg;
623 /* Make ARG the last argument on the list. */
624 arg_list->last_argument->next = arg;
625 /* Make ARG the last on the list. */
626 arg_list->last_argument = arg;
630 /* Returns the template arugment at position INDEX in template
631 argument list ARG_LIST. */
634 template_arg_list_get_arg (arg_list, index)
635 template_arg_list_t arg_list;
638 string_list_t arg = arg_list->first_argument;
639 /* Scan down the list of arguments to find the one at position
645 /* Ran out of arguments before INDEX hit zero. That's an
649 /* Return the argument at position INDEX. */
653 /* Pushes ARG_LIST onto the top of the template argument list stack. */
656 push_template_arg_list (dm, arg_list)
658 template_arg_list_t arg_list;
660 arg_list->next = dm->template_arg_lists;
661 dm->template_arg_lists = arg_list;
662 #ifdef CP_DEMANGLE_DEBUG
663 fprintf (stderr, " ** pushing template arg list\n");
664 template_arg_list_print (arg_list, stderr);
668 /* Pops and deletes elements on the template argument list stack until
669 arg_list is the topmost element. If arg_list is NULL, all elements
670 are popped and deleted. */
673 pop_to_template_arg_list (dm, arg_list)
675 template_arg_list_t arg_list;
677 while (dm->template_arg_lists != arg_list)
679 template_arg_list_t top = dm->template_arg_lists;
680 /* Disconnect the topmost element from the list. */
681 dm->template_arg_lists = top->next;
682 /* Delete the popped element. */
683 template_arg_list_delete (top);
684 #ifdef CP_DEMANGLE_DEBUG
685 fprintf (stderr, " ** removing template arg list\n");
690 #ifdef CP_DEMANGLE_DEBUG
692 /* Prints the contents of ARG_LIST to FP. */
695 template_arg_list_print (arg_list, fp)
696 template_arg_list_t arg_list;
702 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
703 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
706 fprintf (fp, " T_ : ");
708 fprintf (fp, " T%d_ : ", index);
710 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
714 #endif /* CP_DEMANGLE_DEBUG */
716 /* Returns the topmost element on the stack of template argument
717 lists. If there is no list of template arguments, returns NULL. */
719 static template_arg_list_t
720 current_template_arg_list (dm)
723 return dm->template_arg_lists;
726 /* Allocates a demangling_t object for demangling mangled NAME. A new
727 result must be pushed before the returned object can be used.
728 Returns NULL if allocation fails. */
731 demangling_new (name)
735 dm = (demangling_t) malloc (sizeof (struct demangling_def));
742 dm->num_substitutions = 0;
743 dm->substitutions_allocated = 10;
744 dm->template_arg_lists = NULL;
745 dm->last_source_name = dyn_string_new (0);
746 if (dm->last_source_name == NULL)
748 dm->substitutions = (struct substitution_def *)
749 malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
750 if (dm->substitutions == NULL)
752 dyn_string_delete (dm->last_source_name);
759 /* Deallocates a demangling_t object and all memory associated with
763 demangling_delete (dm)
767 template_arg_list_t arg_list = dm->template_arg_lists;
769 /* Delete the stack of template argument lists. */
770 while (arg_list != NULL)
772 template_arg_list_t next = arg_list->next;
773 template_arg_list_delete (arg_list);
776 /* Delete the list of substitutions. */
777 for (i = dm->num_substitutions; --i >= 0; )
778 dyn_string_delete (dm->substitutions[i].text);
779 free (dm->substitutions);
780 /* Delete the demangled result. */
781 string_list_delete (dm->result);
782 /* Delete the stored identifier name. */
783 dyn_string_delete (dm->last_source_name);
784 /* Delete the context object itself. */
788 /* These functions demangle an alternative of the corresponding
789 production in the mangling spec. The first argument of each is a
790 demangling context structure for the current demangling
791 operation. Most emit demangled text directly to the topmost result
792 string on the result string stack in the demangling context
795 static status_t demangle_char
796 PARAMS ((demangling_t, int));
797 static status_t demangle_mangled_name
798 PARAMS ((demangling_t));
799 static status_t demangle_encoding
800 PARAMS ((demangling_t));
801 static status_t demangle_name
802 PARAMS ((demangling_t, int *));
803 static status_t demangle_nested_name
804 PARAMS ((demangling_t, int *));
805 static status_t demangle_prefix
806 PARAMS ((demangling_t, int *));
807 static status_t demangle_unqualified_name
808 PARAMS ((demangling_t));
809 static status_t demangle_source_name
810 PARAMS ((demangling_t));
811 static status_t demangle_number
812 PARAMS ((demangling_t, int *, int, int));
813 static status_t demangle_number_literally
814 PARAMS ((demangling_t, dyn_string_t, int, int));
815 static status_t demangle_identifier
816 PARAMS ((demangling_t, int, dyn_string_t));
817 static status_t demangle_operator_name
818 PARAMS ((demangling_t, int, int *));
819 static status_t demangle_special_name
820 PARAMS ((demangling_t));
821 static status_t demangle_ctor_dtor_name
822 PARAMS ((demangling_t));
823 static status_t demangle_type_ptr
824 PARAMS ((demangling_t, int *, int));
825 static status_t demangle_type
826 PARAMS ((demangling_t));
827 static status_t demangle_CV_qualifiers
828 PARAMS ((demangling_t, dyn_string_t));
829 static status_t demangle_builtin_type
830 PARAMS ((demangling_t));
831 static status_t demangle_function_type
832 PARAMS ((demangling_t, int *));
833 static status_t demangle_bare_function_type
834 PARAMS ((demangling_t, int *));
835 static status_t demangle_class_enum_type
836 PARAMS ((demangling_t, int *));
837 static status_t demangle_array_type
838 PARAMS ((demangling_t));
839 static status_t demangle_template_param
840 PARAMS ((demangling_t));
841 static status_t demangle_template_args
842 PARAMS ((demangling_t));
843 static status_t demangle_literal
844 PARAMS ((demangling_t));
845 static status_t demangle_template_arg
846 PARAMS ((demangling_t));
847 static status_t demangle_expression
848 PARAMS ((demangling_t));
849 static status_t demangle_scope_expression
850 PARAMS ((demangling_t));
851 static status_t demangle_expr_primary
852 PARAMS ((demangling_t));
853 static status_t demangle_substitution
854 PARAMS ((demangling_t, int *));
855 static status_t demangle_local_name
856 PARAMS ((demangling_t));
857 static status_t demangle_discriminator
858 PARAMS ((demangling_t, int));
859 static status_t cp_demangle
860 PARAMS ((const char *, dyn_string_t));
862 static status_t cp_demangle_type
863 PARAMS ((const char*, dyn_string_t));
866 /* When passed to demangle_bare_function_type, indicates that the
867 function's return type is not encoded before its parameter types. */
868 #define BFT_NO_RETURN_TYPE NULL
870 /* Check that the next character is C. If so, consume it. If not,
874 demangle_char (dm, c)
878 static char *error_message = NULL;
880 if (peek_char (dm) == c)
887 if (error_message == NULL)
888 error_message = strdup ("Expected ?");
889 error_message[9] = c;
890 return error_message;
894 /* Demangles and emits a <mangled-name>.
896 <mangled-name> ::= _Z <encoding> */
899 demangle_mangled_name (dm)
902 DEMANGLE_TRACE ("mangled-name", dm);
903 RETURN_IF_ERROR (demangle_char (dm, '_'));
904 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
905 RETURN_IF_ERROR (demangle_encoding (dm));
909 /* Demangles and emits an <encoding>.
911 <encoding> ::= <function name> <bare-function-type>
913 ::= <special-name> */
916 demangle_encoding (dm)
921 template_arg_list_t old_arg_list = current_template_arg_list (dm);
922 char peek = peek_char (dm);
924 DEMANGLE_TRACE ("encoding", dm);
926 /* Remember where the name starts. If it turns out to be a template
927 function, we'll have to insert the return type here. */
928 start_position = result_length (dm);
930 if (peek == 'G' || peek == 'T')
931 RETURN_IF_ERROR (demangle_special_name (dm));
934 /* Now demangle the name. */
935 RETURN_IF_ERROR (demangle_name (dm, &template_p));
937 /* If there's anything left, the name was a function name, with
938 maybe its return type, and its parameters types, following. */
939 if (!end_of_name_p (dm)
940 && peek_char (dm) != 'E')
943 /* Template functions have their return type encoded. The
944 return type should be inserted at start_position. */
946 (demangle_bare_function_type (dm, &start_position));
948 /* Non-template functions don't have their return type
951 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
955 /* Pop off template argument lists that were built during the
956 mangling of this name, to restore the old template context. */
957 pop_to_template_arg_list (dm, old_arg_list);
962 /* Demangles and emits a <name>.
964 <name> ::= <unscoped-name>
965 ::= <unscoped-template-name> <template-args>
969 <unscoped-name> ::= <unqualified-name>
970 ::= St <unqualified-name> # ::std::
972 <unscoped-template-name>
974 ::= <substitution> */
977 demangle_name (dm, template_p)
981 int start = substitution_start (dm);
982 char peek = peek_char (dm);
983 int is_std_substitution = 0;
985 DEMANGLE_TRACE ("name", dm);
990 /* This is a <nested-name>. */
991 RETURN_IF_ERROR (demangle_nested_name (dm, template_p));
995 RETURN_IF_ERROR (demangle_local_name (dm));
1000 /* The `St' substitution allows a name nested in std:: to appear
1001 without being enclosed in a nested name. */
1002 if (peek_char_next (dm) == 't')
1004 (void) next_char (dm);
1005 (void) next_char (dm);
1006 RETURN_IF_ERROR (result_append (dm, "std::"));
1007 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1008 is_std_substitution = 1;
1012 RETURN_IF_ERROR (demangle_substitution (dm, template_p));
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')
1018 /* A template name of the form std::<unqualified-name> is a
1019 substitution candidate. */
1020 if (is_std_substitution)
1021 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1022 /* Demangle the <template-args> here. */
1023 RETURN_IF_ERROR (demangle_template_args (dm));
1032 /* This is an <unscoped-name> or <unscoped-template-name>. */
1033 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1035 /* If the <unqualified-name> is followed by template args, this
1036 is an <unscoped-template-name>. */
1037 if (peek_char (dm) == 'I')
1039 /* Add a substitution for the unqualified template name. */
1040 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1042 RETURN_IF_ERROR (demangle_template_args (dm));
1054 /* Demangles and emits a <nested-name>.
1056 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1059 demangle_nested_name (dm, template_p)
1065 DEMANGLE_TRACE ("nested-name", dm);
1067 RETURN_IF_ERROR (demangle_char (dm, 'N'));
1069 peek = peek_char (dm);
1070 if (peek == 'r' || peek == 'V' || peek == 'K')
1074 /* Snarf up and emit CV qualifiers. */
1075 dyn_string_t cv_qualifiers = dyn_string_new (24);
1076 if (cv_qualifiers == NULL)
1077 return STATUS_ALLOCATION_FAILED;
1079 demangle_CV_qualifiers (dm, cv_qualifiers);
1080 status = result_append_string (dm, cv_qualifiers);
1081 dyn_string_delete (cv_qualifiers);
1082 RETURN_IF_ERROR (status);
1083 RETURN_IF_ERROR (result_append_space (dm));
1086 RETURN_IF_ERROR (demangle_prefix (dm, template_p));
1087 /* No need to demangle the final <unqualified-name>; demangle_prefix
1089 RETURN_IF_ERROR (demangle_char (dm, 'E'));
1094 /* Demangles and emits a <prefix>.
1096 <prefix> ::= <prefix> <unqualified-name>
1097 ::= <template-prefix> <template-args>
1101 <template-prefix> ::= <prefix>
1102 ::= <substitution> */
1105 demangle_prefix (dm, template_p)
1109 int start = substitution_start (dm);
1112 /* This flag is set to non-zero if the most recent (rightmost)
1113 element in the prefix was a constructor. */
1114 int last_was_ctor = 0;
1116 /* TEMPLATE_P is updated as we decend the nesting chain. After
1117 <template-args>, it is set to non-zero; after everything else it
1120 DEMANGLE_TRACE ("prefix", dm);
1126 if (end_of_name_p (dm))
1127 return "Unexpected end of name in <compound-name>.";
1129 peek = peek_char (dm);
1131 /* We'll initialize last_was_ctor to false, and set it to true
1132 if we end up demangling a constructor name. However, make
1133 sure we're not actually about to demangle template arguments
1134 -- if so, this is the <template-args> following a
1135 <template-prefix>, so we'll want the previous flag value
1140 if (IS_DIGIT ((unsigned char) peek)
1141 || (peek >= 'a' && peek <= 'z')
1142 || peek == 'C' || peek == 'D'
1145 /* We have another level of scope qualification. */
1147 RETURN_IF_ERROR (result_append (dm, "::"));
1152 /* The substitution determines whether this is a
1154 RETURN_IF_ERROR (demangle_substitution (dm, template_p));
1157 /* It's just a name. */
1158 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1162 /* If this element was a constructor name, make a note of
1167 else if (peek == 'Z')
1168 RETURN_IF_ERROR (demangle_local_name (dm));
1169 else if (peek == 'I')
1171 RETURN_IF_ERROR (demangle_template_args (dm));
1173 /* Now we want to indicate to the caller that we've
1174 demangled template arguments, thus the prefix was a
1175 <template-prefix>. That's so that the caller knows to
1176 demangle the function's return type, if this turns out to
1177 be a function name. */
1181 /* But, if it's a member template constructor, report it
1182 as untemplated. We don't ever want to demangle the
1183 return type of a constructor. */
1186 else if (peek == 'E')
1190 return "Unexpected character in <compound-name>.";
1193 && peek_char (dm) != 'E')
1194 /* Add a new substitution for the prefix thus far. */
1195 RETURN_IF_ERROR (substitution_add (dm, start, *template_p));
1199 /* Demangles and emits an <unqualified-name>. If the
1200 <unqualified-name> is a function and the first element in the
1201 argument list should be taken to be its return type,
1202 ENCODE_RETURN_TYPE is non-zero.
1204 <unqualified-name> ::= <operator-name>
1206 ::= <source-name> */
1209 demangle_unqualified_name (dm)
1212 char peek = peek_char (dm);
1214 DEMANGLE_TRACE ("unqualified-name", dm);
1216 if (IS_DIGIT ((unsigned char) peek))
1217 RETURN_IF_ERROR (demangle_source_name (dm));
1218 else if (peek >= 'a' && peek <= 'z')
1221 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1223 else if (peek == 'C' || peek == 'D')
1224 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1226 return "Unexpected character in <unqualified-name>.";
1231 /* Demangles and emits <source-name>.
1233 <source-name> ::= <length number> <identifier> */
1236 demangle_source_name (dm)
1241 DEMANGLE_TRACE ("source-name", dm);
1243 /* Decode the length of the identifier. */
1244 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1246 return "Zero length in <source-name>.";
1248 /* Now the identifier itself. It's placed into last_source_name,
1249 where it can be used to build a constructor or destructor name. */
1250 RETURN_IF_ERROR (demangle_identifier (dm, length,
1251 dm->last_source_name));
1254 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1259 /* Demangles a number, either a <number> or a <positive-number> at the
1260 current position, consuming all consecutive digit characters. Sets
1261 *VALUE to the resulting numberand returns STATUS_OK. The number is
1262 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1263 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1265 <number> ::= [n] <positive-number>
1267 <positive-number> ::= <decimal integer> */
1270 demangle_number (dm, value, base, is_signed)
1276 dyn_string_t number = dyn_string_new (10);
1278 DEMANGLE_TRACE ("number", dm);
1281 return STATUS_ALLOCATION_FAILED;
1283 demangle_number_literally (dm, number, base, is_signed);
1284 *value = strtol (dyn_string_buf (number), NULL, base);
1285 dyn_string_delete (number);
1290 /* Demangles a number at the current position. The digits (and minus
1291 sign, if present) that make up the number are appended to STR.
1292 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1293 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1294 accepted. Does not consume a trailing underscore or other
1295 terminating character. */
1298 demangle_number_literally (dm, str, base, is_signed)
1304 DEMANGLE_TRACE ("number*", dm);
1306 if (base != 10 && base != 36)
1307 return STATUS_INTERNAL_ERROR;
1309 /* An `n' denotes a negative number. */
1310 if (is_signed && peek_char (dm) == 'n')
1312 /* Skip past the n. */
1314 /* The normal way to write a negative number is with a minus
1316 if (!dyn_string_append_char (str, '-'))
1317 return STATUS_ALLOCATION_FAILED;
1320 /* Loop until we hit a non-digit. */
1323 char peek = peek_char (dm);
1324 if (IS_DIGIT ((unsigned char) peek)
1325 || (base == 36 && peek >= 'A' && peek <= 'Z'))
1327 /* Accumulate digits. */
1328 if (!dyn_string_append_char (str, next_char (dm)))
1329 return STATUS_ALLOCATION_FAILED;
1332 /* Not a digit? All done. */
1339 /* Demangles an identifier at the current position of LENGTH
1340 characters and places it in IDENTIFIER. */
1343 demangle_identifier (dm, length, identifier)
1346 dyn_string_t identifier;
1348 DEMANGLE_TRACE ("identifier", dm);
1350 dyn_string_clear (identifier);
1351 if (!dyn_string_resize (identifier, length))
1352 return STATUS_ALLOCATION_FAILED;
1354 while (length-- > 0)
1356 if (end_of_name_p (dm))
1357 return "Unexpected end of name in <identifier>.";
1358 if (!dyn_string_append_char (identifier, next_char (dm)))
1359 return STATUS_ALLOCATION_FAILED;
1362 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1363 followed by the source file name and some random characters.
1364 Unless we're in strict mode, decipher these names appropriately. */
1367 char *name = dyn_string_buf (identifier);
1368 int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
1370 /* Compare the first, fixed part. */
1371 if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
1373 name += prefix_length;
1374 /* The next character might be a period, an underscore, or
1375 dollar sign, depending on the target architecture's
1376 assembler's capabilities. After that comes an `N'. */
1377 if ((*name == '.' || *name == '_' || *name == '$')
1378 && *(name + 1) == 'N')
1379 /* This looks like the anonymous namespace identifier.
1380 Replace it with something comprehensible. */
1381 dyn_string_copy_cstr (identifier, "(anonymous namespace)");
1388 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1389 the short form is emitted; otherwise the full source form
1390 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1391 operands that the operator takes.
1442 ::= cv <type> # cast
1443 ::= v [0-9] <source-name> # vendor extended operator */
1446 demangle_operator_name (dm, short_name, num_args)
1451 struct operator_code
1453 /* The mangled code for this operator. */
1455 /* The source name of this operator. */
1457 /* The number of arguments this operator takes. */
1461 static const struct operator_code operators[] =
1472 { "da", " delete[]", 1 },
1474 { "dl", " delete" , 1 },
1482 { "lS", "<<=" , 2 },
1491 { "na", " new[]" , 1 },
1495 { "nw", " new" , 1 },
1501 { "pm", "->*" , 2 },
1507 { "rS", ">>=" , 2 },
1510 { "sz", " sizeof" , 1 }
1513 const int num_operators =
1514 sizeof (operators) / sizeof (struct operator_code);
1516 int c0 = next_char (dm);
1517 int c1 = next_char (dm);
1518 const struct operator_code* p1 = operators;
1519 const struct operator_code* p2 = operators + num_operators;
1521 DEMANGLE_TRACE ("operator-name", dm);
1523 /* Is this a vendor-extended operator? */
1524 if (c0 == 'v' && IS_DIGIT (c1))
1526 RETURN_IF_ERROR (result_append (dm, "operator "));
1527 RETURN_IF_ERROR (demangle_source_name (dm));
1532 /* Is this a conversion operator? */
1533 if (c0 == 'c' && c1 == 'v')
1535 RETURN_IF_ERROR (result_append (dm, "operator "));
1536 /* Demangle the converted-to type. */
1537 RETURN_IF_ERROR (demangle_type (dm));
1542 /* Perform a binary search for the operator code. */
1545 const struct operator_code* p = p1 + (p2 - p1) / 2;
1546 char match0 = p->code[0];
1547 char match1 = p->code[1];
1549 if (c0 == match0 && c1 == match1)
1553 RETURN_IF_ERROR (result_append (dm, "operator"));
1554 RETURN_IF_ERROR (result_append (dm, p->name));
1555 *num_args = p->num_args;
1561 /* Couldn't find it. */
1562 return "Unknown code in <operator-name>.";
1565 if (c0 < match0 || (c0 == match0 && c1 < match1))
1572 /* Demangles and emits a <special-name>.
1574 <special-name> ::= GV <object name> # Guard variable
1575 ::= Th[n] <offset number> _ <base name> <base encoding>
1576 # non-virtual base override thunk
1577 ::= Tv[n] <offset number> _ <vcall offset number>
1579 # virtual base override thunk
1580 ::= TV <type> # virtual table
1582 ::= TI <type> # typeinfo structure
1583 ::= TS <type> # typeinfo name
1585 Also demangles the special g++ manglings,
1587 <special-name> ::= CT <type> <offset number> _ <base type>
1588 # construction vtable
1589 ::= TF <type> # typeinfo function (old ABI only)
1590 ::= TJ <type> # java Class structure */
1593 demangle_special_name (dm)
1596 dyn_string_t number;
1598 char peek = peek_char (dm);
1600 DEMANGLE_TRACE ("special-name", dm);
1604 /* A guard variable name. Consume the G. */
1606 RETURN_IF_ERROR (demangle_char (dm, 'V'));
1607 RETURN_IF_ERROR (result_append (dm, "guard variable for "));
1608 RETURN_IF_ERROR (demangle_name (dm, &unused));
1610 else if (peek == 'T')
1612 status_t status = STATUS_OK;
1614 /* Other C++ implementation miscellania. Consume the T. */
1617 switch (peek_char (dm))
1620 /* Virtual table. */
1622 RETURN_IF_ERROR (result_append (dm, "vtable for "));
1623 RETURN_IF_ERROR (demangle_type (dm));
1627 /* VTT structure. */
1629 RETURN_IF_ERROR (result_append (dm, "VTT for "));
1630 RETURN_IF_ERROR (demangle_type (dm));
1634 /* Typeinfo structure. */
1636 RETURN_IF_ERROR (result_append (dm, "typeinfo for "));
1637 RETURN_IF_ERROR (demangle_type (dm));
1641 /* Typeinfo function. Used only in old ABI with new mangling. */
1643 RETURN_IF_ERROR (result_append (dm, "typeinfo fn for "));
1644 RETURN_IF_ERROR (demangle_type (dm));
1648 /* Character string containing type name, used in typeinfo. */
1650 RETURN_IF_ERROR (result_append (dm, "typeinfo name for "));
1651 RETURN_IF_ERROR (demangle_type (dm));
1655 /* The java Class variable corresponding to a C++ class. */
1657 RETURN_IF_ERROR (result_append (dm, "java Class for "));
1658 RETURN_IF_ERROR (demangle_type (dm));
1662 /* Non-virtual thunk. */
1664 RETURN_IF_ERROR (result_append (dm, "non-virtual thunk"));
1665 /* Demangle and emit the offset. */
1666 number = dyn_string_new (4);
1668 return STATUS_ALLOCATION_FAILED;
1669 demangle_number_literally (dm, number, 10, 1);
1670 /* Don't display the offset unless in verbose mode. */
1673 status = result_append_char (dm, ' ');
1674 if (STATUS_NO_ERROR (status))
1675 status = result_append_string (dm, number);
1677 dyn_string_delete (number);
1678 RETURN_IF_ERROR (status);
1679 /* Demangle the separator. */
1680 RETURN_IF_ERROR (demangle_char (dm, '_'));
1681 /* Demangle and emit the target name and function type. */
1682 RETURN_IF_ERROR (result_append (dm, " to "));
1683 RETURN_IF_ERROR (demangle_encoding (dm));
1687 /* Virtual thunk. */
1689 RETURN_IF_ERROR (result_append (dm, "virtual thunk "));
1690 /* Demangle and emit the offset. */
1691 number = dyn_string_new (4);
1693 return STATUS_ALLOCATION_FAILED;
1694 demangle_number_literally (dm, number, 10, 1);
1695 /* Don't display the offset unless in verbose mode. */
1698 status = result_append_string (dm, number);
1699 if (STATUS_NO_ERROR (status))
1700 result_append_char (dm, ' ');
1702 dyn_string_delete (number);
1703 RETURN_IF_ERROR (status);
1704 /* Demangle the separator. */
1705 RETURN_IF_ERROR (demangle_char (dm, '_'));
1706 /* Demangle and emit the vcall offset. */
1707 number = dyn_string_new (4);
1709 return STATUS_ALLOCATION_FAILED;
1710 demangle_number_literally (dm, number, 10, 1);
1711 /* Don't display the vcall offset unless in verbose mode. */
1714 status = result_append_string (dm, number);
1715 if (STATUS_NO_ERROR (status))
1716 status = result_append_char (dm, ' ');
1718 dyn_string_delete (number);
1719 RETURN_IF_ERROR (status);
1720 /* Demangle the separator. */
1721 RETURN_IF_ERROR (demangle_char (dm, '_'));
1722 /* Demangle and emit the target function. */
1723 RETURN_IF_ERROR (result_append (dm, "to "));
1724 RETURN_IF_ERROR (demangle_encoding (dm));
1728 /* TC is a special g++ mangling for a construction vtable. */
1731 dyn_string_t derived_type;
1734 RETURN_IF_ERROR (result_append (dm, "construction vtable for "));
1736 /* Demangle the derived type off to the side. */
1737 RETURN_IF_ERROR (result_push (dm));
1738 RETURN_IF_ERROR (demangle_type (dm));
1739 derived_type = (dyn_string_t) result_pop (dm);
1741 /* Demangle the offset. */
1742 number = dyn_string_new (4);
1745 dyn_string_delete (derived_type);
1746 return STATUS_ALLOCATION_FAILED;
1748 demangle_number_literally (dm, number, 10, 1);
1749 /* Demangle the underscore separator. */
1750 status = demangle_char (dm, '_');
1752 /* Demangle the base type. */
1753 if (STATUS_NO_ERROR (status))
1754 status = demangle_type (dm);
1756 /* Emit the derived type. */
1757 if (STATUS_NO_ERROR (status))
1758 status = result_append (dm, "-in-");
1759 if (STATUS_NO_ERROR (status))
1760 status = result_append_string (dm, derived_type);
1761 dyn_string_delete (derived_type);
1763 /* Don't display the offset unless in verbose mode. */
1766 status = result_append_char (dm, ' ');
1767 if (STATUS_NO_ERROR (status))
1768 result_append_string (dm, number);
1770 dyn_string_delete (number);
1771 RETURN_IF_ERROR (status);
1774 /* If flag_strict, fall through. */
1777 return "Unrecognized <special-name>.";
1781 return STATUS_ERROR;
1786 /* Demangles and emits a <ctor-dtor-name>.
1789 ::= C1 # complete object (in-charge) ctor
1790 ::= C2 # base object (not-in-charge) ctor
1791 ::= C3 # complete object (in-charge) allocating ctor
1792 ::= D0 # deleting (in-charge) dtor
1793 ::= D1 # complete object (in-charge) dtor
1794 ::= D2 # base object (not-in-charge) dtor */
1797 demangle_ctor_dtor_name (dm)
1800 static const char *const ctor_flavors[] =
1806 static const char *const dtor_flavors[] =
1808 "in-charge deleting",
1814 char peek = peek_char (dm);
1816 DEMANGLE_TRACE ("ctor-dtor-name", dm);
1820 /* A constructor name. Consume the C. */
1822 if (peek_char (dm) < '1' || peek_char (dm) > '3')
1823 return "Unrecognized constructor.";
1824 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1825 /* Print the flavor of the constructor if in verbose mode. */
1826 flavor = next_char (dm) - '1';
1829 RETURN_IF_ERROR (result_append (dm, "["));
1830 RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor]));
1831 RETURN_IF_ERROR (result_append_char (dm, ']'));
1834 else if (peek == 'D')
1836 /* A destructor name. Consume the D. */
1838 if (peek_char (dm) < '0' || peek_char (dm) > '2')
1839 return "Unrecognized destructor.";
1840 RETURN_IF_ERROR (result_append_char (dm, '~'));
1841 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1842 /* Print the flavor of the destructor if in verbose mode. */
1843 flavor = next_char (dm) - '0';
1846 RETURN_IF_ERROR (result_append (dm, " ["));
1847 RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor]));
1848 RETURN_IF_ERROR (result_append_char (dm, ']'));
1852 return STATUS_ERROR;
1857 /* Handle pointer, reference, and pointer-to-member cases for
1858 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1859 build a pointer/reference type. We snarf all these, plus the
1860 following <type>, all at once since we need to know whether we have
1861 a pointer to data or pointer to function to construct the right
1862 output syntax. C++'s pointer syntax is hairy.
1864 This function adds substitution candidates for every nested
1865 pointer/reference type it processes, including the outermost, final
1866 type, assuming the substitution starts at SUBSTITUTION_START in the
1867 demangling result. For example, if this function demangles
1868 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
1869 `Foo**', in that order.
1871 *INSERT_POS is a quantity used internally, when this function calls
1872 itself recursively, to figure out where to insert pointer
1873 punctuation on the way up. On entry to this function, INSERT_POS
1874 should point to a temporary value, but that value need not be
1879 ::= <pointer-to-member-type>
1881 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1884 demangle_type_ptr (dm, insert_pos, substitution_start)
1887 int substitution_start;
1891 int is_substitution_candidate = 1;
1893 DEMANGLE_TRACE ("type*", dm);
1895 /* Scan forward, collecting pointers and references into symbols,
1896 until we hit something else. Then emit the type. */
1897 next = peek_char (dm);
1900 /* A pointer. Snarf the `P'. */
1902 /* Demangle the underlying type. */
1903 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
1904 substitution_start));
1905 /* Insert an asterisk where we're told to; it doesn't
1906 necessarily go at the end. */
1907 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
1909 else if (next == 'R')
1911 /* A reference. Snarf the `R'. */
1913 /* Demangle the underlying type. */
1914 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
1915 substitution_start));
1916 /* Insert an ampersand where we're told to; it doesn't
1917 necessarily go at the end. */
1918 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
1920 else if (next == 'M')
1922 /* A pointer-to-member. */
1923 dyn_string_t class_type;
1928 /* Capture the type of which this is a pointer-to-member. */
1929 RETURN_IF_ERROR (result_push (dm));
1930 RETURN_IF_ERROR (demangle_type (dm));
1931 class_type = (dyn_string_t) result_pop (dm);
1933 if (peek_char (dm) == 'F')
1934 /* A pointer-to-member function. We want output along the
1935 lines of `void (C::*) (int, int)'. Demangle the function
1936 type, which would in this case give `void () (int, int)'
1937 and set *insert_pos to the spot between the first
1939 status = demangle_type_ptr (dm, insert_pos, substitution_start);
1942 /* A pointer-to-member variable. Demangle the type of the
1943 pointed-to member. */
1944 status = demangle_type (dm);
1945 /* Make it pretty. */
1946 if (STATUS_NO_ERROR (status))
1947 status = result_append_space (dm);
1948 /* The pointer-to-member notation (e.g. `C::*') follows the
1950 *insert_pos = result_length (dm);
1953 /* Build the pointer-to-member notation. */
1954 if (STATUS_NO_ERROR (status))
1955 status = result_insert (dm, *insert_pos, "::*");
1956 if (STATUS_NO_ERROR (status))
1957 status = result_insert_string (dm, *insert_pos, class_type);
1958 /* There may be additional levels of (pointer or reference)
1959 indirection in this type. If so, the `*' and `&' should be
1960 added after the pointer-to-member notation (e.g. `C::*&' for
1961 a reference to a pointer-to-member of class C). */
1962 *insert_pos += dyn_string_length (class_type) + 3;
1965 dyn_string_delete (class_type);
1967 RETURN_IF_ERROR (status);
1969 else if (next == 'F')
1971 /* Ooh, tricky, a pointer-to-function. When we demangle the
1972 function type, the return type should go at the very
1974 *insert_pos = result_length (dm);
1975 /* The parentheses indicate this is a function pointer or
1977 RETURN_IF_ERROR (result_append (dm, "()"));
1978 /* Now demangle the function type. The return type will be
1979 inserted before the `()', and the argument list will go after
1981 RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
1982 /* We should now have something along the lines of
1983 `void () (int, int)'. The pointer or reference characters
1984 have to inside the first set of parentheses. *insert_pos has
1985 already been updated to point past the end of the return
1986 type. Move it one character over so it points inside the
1992 /* No more pointer or reference tokens; this is therefore a
1993 pointer to data. Finish up by demangling the underlying
1995 RETURN_IF_ERROR (demangle_type (dm));
1996 /* The pointer or reference characters follow the underlying
1997 type, as in `int*&'. */
1998 *insert_pos = result_length (dm);
1999 /* Because of the production <type> ::= <substitution>,
2000 demangle_type will already have added the underlying type as
2001 a substitution candidate. Don't do it again. */
2002 is_substitution_candidate = 0;
2005 if (is_substitution_candidate)
2006 RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
2011 /* Demangles and emits a <type>.
2013 <type> ::= <builtin-type>
2015 ::= <class-enum-type>
2017 ::= <pointer-to-member-type>
2018 ::= <template-param>
2019 ::= <template-template-param> <template-args>
2020 ::= <CV-qualifiers> <type>
2021 ::= P <type> # pointer-to
2022 ::= R <type> # reference-to
2023 ::= C <type> # complex pair (C 2000)
2024 ::= G <type> # imaginary (C 2000)
2025 ::= U <source-name> <type> # vendor extended type qualifier
2026 ::= <substitution> */
2032 int start = substitution_start (dm);
2033 char peek = peek_char (dm);
2036 template_arg_list_t old_arg_list = current_template_arg_list (dm);
2039 /* A <type> can be a <substitution>; therefore, this <type> is a
2040 substitution candidate unless a special condition holds (see
2042 int is_substitution_candidate = 1;
2044 DEMANGLE_TRACE ("type", dm);
2046 /* A <class-enum-type> can start with a digit (a <source-name>), an
2047 N (a <nested-name>), or a Z (a <local-name>). */
2048 if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
2049 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
2050 /* Lower-case letters begin <builtin-type>s, except for `r', which
2051 denotes restrict. */
2052 else if (peek >= 'a' && peek <= 'z' && peek != 'r')
2054 RETURN_IF_ERROR (demangle_builtin_type (dm));
2055 /* Built-in types are not substitution candidates. */
2056 is_substitution_candidate = 0;
2064 /* CV-qualifiers (including restrict). We have to demangle
2065 them off to the side, since C++ syntax puts them in a funny
2066 place for qualified pointer and reference types. */
2069 dyn_string_t cv_qualifiers = dyn_string_new (24);
2071 if (cv_qualifiers == NULL)
2072 return STATUS_ALLOCATION_FAILED;
2074 demangle_CV_qualifiers (dm, cv_qualifiers);
2076 /* If the qualifiers apply to a pointer or reference, they
2077 need to come after the whole qualified type. */
2078 if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
2080 status = demangle_type (dm);
2081 if (STATUS_NO_ERROR (status))
2082 status = result_append_space (dm);
2083 if (STATUS_NO_ERROR (status))
2084 status = result_append_string (dm, cv_qualifiers);
2086 /* Otherwise, the qualifiers come first. */
2089 status = result_append_string (dm, cv_qualifiers);
2090 if (STATUS_NO_ERROR (status))
2091 status = result_append_space (dm);
2092 if (STATUS_NO_ERROR (status))
2093 status = demangle_type (dm);
2096 dyn_string_delete (cv_qualifiers);
2097 RETURN_IF_ERROR (status);
2102 return "Non-pointer or -reference function type.";
2105 RETURN_IF_ERROR (demangle_array_type (dm));
2109 /* It's either a <template-param> or a
2110 <template-template-param>. In either case, demangle the
2112 RETURN_IF_ERROR (demangle_template_param (dm));
2114 /* Check for a template argument list; if one is found, it's a
2115 <template-template-param> ::= <template-param>
2116 ::= <substitution> */
2117 if (peek_char (dm) == 'I')
2119 /* Add a substitution candidate. The template parameter
2120 `T' token is a substitution candidate by itself,
2121 without the template argument list. */
2122 RETURN_IF_ERROR (substitution_add (dm, start, template_p));
2124 /* Now demangle the template argument list. */
2125 RETURN_IF_ERROR (demangle_template_args (dm));
2126 /* The entire type, including the template template
2127 parameter and its argument list, will be added as a
2128 substitution candidate below. */
2134 /* First check if this is a special substitution. If it is,
2135 this is a <class-enum-type>. Special substitutions have a
2136 letter following the `S'; other substitutions have a digit
2138 peek_next = peek_char_next (dm);
2139 if (IS_DIGIT (peek_next) || peek_next == '_')
2141 RETURN_IF_ERROR (demangle_substitution (dm, &template_p));
2143 /* The substituted name may have been a template name.
2144 Check if template arguments follow, and if so, demangle
2146 if (peek_char (dm) == 'I')
2147 RETURN_IF_ERROR (demangle_template_args (dm));
2149 /* A substitution token is not itself a substitution
2150 candidate. (However, if the substituted template is
2151 instantiated, the resulting type is.) */
2152 is_substitution_candidate = 0;
2155 /* While the special substitution token itself is not a
2156 substitution candidate, the <class-enum-type> is, so
2157 don't clear is_substitution_candidate. */
2158 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
2165 RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
2166 /* demangle_type_ptr adds all applicable substitution
2168 is_substitution_candidate = 0;
2172 /* A C99 complex type. */
2173 RETURN_IF_ERROR (result_append (dm, "complex "));
2175 RETURN_IF_ERROR (demangle_type (dm));
2179 /* A C99 imaginary type. */
2180 RETURN_IF_ERROR (result_append (dm, "imaginary "));
2182 RETURN_IF_ERROR (demangle_type (dm));
2186 /* Vendor-extended type qualifier. */
2188 RETURN_IF_ERROR (demangle_source_name (dm));
2189 RETURN_IF_ERROR (result_append_char (dm, ' '));
2190 RETURN_IF_ERROR (demangle_type (dm));
2194 return "Unexpected character in <type>.";
2197 if (is_substitution_candidate)
2198 /* Add a new substitution for the type. If this type was a
2199 <template-param>, pass its index since from the point of
2200 substitutions; a <template-param> token is a substitution
2201 candidate distinct from the type that is substituted for it. */
2202 RETURN_IF_ERROR (substitution_add (dm, start, template_p));
2204 /* Pop off template argument lists added during mangling of this
2206 pop_to_template_arg_list (dm, old_arg_list);
2211 /* C++ source names of builtin types, indexed by the mangled code
2212 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2213 static const char *const builtin_type_names[26] =
2215 "signed char", /* a */
2219 "long double", /* e */
2221 "__float128", /* g */
2222 "unsigned char", /* h */
2227 "unsigned long", /* m */
2229 "unsigned __int128", /* o */
2234 "unsigned short", /* t */
2238 "long long", /* x */
2239 "unsigned long long", /* y */
2243 /* Demangles and emits a <builtin-type>.
2245 <builtin-type> ::= v # void
2250 ::= h # unsigned char
2252 ::= t # unsigned short
2254 ::= j # unsigned int
2256 ::= m # unsigned long
2257 ::= x # long long, __int64
2258 ::= y # unsigned long long, __int64
2260 ::= o # unsigned __int128
2263 ::= e # long double, __float80
2266 ::= u <source-name> # vendor extended type */
2269 demangle_builtin_type (dm)
2273 char code = peek_char (dm);
2275 DEMANGLE_TRACE ("builtin-type", dm);
2280 RETURN_IF_ERROR (demangle_source_name (dm));
2283 else if (code >= 'a' && code <= 'z')
2285 const char *type_name = builtin_type_names[code - 'a'];
2286 if (type_name == NULL)
2287 return "Unrecognized <builtin-type> code.";
2289 RETURN_IF_ERROR (result_append (dm, type_name));
2294 return "Non-alphabetic <builtin-type> code.";
2297 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2298 restrict) at the current position. The qualifiers are appended to
2299 QUALIFIERS. Returns STATUS_OK. */
2302 demangle_CV_qualifiers (dm, qualifiers)
2304 dyn_string_t qualifiers;
2306 DEMANGLE_TRACE ("CV-qualifiers", dm);
2310 switch (peek_char (dm))
2313 if (!dyn_string_append_space (qualifiers))
2314 return STATUS_ALLOCATION_FAILED;
2315 if (!dyn_string_append_cstr (qualifiers, "restrict"))
2316 return STATUS_ALLOCATION_FAILED;
2320 if (!dyn_string_append_space (qualifiers))
2321 return STATUS_ALLOCATION_FAILED;
2322 if (!dyn_string_append_cstr (qualifiers, "volatile"))
2323 return STATUS_ALLOCATION_FAILED;
2327 if (!dyn_string_append_space (qualifiers))
2328 return STATUS_ALLOCATION_FAILED;
2329 if (!dyn_string_append_cstr (qualifiers, "const"))
2330 return STATUS_ALLOCATION_FAILED;
2341 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2342 position in the result string of the start of the function
2343 identifier, at which the function's return type will be inserted;
2344 *FUNCTION_NAME_POS is updated to position past the end of the
2345 function's return type.
2347 <function-type> ::= F [Y] <bare-function-type> E */
2350 demangle_function_type (dm, function_name_pos)
2352 int *function_name_pos;
2354 DEMANGLE_TRACE ("function-type", dm);
2355 RETURN_IF_ERROR (demangle_char (dm, 'F'));
2356 if (peek_char (dm) == 'Y')
2358 /* Indicate this function has C linkage if in verbose mode. */
2360 RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] "));
2363 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2364 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2368 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2369 position in the result string at which the function return type
2370 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2371 function's return type is assumed not to be encoded.
2373 <bare-function-type> ::= <signature type>+ */
2376 demangle_bare_function_type (dm, return_type_pos)
2378 int *return_type_pos;
2380 /* Sequence is the index of the current function parameter, counting
2381 from zero. The value -1 denotes the return type. */
2383 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2385 DEMANGLE_TRACE ("bare-function-type", dm);
2387 RETURN_IF_ERROR (result_append_char (dm, '('));
2388 while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2391 /* We're decoding the function's return type. */
2393 dyn_string_t return_type;
2394 status_t status = STATUS_OK;
2396 /* Decode the return type off to the side. */
2397 RETURN_IF_ERROR (result_push (dm));
2398 RETURN_IF_ERROR (demangle_type (dm));
2399 return_type = (dyn_string_t) result_pop (dm);
2401 /* Add a space to the end of the type. Insert the return
2402 type where we've been asked to. */
2403 if (!dyn_string_append_space (return_type))
2404 status = STATUS_ALLOCATION_FAILED;
2405 if (STATUS_NO_ERROR (status))
2407 if (!dyn_string_insert (result_string (dm), *return_type_pos,
2409 status = STATUS_ALLOCATION_FAILED;
2411 *return_type_pos += dyn_string_length (return_type);
2414 dyn_string_delete (return_type);
2415 RETURN_IF_ERROR (status);
2419 /* Skip `void' parameter types. One should only occur as
2420 the only type in a parameter list; in that case, we want
2421 to print `foo ()' instead of `foo (void)'. */
2422 if (peek_char (dm) == 'v')
2424 /* Consume the v. */
2428 /* Separate parameter types by commas. */
2430 RETURN_IF_ERROR (result_append (dm, ", "));
2431 /* Demangle the type. */
2432 RETURN_IF_ERROR (demangle_type (dm));
2437 RETURN_IF_ERROR (result_append_char (dm, ')'));
2442 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2443 non-zero if the type is a template-id, zero otherwise.
2445 <class-enum-type> ::= <name> */
2448 demangle_class_enum_type (dm, template_p)
2452 DEMANGLE_TRACE ("class-enum-type", dm);
2454 RETURN_IF_ERROR (demangle_name (dm, template_p));
2458 /* Demangles and emits an <array-type>.
2460 <array-type> ::= A [<dimension number>] _ <element type>
2461 ::= A <dimension expression> _ <element type> */
2464 demangle_array_type (dm)
2467 status_t status = STATUS_OK;
2468 dyn_string_t array_size = NULL;
2471 RETURN_IF_ERROR (demangle_char (dm, 'A'));
2473 /* Demangle the array size into array_size. */
2474 peek = peek_char (dm);
2476 /* Array bound is omitted. This is a C99-style VLA. */
2478 else if (IS_DIGIT (peek_char (dm)))
2480 /* It looks like a constant array bound. */
2481 array_size = dyn_string_new (10);
2482 if (array_size == NULL)
2483 return STATUS_ALLOCATION_FAILED;
2484 status = demangle_number_literally (dm, array_size, 10, 0);
2488 /* Anything is must be an expression for a nont-constant array
2489 bound. This happens if the array type occurs in a template
2490 and the array bound references a template parameter. */
2491 RETURN_IF_ERROR (result_push (dm));
2492 RETURN_IF_ERROR (demangle_expression (dm));
2493 array_size = (dyn_string_t) result_pop (dm);
2495 /* array_size may have been allocated by now, so we can't use
2496 RETURN_IF_ERROR until it's been deallocated. */
2498 /* Demangle the base type of the array. */
2499 if (STATUS_NO_ERROR (status))
2500 status = demangle_char (dm, '_');
2501 if (STATUS_NO_ERROR (status))
2502 status = demangle_type (dm);
2504 /* Emit the array dimension syntax. */
2505 if (STATUS_NO_ERROR (status))
2506 status = result_append_char (dm, '[');
2507 if (STATUS_NO_ERROR (status) && array_size != NULL)
2508 status = result_append_string (dm, array_size);
2509 if (STATUS_NO_ERROR (status))
2510 status = result_append_char (dm, ']');
2511 if (array_size != NULL)
2512 dyn_string_delete (array_size);
2514 RETURN_IF_ERROR (status);
2519 /* Demangles and emits a <template-param>.
2521 <template-param> ::= T_ # first template parameter
2522 ::= T <parameter-2 number> _ */
2525 demangle_template_param (dm)
2529 template_arg_list_t current_arg_list = current_template_arg_list (dm);
2532 DEMANGLE_TRACE ("template-param", dm);
2534 /* Make sure there is a template argmust list in which to look up
2535 this parameter reference. */
2536 if (current_arg_list == NULL)
2537 return "Template parameter outside of template.";
2539 RETURN_IF_ERROR (demangle_char (dm, 'T'));
2540 if (peek_char (dm) == '_')
2544 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2547 RETURN_IF_ERROR (demangle_char (dm, '_'));
2549 arg = template_arg_list_get_arg (current_arg_list, parm_number);
2551 /* parm_number exceeded the number of arguments in the current
2552 template argument list. */
2553 return "Template parameter number out of bounds.";
2554 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2559 /* Demangles and emits a <template-args>.
2561 <template-args> ::= I <template-arg>+ E */
2564 demangle_template_args (dm)
2568 dyn_string_t old_last_source_name;
2569 template_arg_list_t arg_list = template_arg_list_new ();
2571 if (arg_list == NULL)
2572 return STATUS_ALLOCATION_FAILED;
2574 /* Preserve the most recently demangled source name. */
2575 old_last_source_name = dm->last_source_name;
2576 dm->last_source_name = dyn_string_new (0);
2578 DEMANGLE_TRACE ("template-args", dm);
2580 if (dm->last_source_name == NULL)
2581 return STATUS_ALLOCATION_FAILED;
2583 RETURN_IF_ERROR (demangle_char (dm, 'I'));
2584 RETURN_IF_ERROR (result_open_template_list (dm));
2592 RETURN_IF_ERROR (result_append (dm, ", "));
2594 /* Capture the template arg. */
2595 RETURN_IF_ERROR (result_push (dm));
2596 RETURN_IF_ERROR (demangle_template_arg (dm));
2597 arg = result_pop (dm);
2599 /* Emit it in the demangled name. */
2600 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2602 /* Save it for use in expanding <template-param>s. */
2603 template_arg_list_add_arg (arg_list, arg);
2605 while (peek_char (dm) != 'E');
2606 /* Append the '>'. */
2607 RETURN_IF_ERROR (result_close_template_list (dm));
2609 /* Consume the 'E'. */
2612 /* Restore the most recent demangled source name. */
2613 dyn_string_delete (dm->last_source_name);
2614 dm->last_source_name = old_last_source_name;
2616 /* Push the list onto the top of the stack of template argument
2617 lists, so that arguments from it are used from now on when
2618 expanding <template-param>s. */
2619 push_template_arg_list (dm, arg_list);
2624 /* This function, which does not correspond to a production in the
2625 mangling spec, handles the `literal' production for both
2626 <template-arg> and <expr-primary>. It does not expect or consume
2627 the initial `L' or final `E'. The demangling is given by:
2629 <literal> ::= <type> </value/ number>
2631 and the emitted output is `(type)number'. */
2634 demangle_literal (dm)
2637 char peek = peek_char (dm);
2638 dyn_string_t value_string;
2641 DEMANGLE_TRACE ("literal", dm);
2643 if (!flag_verbose && peek >= 'a' && peek <= 'z')
2645 /* If not in verbose mode and this is a builtin type, see if we
2646 can produce simpler numerical output. In particular, for
2647 integer types shorter than `long', just write the number
2648 without type information; for bools, write `true' or `false'.
2649 Other refinements could be made here too. */
2651 /* This constant string is used to map from <builtin-type> codes
2652 (26 letters of the alphabet) to codes that determine how the
2653 value will be displayed. The codes are:
2657 A space means the value will be represented using cast
2659 static const char *const code_map = "ibi iii ll ii i ";
2661 char code = code_map[peek - 'a'];
2662 /* FIXME: Implement demangling of floats and doubles. */
2664 return STATUS_UNIMPLEMENTED;
2667 /* It's a boolean. */
2670 /* Consume the b. */
2672 /* Look at the next character. It should be 0 or 1,
2673 corresponding to false or true, respectively. */
2674 value = peek_char (dm);
2676 RETURN_IF_ERROR (result_append (dm, "false"));
2677 else if (value == '1')
2678 RETURN_IF_ERROR (result_append (dm, "true"));
2680 return "Unrecognized bool constant.";
2681 /* Consume the 0 or 1. */
2685 else if (code == 'i' || code == 'l')
2687 /* It's an integer or long. */
2689 /* Consume the type character. */
2692 /* Demangle the number and write it out. */
2693 value_string = dyn_string_new (0);
2694 status = demangle_number_literally (dm, value_string, 10, 1);
2695 if (STATUS_NO_ERROR (status))
2696 status = result_append_string (dm, value_string);
2697 /* For long integers, append an l. */
2698 if (code == 'l' && STATUS_NO_ERROR (status))
2699 status = result_append_char (dm, code);
2700 dyn_string_delete (value_string);
2702 RETURN_IF_ERROR (status);
2705 /* ...else code == ' ', so fall through to represent this
2706 literal's type explicitly using cast syntax. */
2709 RETURN_IF_ERROR (result_append_char (dm, '('));
2710 RETURN_IF_ERROR (demangle_type (dm));
2711 RETURN_IF_ERROR (result_append_char (dm, ')'));
2713 value_string = dyn_string_new (0);
2714 if (value_string == NULL)
2715 return STATUS_ALLOCATION_FAILED;
2717 status = demangle_number_literally (dm, value_string, 10, 1);
2718 if (STATUS_NO_ERROR (status))
2719 status = result_append_string (dm, value_string);
2720 dyn_string_delete (value_string);
2721 RETURN_IF_ERROR (status);
2726 /* Demangles and emits a <template-arg>.
2728 <template-arg> ::= <type> # type
2729 ::= L <type> <value number> E # literal
2730 ::= LZ <encoding> E # external name
2731 ::= X <expression> E # expression */
2734 demangle_template_arg (dm)
2737 DEMANGLE_TRACE ("template-arg", dm);
2739 switch (peek_char (dm))
2744 if (peek_char (dm) == 'Z')
2746 /* External name. */
2748 /* FIXME: Standard is contradictory here. */
2749 RETURN_IF_ERROR (demangle_encoding (dm));
2752 RETURN_IF_ERROR (demangle_literal (dm));
2753 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2759 RETURN_IF_ERROR (demangle_expression (dm));
2763 RETURN_IF_ERROR (demangle_type (dm));
2770 /* Demangles and emits an <expression>.
2772 <expression> ::= <unary operator-name> <expression>
2773 ::= <binary operator-name> <expression> <expression>
2775 ::= <scope-expression> */
2778 demangle_expression (dm)
2781 char peek = peek_char (dm);
2783 DEMANGLE_TRACE ("expression", dm);
2785 if (peek == 'L' || peek == 'T')
2786 RETURN_IF_ERROR (demangle_expr_primary (dm));
2787 else if (peek == 's' && peek_char_next (dm) == 'r')
2788 RETURN_IF_ERROR (demangle_scope_expression (dm));
2790 /* An operator expression. */
2793 status_t status = STATUS_OK;
2794 dyn_string_t operator_name;
2796 /* We have an operator name. Since we want to output binary
2797 operations in infix notation, capture the operator name
2799 RETURN_IF_ERROR (result_push (dm));
2800 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
2801 operator_name = (dyn_string_t) result_pop (dm);
2803 /* If it's binary, do an operand first. */
2806 status = result_append_char (dm, '(');
2807 if (STATUS_NO_ERROR (status))
2808 status = demangle_expression (dm);
2809 if (STATUS_NO_ERROR (status))
2810 status = result_append_char (dm, ')');
2813 /* Emit the operator. */
2814 if (STATUS_NO_ERROR (status))
2815 status = result_append_string (dm, operator_name);
2816 dyn_string_delete (operator_name);
2817 RETURN_IF_ERROR (status);
2819 /* Emit its second (if binary) or only (if unary) operand. */
2820 RETURN_IF_ERROR (result_append_char (dm, '('));
2821 RETURN_IF_ERROR (demangle_expression (dm));
2822 RETURN_IF_ERROR (result_append_char (dm, ')'));
2824 /* The ternary operator takes a third operand. */
2827 RETURN_IF_ERROR (result_append (dm, ":("));
2828 RETURN_IF_ERROR (demangle_expression (dm));
2829 RETURN_IF_ERROR (result_append_char (dm, ')'));
2836 /* Demangles and emits a <scope-expression>.
2838 <scope-expression> ::= sr <qualifying type> <source-name>
2839 ::= sr <qualifying type> <encoding> */
2842 demangle_scope_expression (dm)
2845 RETURN_IF_ERROR (demangle_char (dm, 's'));
2846 RETURN_IF_ERROR (demangle_char (dm, 'r'));
2847 RETURN_IF_ERROR (demangle_type (dm));
2848 RETURN_IF_ERROR (result_append (dm, "::"));
2849 RETURN_IF_ERROR (demangle_encoding (dm));
2853 /* Demangles and emits an <expr-primary>.
2855 <expr-primary> ::= <template-param>
2856 ::= L <type> <value number> E # literal
2857 ::= L <mangled-name> E # external name */
2860 demangle_expr_primary (dm)
2863 char peek = peek_char (dm);
2865 DEMANGLE_TRACE ("expr-primary", dm);
2868 RETURN_IF_ERROR (demangle_template_param (dm));
2869 else if (peek == 'L')
2871 /* Consume the `L'. */
2873 peek = peek_char (dm);
2876 RETURN_IF_ERROR (demangle_mangled_name (dm));
2878 RETURN_IF_ERROR (demangle_literal (dm));
2880 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2883 return STATUS_ERROR;
2888 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2889 if the substitution is the name of a template, zero otherwise.
2891 <substitution> ::= S <seq-id> _
2895 ::= Sa # ::std::allocator
2896 ::= Sb # ::std::basic_string
2897 ::= Ss # ::std::basic_string<char,
2898 ::std::char_traits<char>,
2899 ::std::allocator<char> >
2900 ::= Si # ::std::basic_istream<char,
2901 std::char_traits<char> >
2902 ::= So # ::std::basic_ostream<char,
2903 std::char_traits<char> >
2904 ::= Sd # ::std::basic_iostream<char,
2905 std::char_traits<char> >
2909 demangle_substitution (dm, template_p)
2917 DEMANGLE_TRACE ("substitution", dm);
2919 RETURN_IF_ERROR (demangle_char (dm, 'S'));
2921 /* Scan the substitution sequence index. A missing number denotes
2923 peek = peek_char (dm);
2926 /* If the following character is 0-9 or a capital letter, interpret
2927 the sequence up to the next underscore as a base-36 substitution
2929 else if (IS_DIGIT ((unsigned char) peek)
2930 || (peek >= 'A' && peek <= 'Z'))
2931 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
2934 const char *new_last_source_name = NULL;
2939 RETURN_IF_ERROR (result_append (dm, "std"));
2943 RETURN_IF_ERROR (result_append (dm, "std::allocator"));
2944 new_last_source_name = "allocator";
2949 RETURN_IF_ERROR (result_append (dm, "std::basic_string"));
2950 new_last_source_name = "basic_string";
2957 RETURN_IF_ERROR (result_append (dm, "std::string"));
2958 new_last_source_name = "string";
2962 RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
2963 new_last_source_name = "basic_string";
2971 RETURN_IF_ERROR (result_append (dm, "std::istream"));
2972 new_last_source_name = "istream";
2976 RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >"));
2977 new_last_source_name = "basic_istream";
2985 RETURN_IF_ERROR (result_append (dm, "std::ostream"));
2986 new_last_source_name = "ostream";
2990 RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >"));
2991 new_last_source_name = "basic_ostream";
2999 RETURN_IF_ERROR (result_append (dm, "std::iostream"));
3000 new_last_source_name = "iostream";
3004 RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >"));
3005 new_last_source_name = "basic_iostream";
3011 return "Unrecognized <substitution>.";
3014 /* Consume the character we just processed. */
3017 if (new_last_source_name != NULL)
3019 if (!dyn_string_copy_cstr (dm->last_source_name,
3020 new_last_source_name))
3021 return STATUS_ALLOCATION_FAILED;
3027 /* Look up the substitution text. Since `S_' is the most recent
3028 substitution, `S0_' is the second-most-recent, etc., shift the
3029 numbering by one. */
3030 text = substitution_get (dm, seq_id + 1, template_p);
3032 return "Substitution number out of range.";
3034 /* Emit the substitution text. */
3035 RETURN_IF_ERROR (result_append_string (dm, text));
3037 RETURN_IF_ERROR (demangle_char (dm, '_'));
3041 /* Demangles and emits a <local-name>.
3043 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3044 := Z <function encoding> E s [<discriminator>] */
3047 demangle_local_name (dm)
3050 DEMANGLE_TRACE ("local-name", dm);
3052 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
3053 RETURN_IF_ERROR (demangle_encoding (dm));
3054 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3055 RETURN_IF_ERROR (result_append (dm, "::"));
3057 if (peek_char (dm) == 's')
3059 /* Local character string literal. */
3060 RETURN_IF_ERROR (result_append (dm, "string literal"));
3061 /* Consume the s. */
3063 RETURN_IF_ERROR (demangle_discriminator (dm, 0));
3068 /* Local name for some other entity. Demangle its name. */
3069 RETURN_IF_ERROR (demangle_name (dm, &unused));
3070 RETURN_IF_ERROR (demangle_discriminator (dm, 1));
3076 /* Optimonally demangles and emits a <discriminator>. If there is no
3077 <discriminator> at the current position in the mangled string, the
3078 descriminator is assumed to be zero. Emit the discriminator number
3079 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3080 discriminator is zero.
3082 <discriminator> ::= _ <number> */
3085 demangle_discriminator (dm, suppress_first)
3089 /* Output for <discriminator>s to the demangled name is completely
3090 supressed if not in verbose mode. */
3092 if (peek_char (dm) == '_')
3094 /* Consume the underscore. */
3097 RETURN_IF_ERROR (result_append (dm, " [#"));
3098 /* Check if there's a number following the underscore. */
3099 if (IS_DIGIT ((unsigned char) peek_char (dm)))
3102 /* Demangle the number. */
3103 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
3105 /* Write the discriminator. The mangled number is two
3106 less than the discriminator ordinal, counting from
3108 RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2,
3109 (dyn_string_t) dm->result));
3114 /* A missing digit correspond to one. */
3115 RETURN_IF_ERROR (result_append_char (dm, '1'));
3118 RETURN_IF_ERROR (result_append_char (dm, ']'));
3120 else if (!suppress_first)
3123 RETURN_IF_ERROR (result_append (dm, " [#0]"));
3129 /* Demangle NAME into RESULT, which must be an initialized
3130 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3131 an error message, and the contents of RESULT are unchanged. */
3134 cp_demangle (name, result)
3136 dyn_string_t result;
3139 int length = strlen (name);
3141 if (length > 2 && name[0] == '_' && name[1] == 'Z')
3143 demangling_t dm = demangling_new (name);
3145 return STATUS_ALLOCATION_FAILED;
3147 status = result_push (dm);
3148 if (status != STATUS_OK)
3150 demangling_delete (dm);
3154 status = demangle_mangled_name (dm);
3155 if (STATUS_NO_ERROR (status))
3157 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3158 if (!dyn_string_copy (result, demangled))
3159 return STATUS_ALLOCATION_FAILED;
3160 dyn_string_delete (demangled);
3163 demangling_delete (dm);
3167 /* It's evidently not a mangled C++ name. It could be the name
3168 of something with C linkage, though, so just copy NAME into
3170 if (!dyn_string_copy_cstr (result, name))
3171 return STATUS_ALLOCATION_FAILED;
3178 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3179 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3180 an error message, and the contents of RESULT are unchanged. */
3184 cp_demangle_type (type_name, result)
3185 const char* type_name;
3186 dyn_string_t result;
3189 demangling_t dm = demangling_new (type_name);
3192 return STATUS_ALLOCATION_FAILED;
3194 /* Demangle the type name. The demangled name is stored in dm. */
3195 status = result_push (dm);
3196 if (status != STATUS_OK)
3198 demangling_delete (dm);
3202 status = demangle_type (dm);
3204 if (STATUS_NO_ERROR (status))
3206 /* The demangling succeeded. Pop the result out of dm and copy
3208 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3209 if (!dyn_string_copy (result, demangled))
3210 return STATUS_ALLOCATION_FAILED;
3211 dyn_string_delete (demangled);
3215 demangling_delete (dm);
3220 extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
3222 /* ABI-mandated entry point in the C++ runtime library for performing
3223 demangling. MANGLED_NAME is a NUL-terminated character string
3224 containing the name to be demangled.
3226 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3227 *LENGTH bytes, into which the demangled name is stored. If
3228 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3229 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3230 is placed in a region of memory allocated with malloc.
3232 If LENGTH is non-NULL, the length of the buffer conaining the
3233 demangled name, is placed in *LENGTH.
3235 The return value is a pointer to the start of the NUL-terminated
3236 demangled name, or NULL if the demangling fails. The caller is
3237 responsible for deallocating this memory using free.
3239 *STATUS is set to one of the following values:
3240 0: The demangling operation succeeded.
3241 -1: A memory allocation failiure occurred.
3242 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3243 -3: One of the arguments is invalid.
3245 The demagling is performed using the C++ ABI mangling rules, with
3249 __cxa_demangle (mangled_name, output_buffer, length, status)
3250 const char *mangled_name;
3251 char *output_buffer;
3255 struct dyn_string demangled_name;
3261 if (mangled_name == NULL) {
3266 /* Did the caller provide a buffer for the demangled name? */
3267 if (output_buffer == NULL) {
3268 /* No; dyn_string will malloc a buffer for us. */
3269 if (!dyn_string_init (&demangled_name, 0))
3276 /* Yes. Check that the length was provided. */
3277 if (length == NULL) {
3281 /* Install the buffer into a dyn_string. */
3282 demangled_name.allocated = *length;
3283 demangled_name.length = 0;
3284 demangled_name.s = output_buffer;
3287 if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
3288 /* MANGLED_NAME apprears to be a function or variable name.
3289 Demangle it accordingly. */
3290 result = cp_demangle (mangled_name, &demangled_name);
3292 /* Try to demangled MANGLED_NAME as the name of a type. */
3293 result = cp_demangle_type (mangled_name, &demangled_name);
3295 if (result == STATUS_OK)
3296 /* The demangling succeeded. */
3298 /* If LENGTH isn't NULL, store the allocated buffer length
3299 there; the buffer may have been realloced by dyn_string
3302 *length = demangled_name.allocated;
3303 /* The operation was a success. */
3305 return dyn_string_buf (&demangled_name);
3307 else if (result == STATUS_ALLOCATION_FAILED)
3308 /* A call to malloc or realloc failed during the demangling
3315 /* The demangling failed for another reason, most probably because
3316 MANGLED_NAME isn't a valid mangled name. */
3318 /* If the buffer containing the demangled name wasn't provided
3319 by the caller, free it. */
3320 if (output_buffer == NULL)
3321 free (dyn_string_buf (&demangled_name));
3327 #else /* !IN_LIBGCC2 */
3329 /* Variant entry point for integration with the existing cplus-dem
3330 demangler. Attempts to demangle MANGLED. If the demangling
3331 succeeds, returns a buffer, allocated with malloc, containing the
3332 demangled name. The caller must deallocate the buffer using free.
3333 If the demangling failes, returns NULL. */
3336 cplus_demangle_new_abi (mangled)
3337 const char* mangled;
3339 /* Create a dyn_string to hold the demangled name. */
3340 dyn_string_t demangled = dyn_string_new (0);
3341 /* Attempt the demangling. */
3342 status_t status = cp_demangle ((char *) mangled, demangled);
3343 if (STATUS_NO_ERROR (status))
3344 /* Demangling succeeded. */
3346 /* Grab the demangled result from the dyn_string. It was
3347 allocated with malloc, so we can return it directly. */
3348 char *return_value = dyn_string_release (demangled);
3349 /* Hand back the demangled name. */
3350 return return_value;
3352 else if (status == STATUS_ALLOCATION_FAILED)
3354 fprintf (stderr, "Memory allocation failed.\n");
3358 /* Demangling failed. */
3360 dyn_string_delete (demangled);
3365 #endif /* IN_LIBGCC2 */
3367 #ifdef STANDALONE_DEMANGLER
3371 static void print_usage
3372 PARAMS ((FILE* fp, int exit_value));
3374 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3375 #define is_mangled_char(CHAR) \
3376 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3377 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3379 /* The name of this program, as invoked. */
3380 const char* program_name;
3382 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3385 print_usage (fp, exit_value)
3389 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
3390 fprintf (fp, "Options:\n");
3391 fprintf (fp, " -h,--help Display this message.\n");
3392 fprintf (fp, " -s,--strict Demangle standard names only.\n");
3393 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
3394 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3399 /* Option specification for getopt_long. */
3400 static struct option long_options[] =
3402 { "help", no_argument, NULL, 'h' },
3403 { "strict", no_argument, NULL, 's' },
3404 { "verbose", no_argument, NULL, 'v' },
3405 { NULL, no_argument, NULL, 0 },
3408 /* Main entry for a demangling filter executable. It will demangle
3409 its command line arguments, if any. If none are provided, it will
3410 filter stdin to stdout, replacing any recognized mangled C++ names
3411 with their demangled equivalents. */
3422 /* Use the program name of this program, as invoked. */
3423 program_name = argv[0];
3425 /* Parse options. */
3428 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
3431 case '?': /* Unrecognized option. */
3432 print_usage (stderr, 1);
3436 print_usage (stdout, 0);
3448 while (opt_char != -1);
3451 /* No command line arguments were provided. Filter stdin. */
3453 dyn_string_t mangled = dyn_string_new (3);
3454 dyn_string_t demangled = dyn_string_new (0);
3457 /* Read all of input. */
3458 while (!feof (stdin))
3460 char c = getchar ();
3462 /* The first character of a mangled name is an underscore. */
3467 /* It's not a mangled name. Print the character and go
3474 /* The second character of a mangled name is a capital `Z'. */
3479 /* It's not a mangled name. Print the previous
3480 underscore, the `Z', and go on. */
3486 /* Start keeping track of the candidate mangled name. */
3487 dyn_string_append_char (mangled, '_');
3488 dyn_string_append_char (mangled, 'Z');
3490 /* Pile characters into mangled until we hit one that can't
3491 occur in a mangled name. */
3493 while (!feof (stdin) && is_mangled_char (c))
3495 dyn_string_append_char (mangled, c);
3501 /* Attempt to demangle the name. */
3502 status = cp_demangle (dyn_string_buf (mangled), demangled);
3504 /* If the demangling succeeded, great! Print out the
3505 demangled version. */
3506 if (STATUS_NO_ERROR (status))
3507 fputs (dyn_string_buf (demangled), stdout);
3508 /* Abort on allocation failures. */
3509 else if (status == STATUS_ALLOCATION_FAILED)
3511 fprintf (stderr, "Memory allocation failed.\n");
3514 /* Otherwise, it might not have been a mangled name. Just
3515 print out the original text. */
3517 fputs (dyn_string_buf (mangled), stdout);
3519 /* If we haven't hit EOF yet, we've read one character that
3520 can't occur in a mangled name, so print it out. */
3524 /* Clear the candidate mangled name, to start afresh next
3525 time we hit a `_Z'. */
3526 dyn_string_clear (mangled);
3529 dyn_string_delete (mangled);
3530 dyn_string_delete (demangled);
3533 /* Demangle command line arguments. */
3535 dyn_string_t result = dyn_string_new (0);
3537 /* Loop over command line arguments. */
3538 for (i = optind; i < argc; ++i)
3540 /* Attempt to demangle. */
3541 status = cp_demangle (argv[i], result);
3543 /* If it worked, print the demangled name. */
3544 if (STATUS_NO_ERROR (status))
3545 printf ("%s\n", dyn_string_buf (result));
3546 /* Abort on allocaiton failures. */
3547 else if (status == STATUS_ALLOCATION_FAILED)
3549 fprintf (stderr, "Memory allocaiton failed.\n");
3552 /* If not, print the error message to stderr instead. */
3554 fprintf (stderr, "%s\n", status);
3556 dyn_string_delete (result);
3562 #endif /* STANDALONE_DEMANGLER */