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
43 #include "libiberty.h"
44 #include "dyn-string.h"
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));
54 #define DEMANGLE_TRACE(PRODUCTION, DM)
57 /* If flag_verbose is zero, some simplifications will be made to the
58 output to make it easier to read and supress details that are
59 generally not of interest to the average C++ programmer.
60 Otherwise, the demangled representation will attempt to convey as
61 much information as the mangled form. */
62 static int flag_verbose;
64 /* If flag_strict is non-zero, demangle strictly according to the
65 specification -- don't demangle special g++ manglings. */
66 static int flag_strict;
68 /* String_list_t is an extended form of dyn_string_t which provides a link
69 field. A string_list_t may safely be cast to and used as a
72 struct string_list_def
74 struct dyn_string string;
75 struct string_list_def *next;
78 typedef struct string_list_def *string_list_t;
80 /* Data structure representing a potential substitution. */
82 struct substitution_def
84 /* The demangled text of the substitution. */
87 /* The template parameter that this represents, indexed from zero.
88 If this is not a template paramter number, the value is
90 int template_parm_number;
92 /* Whether this substitution represents a template item. */
96 #define NOT_TEMPLATE_PARM (-1)
98 /* Data structure representing a template argument list. */
100 struct template_arg_list_def
102 /* The next (lower) template argument list in the stack of currently
103 active template arguments. */
104 struct template_arg_list_def *next;
106 /* The first element in the list of template arguments in
107 left-to-right order. */
108 string_list_t first_argument;
110 /* The last element in the arguments lists. */
111 string_list_t last_argument;
114 typedef struct template_arg_list_def *template_arg_list_t;
116 /* Data structure to maintain the state of the current demangling. */
118 struct demangling_def
120 /* The full mangled name being mangled. */
123 /* Pointer into name at the current position. */
126 /* Stack for strings containing demangled result generated so far.
127 Text is emitted to the topmost (first) string. */
128 string_list_t result;
130 /* The number of presently available substitutions. */
131 int num_substitutions;
133 /* The allocated size of the substitutions array. */
134 int substitutions_allocated;
136 /* An array of available substitutions. The number of elements in
137 the array is given by num_substitions, and the allocated array
138 size in substitutions_size.
140 The most recent substition is at the end, so
142 - `S_' corresponds to substititutions[num_substitutions - 1]
143 - `S0_' corresponds to substititutions[num_substitutions - 2]
146 struct substitution_def *substitutions;
148 /* The stack of template argument lists. */
149 template_arg_list_t template_arg_lists;
151 /* The most recently demangled source-name. */
152 dyn_string_t last_source_name;
155 typedef struct demangling_def *demangling_t;
157 /* This type is the standard return code from most functions. Values
158 other than STATUS_OK contain descriptive messages. */
159 typedef const char *status_t;
161 /* Special values that can be used as a status_t. */
162 #define STATUS_OK NULL
163 #define STATUS_ERROR "Error."
164 #define STATUS_UNIMPLEMENTED "Unimplemented."
165 #define STATUS_INTERNAL_ERROR "Internal error."
167 static void int_to_dyn_string
168 PARAMS ((int, dyn_string_t));
169 static string_list_t string_list_new
171 static void string_list_delete
172 PARAMS ((string_list_t));
173 static void result_close_template_list
174 PARAMS ((demangling_t));
175 static void result_push
176 PARAMS ((demangling_t));
177 static string_list_t result_pop
178 PARAMS ((demangling_t));
179 static int substitution_start
180 PARAMS ((demangling_t));
181 static void substitution_add
182 PARAMS ((demangling_t, int, int, int));
183 static dyn_string_t substitution_get
184 PARAMS ((demangling_t, int, int *));
185 #ifdef CP_DEMANGLE_DEBUG
186 static void substitutions_print
187 PARAMS ((demangling_t, FILE *));
189 static template_arg_list_t template_arg_list_new
191 static void template_arg_list_delete
192 PARAMS ((template_arg_list_t));
193 static void template_arg_list_add_arg
194 PARAMS ((template_arg_list_t, string_list_t));
195 static string_list_t template_arg_list_get_arg
196 PARAMS ((template_arg_list_t, int));
197 static void push_template_arg_list
198 PARAMS ((demangling_t, template_arg_list_t));
199 static void pop_to_template_arg_list
200 PARAMS ((demangling_t, template_arg_list_t));
201 #ifdef CP_DEMANGLE_DEBUG
202 static void template_arg_list_print
203 PARAMS ((template_arg_list_t, FILE *));
205 static template_arg_list_t current_template_arg_list
206 PARAMS ((demangling_t));
207 static demangling_t demangling_new
209 static void demangling_delete
210 PARAMS ((demangling_t));
212 /* The last character of DS. Warning: DS is evaluated twice. */
213 #define dyn_string_last_char(DS) \
214 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
216 /* Append a space character (` ') to DS if it does not already end
218 #define dyn_string_append_space(DS) \
221 if (dyn_string_length (DS) > 0 \
222 && dyn_string_last_char (DS) != ' ') \
223 dyn_string_append_char ((DS), ' '); \
227 /* Returns the index of the current position in the mangled name. */
228 #define current_position(DM) ((DM)->next - (DM)->name)
230 /* Returns the character at the current position of the mangled name. */
231 #define peek_char(DM) (*((DM)->next))
233 /* Returns the character one past the current position of the mangled
235 #define peek_char_next(DM) \
236 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
238 /* Returns the character at the current position, and advances the
239 current position to the next character. */
240 #define next_char(DM) (*((DM)->next)++)
242 /* Returns non-zero if the current position is the end of the mangled
243 name, i.e. one past the last character. */
244 #define end_of_name_p(DM) (peek_char (DM) == '\0')
246 /* Advances the current position by one character. */
247 #define advance_char(DM) (++(DM)->next)
249 /* Returns the string containing the current demangled result. */
250 #define result_string(DM) (&(DM)->result->string)
252 /* Appends a dyn_string_t to the demangled result. */
253 #define result_append_string(DM, STRING) \
254 dyn_string_append (&(DM)->result->string, (STRING))
256 /* Appends NUL-terminated string CSTR to the demangled result. */
257 #define result_append(DM, CSTR) \
258 dyn_string_append_cstr (&(DM)->result->string, (CSTR))
260 /* Appends character CHAR to the demangled result. */
261 #define result_append_char(DM, CHAR) \
262 dyn_string_append_char (&(DM)->result->string, (CHAR))
264 /* The length of the current demangled result. */
265 #define result_length(DM) \
266 dyn_string_length (&(DM)->result->string)
268 /* Appends a space to the demangled result if the last character is
270 #define result_append_space(DM) \
271 dyn_string_append_space (&(DM)->result->string)
273 /* Evaluate EXPR, which must produce a status_t. If the status code
274 indicates an error, return from the current function with that
276 #define RETURN_IF_ERROR(EXPR) \
280 if (s != STATUS_OK) \
285 /* Appends a base 10 representation of VALUE to DS. */
288 int_to_dyn_string (value, ds)
295 /* Handle zero up front. */
298 dyn_string_append_char (ds, '0');
302 /* For negative numbers, emit a minus sign. */
305 dyn_string_append_char (ds, '-');
309 /* Find the power of 10 of the first digit. */
317 /* Write the digits. */
320 int digit = value / mask;
321 dyn_string_append_char (ds, '0' + digit);
322 value -= digit * mask;
327 /* Creates a new string list node. The contents of the string are
328 empty, but the initial buffer allocation is LENGTH. The string
329 list node should be deleted with string_list_delete. */
332 string_list_new (length)
336 (string_list_t) xmalloc (sizeof (struct string_list_def));
337 dyn_string_init ((dyn_string_t) s, length);
341 /* Deletes the entire string list starting at NODE. */
344 string_list_delete (node)
349 string_list_t next = node->next;
355 /* Appends a greater-than character to the demangled result. If the
356 last character is a greater-than character, a space is inserted
357 first, so that the two greater-than characters don't look like a
358 right shift token. */
361 result_close_template_list (dm)
364 dyn_string_t s = &dm->result->string;
365 if (dyn_string_last_char (s) == '>')
366 dyn_string_append_char (s, ' ');
367 dyn_string_append_char (s, '>');
370 /* Allocates and pushes a new string onto the demangled results stack
371 for DM. Subsequent demangling with DM will emit to the new string. */
377 string_list_t new_string = string_list_new (0);
378 new_string->next = (string_list_t) dm->result;
379 dm->result = new_string;
382 /* Removes and returns the topmost element on the demangled results
383 stack for DM. The caller assumes ownership for the returned
390 string_list_t top = dm->result;
391 dm->result = top->next;
395 /* Returns the start position of a fragment of the demangled result
396 that will be a substitution candidate. Should be called at the
397 start of productions that can add substitutions. */
400 substitution_start (dm)
403 return result_length (dm);
406 /* Adds the suffix of the current demangled result of DM starting at
407 START_POSITION as a potential substitution. If TEMPLATE_P is
408 non-zero, this potential substitution is a template-id.
410 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
411 is for that particular <template-param>, and is distinct from other
412 otherwise-identical types and other <template-param>s with
413 different indices. */
416 substitution_add (dm, start_position, template_p, template_parm_number)
420 int template_parm_number;
422 dyn_string_t result = result_string (dm);
423 dyn_string_t substitution = dyn_string_new (0);
426 dyn_string_substring (substitution,
427 result, start_position, result_length (dm));
429 /* Check whether SUBSTITUTION already occurs. */
430 for (i = 0; i < dm->num_substitutions; ++i)
431 if (dyn_string_eq (dm->substitutions[i].text, substitution)
432 && dm->substitutions[i].template_parm_number == template_parm_number)
433 /* Found SUBSTITUTION already present. */
435 /* Callers expect this function to take ownership of
436 SUBSTITUTION, so delete it. */
437 dyn_string_delete (substitution);
441 /* If there's no room for the new entry, grow the array. */
442 if (dm->substitutions_allocated == dm->num_substitutions)
444 dm->substitutions_allocated *= 2;
445 dm->substitutions = (struct substitution_def *)
446 xrealloc (dm->substitutions,
447 sizeof (struct substitution_def)
448 * dm->substitutions_allocated);
451 /* Add the substitution to the array. */
452 dm->substitutions[i].text = substitution;
453 dm->substitutions[i].template_p = template_p;
454 dm->substitutions[i].template_parm_number = template_parm_number;
455 ++dm->num_substitutions;
457 #ifdef CP_DEMANGLE_DEBUG
458 substitutions_print (dm, stderr);
462 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
463 non-zero if the substitution is a template-id, zero otherwise.
464 N is numbered from zero. DM retains ownership of the returned
465 string. If N is negative, or equal to or greater than the current
466 number of substitution candidates, returns NULL. */
469 substitution_get (dm, n, template_p)
474 struct substitution_def *sub;
476 /* Make sure N is in the valid range. */
477 if (n < 0 || n >= dm->num_substitutions)
480 sub = &(dm->substitutions[n]);
481 *template_p = sub->template_p;
485 #ifdef CP_DEMANGLE_DEBUG
486 /* Debugging routine to print the current substitutions to FP. */
489 substitutions_print (dm, fp)
494 int num = dm->num_substitutions;
496 fprintf (fp, "SUBSTITUTIONS:\n");
497 for (seq_id = -1; seq_id < num - 1; ++seq_id)
500 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
503 fprintf (fp, " S_ ");
505 fprintf (fp, " S%d_", seq_id);
506 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
510 #endif /* CP_DEMANGLE_DEBUG */
512 /* Creates a new template argument list. */
514 static template_arg_list_t
515 template_arg_list_new ()
517 template_arg_list_t new_list
518 = (template_arg_list_t) xmalloc (sizeof (struct template_arg_list_def));
519 /* Initialize the new list to have no arguments. */
520 new_list->first_argument = NULL;
521 new_list->last_argument = NULL;
522 /* Return the new list. */
526 /* Deletes a template argument list and the template arguments it
530 template_arg_list_delete (list)
531 template_arg_list_t list;
533 /* If there are any arguments on LIST, delete them. */
534 if (list->first_argument != NULL)
535 string_list_delete (list->first_argument);
540 /* Adds ARG to the template argument list ARG_LIST. */
543 template_arg_list_add_arg (arg_list, arg)
544 template_arg_list_t arg_list;
547 if (arg_list->first_argument == NULL)
548 /* If there were no arguments before, ARG is the first one. */
549 arg_list->first_argument = arg;
551 /* Make ARG the last argument on the list. */
552 arg_list->last_argument->next = arg;
553 /* Make ARG the last on the list. */
554 arg_list->last_argument = arg;
558 /* Returns the template arugment at position INDEX in template
559 argument list ARG_LIST. */
562 template_arg_list_get_arg (arg_list, index)
563 template_arg_list_t arg_list;
566 string_list_t arg = arg_list->first_argument;
567 /* Scan down the list of arguments to find the one at position
573 /* Ran out of arguments before INDEX hit zero. That's an
577 /* Return the argument at position INDEX. */
581 /* Pushes ARG_LIST onto the top of the template argument list stack. */
584 push_template_arg_list (dm, arg_list)
586 template_arg_list_t arg_list;
588 arg_list->next = dm->template_arg_lists;
589 dm->template_arg_lists = arg_list;
590 #ifdef CP_DEMANGLE_DEBUG
591 fprintf (stderr, " ** pushing template arg list\n");
592 template_arg_list_print (arg_list, stderr);
596 /* Pops and deletes elements on the template argument list stack until
597 arg_list is the topmost element. If arg_list is NULL, all elements
598 are popped and deleted. */
601 pop_to_template_arg_list (dm, arg_list)
603 template_arg_list_t arg_list;
605 while (dm->template_arg_lists != arg_list)
607 template_arg_list_t top = dm->template_arg_lists;
608 /* Disconnect the topmost element from the list. */
609 dm->template_arg_lists = top->next;
610 /* Delete the popped element. */
611 template_arg_list_delete (top);
612 #ifdef CP_DEMANGLE_DEBUG
613 fprintf (stderr, " ** removing template arg list\n");
618 #ifdef CP_DEMANGLE_DEBUG
620 /* Prints the contents of ARG_LIST to FP. */
623 template_arg_list_print (arg_list, fp)
624 template_arg_list_t arg_list;
630 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
631 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
634 fprintf (fp, " T_ : ");
636 fprintf (fp, " T%d_ : ", index);
638 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
642 #endif /* CP_DEMANGLE_DEBUG */
644 /* Returns the topmost element on the stack of template argument
645 lists. If there is no list of template arguments, returns NULL. */
647 static template_arg_list_t
648 current_template_arg_list (dm)
651 return dm->template_arg_lists;
654 /* Allocates a demangling_t object for demangling mangled NAME. A new
655 result must be pushed before the returned object can be used. */
658 demangling_new (name)
661 demangling_t dm = (demangling_t)
662 xmalloc (sizeof (struct demangling_def));
667 dm->last_source_name = dyn_string_new (0);
668 dm->num_substitutions = 0;
669 dm->substitutions_allocated = 10;
670 dm->substitutions = (struct substitution_def *)
671 xmalloc (dm->substitutions_allocated * sizeof (struct substitution_def));
672 dm->template_arg_lists = NULL;
677 /* Deallocates a demangling_t object and all memory associated with
681 demangling_delete (dm)
685 template_arg_list_t arg_list = dm->template_arg_lists;
687 /* Delete the stack of template argument lists. */
688 while (arg_list != NULL)
690 template_arg_list_t next = arg_list->next;
691 template_arg_list_delete (arg_list);
694 /* Delete the list of substitutions. */
695 for (i = dm->num_substitutions; --i >= 0; )
696 dyn_string_delete (dm->substitutions[i].text);
697 free (dm->substitutions);
698 /* Delete the demangled result. */
699 string_list_delete (dm->result);
700 /* Delete the stored identifier name. */
701 dyn_string_delete (dm->last_source_name);
702 /* Delete the context object itself. */
706 /* These functions demangle an alternative of the corresponding
707 production in the mangling spec. The first argument of each is a
708 demangling context structure for the current demangling
709 operation. Most emit demangled text directly to the topmost result
710 string on the result string stack in the demangling context
713 static status_t demangle_char
714 PARAMS ((demangling_t, int));
715 static status_t demangle_mangled_name
716 PARAMS ((demangling_t));
717 static status_t demangle_encoding
718 PARAMS ((demangling_t));
719 static status_t demangle_name
720 PARAMS ((demangling_t, int *));
721 static status_t demangle_nested_name
722 PARAMS ((demangling_t, int *));
723 static status_t demangle_prefix
724 PARAMS ((demangling_t, int *));
725 static status_t demangle_unqualified_name
726 PARAMS ((demangling_t));
727 static status_t demangle_source_name
728 PARAMS ((demangling_t));
729 static status_t demangle_number
730 PARAMS ((demangling_t, int *, int, int));
731 static status_t demangle_number_literally
732 PARAMS ((demangling_t, dyn_string_t, int, int));
733 static status_t demangle_identifier
734 PARAMS ((demangling_t, int, dyn_string_t));
735 static status_t demangle_operator_name
736 PARAMS ((demangling_t, int, int *));
737 static status_t demangle_special_name
738 PARAMS ((demangling_t));
739 static status_t demangle_ctor_dtor_name
740 PARAMS ((demangling_t));
741 static status_t demangle_type_ptr
742 PARAMS ((demangling_t));
743 static status_t demangle_type
744 PARAMS ((demangling_t));
745 static status_t demangle_CV_qualifiers
746 PARAMS ((demangling_t, dyn_string_t));
747 static status_t demangle_builtin_type
748 PARAMS ((demangling_t));
749 static status_t demangle_function_type
750 PARAMS ((demangling_t, int));
751 static status_t demangle_bare_function_type
752 PARAMS ((demangling_t, int));
753 static status_t demangle_class_enum_type
754 PARAMS ((demangling_t, int *));
755 static status_t demangle_array_type
756 PARAMS ((demangling_t));
757 static status_t demangle_template_param
758 PARAMS ((demangling_t, int *));
759 static status_t demangle_template_args
760 PARAMS ((demangling_t));
761 static status_t demangle_literal
762 PARAMS ((demangling_t));
763 static status_t demangle_template_arg
764 PARAMS ((demangling_t));
765 static status_t demangle_expression
766 PARAMS ((demangling_t));
767 static status_t demangle_scope_expression
768 PARAMS ((demangling_t));
769 static status_t demangle_expr_primary
770 PARAMS ((demangling_t));
771 static status_t demangle_substitution
772 PARAMS ((demangling_t, int *, int *));
773 static status_t demangle_local_name
774 PARAMS ((demangling_t));
775 static status_t demangle_discriminator
776 PARAMS ((demangling_t, int));
777 static status_t cp_demangle
778 PARAMS ((char *, dyn_string_t));
780 /* When passed to demangle_bare_function_type, indicates that the
781 function's return type is not encoded before its parameter types. */
782 #define BFT_NO_RETURN_TYPE -1
784 /* Check that the next character is C. If so, consume it. If not,
788 demangle_char (dm, c)
792 static char *error_message = NULL;
794 if (peek_char (dm) == c)
801 if (error_message == NULL)
802 error_message = strdup ("Expected ?");
803 error_message[9] = c;
804 return error_message;
808 /* Demangles and emits a <mangled-name>.
810 <mangled-name> ::= _Z <encoding> */
813 demangle_mangled_name (dm)
816 DEMANGLE_TRACE ("mangled-name", dm);
817 RETURN_IF_ERROR (demangle_char (dm, '_'));
818 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
819 RETURN_IF_ERROR (demangle_encoding (dm));
823 /* Demangles and emits an <encoding>.
825 <encoding> ::= <function name> <bare-function-type>
827 ::= <substitution> */
830 demangle_encoding (dm)
834 int special_std_substitution;
836 int start = substitution_start (dm);
837 template_arg_list_t old_arg_list = current_template_arg_list (dm);
838 char peek = peek_char (dm);
840 DEMANGLE_TRACE ("encoding", dm);
842 /* Remember where the name starts. If it turns out to be a template
843 function, we'll have to insert the return type here. */
844 start_position = result_length (dm);
848 RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
849 &special_std_substitution));
850 if (special_std_substitution)
852 /* This was the magic `std::' substitution. */
853 result_append (dm, "::");
854 RETURN_IF_ERROR (demangle_encoding (dm));
857 else if (peek == 'G' || peek == 'T')
858 RETURN_IF_ERROR (demangle_special_name (dm));
861 /* Now demangle the name. */
862 RETURN_IF_ERROR (demangle_name (dm, &template_p));
864 /* If there's anything left, the name was a function name, with
865 maybe its return type, and its parameters types, following. */
866 if (!end_of_name_p (dm)
867 && peek_char (dm) != 'E')
870 /* Template functions have their return type encoded. The
871 return type should be inserted at start_position. */
873 (demangle_bare_function_type (dm, start_position));
875 /* Non-template functions don't have their return type
878 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
881 substitution_add (dm, start, template_p, NOT_TEMPLATE_PARM);
884 /* Pop off template argument lists that were built during the
885 mangling of this name, to restore the old template context. */
886 pop_to_template_arg_list (dm, old_arg_list);
891 /* Demangles and emits a <name>.
893 <name> ::= <unscoped-name>
894 ::= <unscoped-template-name> <template-args>
898 <unscoped-name> ::= <unqualified-name>
899 ::= St <unqualified-name> # ::std::
901 <unscoped-template-name>
903 ::= <substitution> */
906 demangle_name (dm, template_p)
910 int special_std_substitution;
911 int start = substitution_start (dm);
913 DEMANGLE_TRACE ("name", dm);
915 switch (peek_char (dm))
918 /* This is a <nested-name>. */
919 RETURN_IF_ERROR (demangle_nested_name (dm, template_p));
923 RETURN_IF_ERROR (demangle_local_name (dm));
927 /* The `St' substitution allows a name nested in std:: to appear
928 without being enclosed in a nested name.
929 <name> ::= St <unqualified-name> # ::std:: */
930 if (peek_char_next (dm) == 't')
932 (void) next_char (dm);
933 (void) next_char (dm);
934 result_append (dm, "std::");
935 RETURN_IF_ERROR (demangle_unqualified_name (dm));
939 RETURN_IF_ERROR (demangle_substitution (dm, template_p,
940 &special_std_substitution));
941 if (special_std_substitution)
943 /* This was the magic `std::' substitution. We can have
944 a <nested-name> or one of the unscoped names
946 result_append (dm, "::");
947 RETURN_IF_ERROR (demangle_name (dm, template_p));
953 /* This is an <unscoped-name> or <unscoped-template-name>. */
954 RETURN_IF_ERROR (demangle_unqualified_name (dm));
956 /* If the <unqualified-name> is followed by template args, this
957 is an <unscoped-template-name>. */
958 if (peek_char (dm) == 'I')
960 /* Add a substitution for the unqualified template name. */
961 substitution_add (dm, start, 0, NOT_TEMPLATE_PARM);
963 RETURN_IF_ERROR (demangle_template_args (dm));
975 /* Demangles and emits a <nested-name>.
977 <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */
980 demangle_nested_name (dm, template_p)
986 DEMANGLE_TRACE ("nested-name", dm);
988 RETURN_IF_ERROR (demangle_char (dm, 'N'));
990 peek = peek_char (dm);
991 if (peek == 'r' || peek == 'V' || peek == 'K')
993 /* Snarf up and emit CV qualifiers. */
994 dyn_string_t cv_qualifiers = dyn_string_new (24);
995 demangle_CV_qualifiers (dm, cv_qualifiers);
996 result_append_string (dm, cv_qualifiers);
997 dyn_string_delete (cv_qualifiers);
998 result_append_space (dm);
1001 RETURN_IF_ERROR (demangle_prefix (dm, template_p));
1002 /* No need to demangle the final <component>; demangle_prefix will
1004 RETURN_IF_ERROR (demangle_char (dm, 'E'));
1009 /* Demangles and emits a <prefix>.
1011 <prefix> ::= <prefix> <component>
1012 ::= <template-prefix> <template-args>
1016 <template-prefix> ::= <prefix>
1019 <component> ::= <unqualified-name>
1023 demangle_prefix (dm, template_p)
1027 int start = substitution_start (dm);
1030 /* TEMPLATE_P is updated as we decend the nesting chain. After
1031 <template-args>, it is set to non-zero; after everything else it
1034 DEMANGLE_TRACE ("prefix", dm);
1041 if (end_of_name_p (dm))
1042 return "Unexpected end of name in <compound-name>.";
1044 peek = peek_char (dm);
1046 if (isdigit ((unsigned char) peek)
1047 || (peek >= 'a' && peek <= 'z')
1048 || peek == 'C' || peek == 'D'
1051 /* We have another level of scope qualification. */
1053 result_append (dm, "::");
1058 /* The substitution determines whether this is a
1060 RETURN_IF_ERROR (demangle_substitution (dm, template_p,
1064 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1068 else if (peek == 'Z')
1069 RETURN_IF_ERROR (demangle_local_name (dm));
1070 else if (peek == 'I')
1073 return STATUS_INTERNAL_ERROR;
1074 /* The template name is a substitution candidate. */
1075 substitution_add (dm, start, 0, NOT_TEMPLATE_PARM);
1076 RETURN_IF_ERROR (demangle_template_args (dm));
1079 else if (peek == 'E')
1083 return "Unexpected character in <compound-name>.";
1085 /* Add a new substitution for the prefix thus far. */
1086 substitution_add (dm, start, *template_p, NOT_TEMPLATE_PARM);
1090 /* Demangles and emits an <unqualified-name>. If the
1091 <unqualified-name> is a function and the first element in the
1092 argument list should be taken to be its return type,
1093 ENCODE_RETURN_TYPE is non-zero.
1095 <unqualified-name> ::= <operator-name>
1097 ::= <source-name> */
1100 demangle_unqualified_name (dm)
1103 char peek = peek_char (dm);
1105 DEMANGLE_TRACE ("unqualified-name", dm);
1107 if (isdigit ((unsigned char) peek))
1108 RETURN_IF_ERROR (demangle_source_name (dm));
1109 else if (peek >= 'a' && peek <= 'z')
1112 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1114 else if (peek == 'C' || peek == 'D')
1115 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1117 return "Unexpected character in <unqualified-name>.";
1122 /* Demangles and emits <source-name>.
1124 <source-name> ::= <length number> <identifier> */
1127 demangle_source_name (dm)
1132 DEMANGLE_TRACE ("source-name", dm);
1134 /* Decode the length of the identifier. */
1135 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1137 return "Zero length in <source-name>.";
1139 /* Now the identifier itself. It's placed into last_source_name,
1140 where it can be used to build a constructor or destructor name. */
1141 RETURN_IF_ERROR (demangle_identifier (dm, length,
1142 dm->last_source_name));
1145 result_append_string (dm, dm->last_source_name);
1150 /* Demangles a number, either a <number> or a <positive-number> at the
1151 current position, consuming all consecutive digit characters. Sets
1152 *VALUE to the resulting numberand returns STATUS_OK. The number is
1153 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1154 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1156 <number> ::= [n] <positive-number>
1158 <positive-number> ::= <decimal integer> */
1161 demangle_number (dm, value, base, is_signed)
1167 dyn_string_t number = dyn_string_new (10);
1169 DEMANGLE_TRACE ("number", dm);
1171 demangle_number_literally (dm, number, base, is_signed);
1172 *value = strtol (dyn_string_buf (number), NULL, base);
1173 dyn_string_delete (number);
1178 /* Demangles a number at the current position. The digits (and minus
1179 sign, if present) that make up the number are appended to STR.
1180 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1181 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1182 accepted. Does not consume a trailing underscore or other
1183 terminating character. */
1186 demangle_number_literally (dm, str, base, is_signed)
1192 DEMANGLE_TRACE ("number*", dm);
1194 if (base != 10 && base != 36)
1195 return STATUS_INTERNAL_ERROR;
1197 /* An `n' denotes a negative number. */
1198 if (is_signed && peek_char (dm) == 'n')
1200 /* Skip past the n. */
1202 /* The normal way to write a negative number is with a minus
1204 dyn_string_append_char (str, '-');
1207 /* Loop until we hit a non-digit. */
1210 char peek = peek_char (dm);
1211 if (isdigit ((unsigned char) peek)
1212 || (base == 36 && peek >= 'A' && peek <= 'Z'))
1213 /* Accumulate digits. */
1214 dyn_string_append_char (str, next_char (dm));
1216 /* Not a digit? All done. */
1223 /* Demangles an identifier at the current position of LENGTH
1224 characters and places it in IDENTIFIER. */
1227 demangle_identifier (dm, length, identifier)
1230 dyn_string_t identifier;
1232 DEMANGLE_TRACE ("identifier", dm);
1234 dyn_string_clear (identifier);
1235 dyn_string_resize (identifier, length);
1236 while (length-- > 0)
1238 if (end_of_name_p (dm))
1239 return "Unexpected end of name in <identifier>.";
1240 dyn_string_append_char (identifier, next_char (dm));
1246 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1247 the short form is emitted; otherwise the full source form
1248 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1249 operands that the operator takes.
1300 ::= cv <type> # cast
1301 ::= vx <source-name> # vendor extended operator */
1304 demangle_operator_name (dm, short_name, num_args)
1309 struct operator_code
1311 /* The mangled code for this operator. */
1313 /* The source name of this operator. */
1315 /* The number of arguments this operator takes. */
1319 static const struct operator_code operators[] =
1330 { "da", " delete[]", 1 },
1332 { "dl", " delete" , 1 },
1340 { "lS", "<<=" , 2 },
1349 { "na", " new[]" , 1 },
1353 { "nw", " new" , 1 },
1359 { "pm", "->*" , 2 },
1364 { "rS", ">>=" , 2 },
1367 { "sz", " sizeof" , 1 }
1370 const int num_operators =
1371 sizeof (operators) / sizeof (struct operator_code);
1373 int c0 = next_char (dm);
1374 int c1 = next_char (dm);
1375 const struct operator_code* p1 = operators;
1376 const struct operator_code* p2 = operators + num_operators;
1378 DEMANGLE_TRACE ("operator-name", dm);
1380 /* Is this a vendor extended operator? */
1381 if (c0 == 'v' && c1 == 'x')
1383 result_append (dm, "operator");
1384 RETURN_IF_ERROR (demangle_source_name (dm));
1389 /* Is this a conversion operator? */
1390 if (c0 == 'c' && c1 == 'v')
1392 result_append (dm, "operator ");
1393 /* Demangle the converted-to type. */
1394 RETURN_IF_ERROR (demangle_type (dm));
1399 /* Perform a binary search for the operator code. */
1402 const struct operator_code* p = p1 + (p2 - p1) / 2;
1403 char match0 = p->code[0];
1404 char match1 = p->code[1];
1406 if (c0 == match0 && c1 == match1)
1410 result_append (dm, "operator");
1411 result_append (dm, p->name);
1412 *num_args = p->num_args;
1418 /* Couldn't find it. */
1419 return "Unknown code in <operator-name>.";
1422 if (c0 < match0 || (c0 == match0 && c1 < match1))
1429 /* Demangles and emits a <special-name>.
1431 <special-name> ::= GV <object name> # Guard variable
1432 ::= Th[n] <offset number> _ <base name> <base encoding>
1433 # non-virtual base override thunk
1434 ::= Tv[n] <offset number> _ <vcall offset number>
1436 # virtual base override thunk
1437 ::= TV <type> # virtual table
1439 ::= TI <type> # typeinfo structure
1440 ::= TS <type> # typeinfo name
1442 Also demangles the special g++ manglings,
1444 <special-name> ::= CT <type> <offset number> _ <base type>
1445 # construction vtable
1446 ::= TF <type> # typeinfo function (old ABI only)
1447 ::= TJ <type> # java Class structure */
1450 demangle_special_name (dm)
1453 dyn_string_t number;
1455 char peek = peek_char (dm);
1457 DEMANGLE_TRACE ("special-name", dm);
1461 /* A guard variable name. Consume the G. */
1463 RETURN_IF_ERROR (demangle_char (dm, 'V'));
1464 result_append (dm, "guard variable for ");
1465 RETURN_IF_ERROR (demangle_name (dm, &unused));
1467 else if (peek == 'T')
1469 /* Other C++ implementation miscellania. Consume the T. */
1472 switch (peek_char (dm))
1475 /* Virtual table. */
1477 result_append (dm, "vtable for ");
1478 RETURN_IF_ERROR (demangle_type (dm));
1482 /* VTT structure. */
1484 result_append (dm, "VTT for ");
1485 RETURN_IF_ERROR (demangle_type (dm));
1489 /* Typeinfo structure. */
1491 result_append (dm, "typeinfo for ");
1492 RETURN_IF_ERROR (demangle_type (dm));
1496 /* Typeinfo function. Used only in old ABI with new mangling. */
1498 result_append (dm, "typeinfo fn for ");
1499 RETURN_IF_ERROR (demangle_type (dm));
1503 /* Character string containing type name, used in typeinfo. */
1505 result_append (dm, "typeinfo name for ");
1506 RETURN_IF_ERROR (demangle_type (dm));
1510 /* The java Class variable corresponding to a C++ class. */
1512 result_append (dm, "java Class for ");
1513 RETURN_IF_ERROR (demangle_type (dm));
1517 /* Non-virtual thunk. */
1519 result_append (dm, "non-virtual thunk");
1520 /* Demangle and emit the offset. */
1521 number = dyn_string_new (4);
1522 demangle_number_literally (dm, number, 10, 1);
1523 /* Don't display the offset unless in verbose mode. */
1526 result_append_char (dm, ' ');
1527 result_append_string (dm, number);
1529 dyn_string_delete (number);
1530 /* Demangle the separator. */
1531 RETURN_IF_ERROR (demangle_char (dm, '_'));
1532 /* Demangle and emit the target name and function type. */
1533 result_append (dm, " to ");
1534 RETURN_IF_ERROR (demangle_encoding (dm));
1538 /* Virtual thunk. */
1540 result_append (dm, "virtual thunk ");
1541 /* Demangle and emit the offset. */
1542 number = dyn_string_new (4);
1543 demangle_number_literally (dm, number, 10, 1);
1544 /* Don't display the offset unless in verbose mode. */
1547 result_append_string (dm, number);
1548 result_append_char (dm, ' ');
1550 dyn_string_delete (number);
1551 /* Demangle the separator. */
1552 RETURN_IF_ERROR (demangle_char (dm, '_'));
1553 /* Demangle and emit the vcall offset. */
1554 number = dyn_string_new (4);
1555 demangle_number_literally (dm, number, 10, 1);
1556 /* Don't display the vcall offset unless in verbose mode. */
1559 result_append_string (dm, number);
1560 result_append_char (dm, ' ');
1562 dyn_string_delete (number);
1563 /* Demangle the separator. */
1564 RETURN_IF_ERROR (demangle_char (dm, '_'));
1565 /* Demangle and emit the target function. */
1566 result_append (dm, "to ");
1567 RETURN_IF_ERROR (demangle_encoding (dm));
1571 /* TC is a special g++ mangling for a construction vtable. */
1575 result_append (dm, "construction vtable for ");
1576 RETURN_IF_ERROR (demangle_type (dm));
1577 /* Demangle the offset. */
1578 number = dyn_string_new (4);
1579 demangle_number_literally (dm, number, 10, 1);
1580 /* Demangle the underscore separator. */
1581 RETURN_IF_ERROR (demangle_char (dm, '_'));
1582 /* Demangle the base type. */
1583 result_append (dm, "-in-");
1584 RETURN_IF_ERROR (demangle_type (dm));
1585 /* Don't display the offset unless in verbose mode. */
1588 result_append_char (dm, ' ');
1589 result_append_string (dm, number);
1591 dyn_string_delete (number);
1594 /* If flag_strict, fall through. */
1597 return "Unrecognized <special-name>.";
1601 return STATUS_ERROR;
1606 /* Demangles and emits a <ctor-dtor-name>.
1609 ::= C1 # complete object (in-charge) ctor
1610 ::= C2 # base object (not-in-charge) ctor
1611 ::= C3 # complete object (in-charge) allocating ctor
1612 ::= C4 # base object (not-in-charge) allocating ctor
1613 ::= D0 # deleting (in-charge) dtor
1614 ::= D1 # complete object (in-charge) dtor
1615 ::= D2 # base object (not-in-charge) dtor */
1618 demangle_ctor_dtor_name (dm)
1621 static const char *const ctor_flavors[] =
1625 "in-charge allocating",
1626 "not-in-charge allocating"
1628 static const char *const dtor_flavors[] =
1630 "in-charge deleting",
1636 char peek = peek_char (dm);
1638 DEMANGLE_TRACE ("ctor-dtor-name", dm);
1642 /* A constructor name. Consume the C. */
1644 if (peek_char (dm) < '1' || peek_char (dm) > '4')
1645 return "Unrecognized constructor.";
1646 result_append_string (dm, dm->last_source_name);
1647 /* Print the flavor of the constructor if in verbose mode. */
1648 flavor = next_char (dm) - '1';
1651 result_append (dm, "[");
1652 result_append (dm, ctor_flavors[flavor]);
1653 result_append_char (dm, ']');
1656 else if (peek == 'D')
1658 /* A destructor name. Consume the D. */
1660 if (peek_char (dm) < '0' || peek_char (dm) > '2')
1661 return "Unrecognized destructor.";
1662 result_append_char (dm, '~');
1663 result_append_string (dm, dm->last_source_name);
1664 /* Print the flavor of the destructor if in verbose mode. */
1665 flavor = next_char (dm) - '0';
1668 result_append (dm, " [");
1669 result_append (dm, dtor_flavors[flavor]);
1670 result_append_char (dm, ']');
1674 return STATUS_ERROR;
1679 /* Handle pointer, reference, and pointer-to-member cases for
1680 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1681 build a pointer/reference type. We snarf all these, plus the
1682 following <type>, all at once since we need to know whether we have
1683 a pointer to data or pointer to function to construct the right
1684 output syntax. C++'s pointer syntax is hairy.
1688 ::= <pointer-to-member-type>
1690 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1693 demangle_type_ptr (dm)
1699 /* Collect pointer symbols into this string. */
1700 dyn_string_t symbols = dyn_string_new (10);
1702 DEMANGLE_TRACE ("type*", dm);
1704 /* Scan forward, collecting pointers and references into symbols,
1705 until we hit something else. Then emit the type. */
1708 next = peek_char (dm);
1711 dyn_string_append_char (symbols, '*');
1714 else if (next == 'R')
1716 dyn_string_append_char (symbols, '&');
1719 else if (next == 'M')
1721 /* Pointer-to-member. */
1722 dyn_string_t class_type;
1727 /* Capture the type of which this is a pointer-to-member. */
1729 RETURN_IF_ERROR (demangle_type (dm));
1730 class_type = (dyn_string_t) result_pop (dm);
1732 /* Build the pointer-to-member notation. It comes before
1733 other pointer and reference qualifiers -- */
1734 dyn_string_prepend_cstr (symbols, "::*");
1735 dyn_string_prepend (symbols, class_type);
1736 dyn_string_delete (class_type);
1738 if (peek_char (dm) == 'F')
1741 /* Demangle the type of the pointed-to member. */
1742 status = demangle_type (dm);
1743 /* Make it pretty. */
1744 result_append_space (dm);
1745 /* Add the pointer-to-member syntax, and other pointer and
1746 reference symbols. */
1747 result_append_string (dm, symbols);
1749 dyn_string_delete (symbols);
1751 RETURN_IF_ERROR (status);
1754 else if (next == 'F')
1756 /* Ooh, tricky, a pointer-to-function. */
1757 int position = result_length (dm);
1758 result_append_char (dm, '(');
1759 result_append_string (dm, symbols);
1760 result_append_char (dm, ')');
1761 dyn_string_delete (symbols);
1763 RETURN_IF_ERROR (demangle_function_type (dm, position));
1768 /* No more pointe or reference tokens. Finish up. */
1769 status = demangle_type (dm);
1771 result_append_string (dm, symbols);
1772 dyn_string_delete (symbols);
1774 RETURN_IF_ERROR (status);
1780 /* Demangles and emits a <type>.
1782 <type> ::= <builtin-type>
1784 ::= <class-enum-type>
1786 ::= <pointer-to-member-type>
1787 ::= <template-param>
1788 ::= <CV-qualifiers> <type>
1789 ::= P <type> # pointer-to
1790 ::= R <type> # reference-to
1791 ::= C <type> # complex pair (C 2000)
1792 ::= G <type> # imaginary (C 2000)
1793 ::= U <source-name> <type> # vendor extended type qualifier
1794 ::= <substitution> */
1800 int start = substitution_start (dm);
1801 char peek = peek_char (dm);
1803 int special_std_substitution;
1804 int is_builtin_type = 0;
1805 template_arg_list_t old_arg_list = current_template_arg_list (dm);
1806 int template_parm = NOT_TEMPLATE_PARM;
1808 DEMANGLE_TRACE ("type", dm);
1810 /* A <class-enum-type> can start with a digit (a <source-name>), an
1811 N (a <nested-name>), or a Z (a <local-name>). */
1812 if (isdigit ((unsigned char) peek) || peek == 'N' || peek == 'Z')
1813 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
1814 else if (peek >= 'a' && peek <= 'z')
1816 RETURN_IF_ERROR (demangle_builtin_type (dm));
1817 is_builtin_type = 1;
1827 dyn_string_t cv_qualifiers = dyn_string_new (24);
1828 demangle_CV_qualifiers (dm, cv_qualifiers);
1830 /* If the qualifiers apply to a pointer or reference, they
1831 need to come after the whole qualified type. */
1832 if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
1834 status = demangle_type (dm);
1835 result_append_space (dm);
1836 result_append_string (dm, cv_qualifiers);
1838 /* Otherwise, the qualifiers come first. */
1841 result_append_string (dm, cv_qualifiers);
1842 result_append_space (dm);
1843 status = demangle_type (dm);
1846 dyn_string_delete (cv_qualifiers);
1847 RETURN_IF_ERROR (status);
1852 return "Non-pointer or -reference function type.";
1855 RETURN_IF_ERROR (demangle_array_type (dm));
1859 RETURN_IF_ERROR (demangle_template_param (dm, &template_parm));
1863 RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
1864 &special_std_substitution));
1865 if (special_std_substitution)
1867 /* This was the magic `std::' substitution. What follows
1868 must be a class name in that namespace. */
1869 result_append (dm, "::");
1870 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
1877 RETURN_IF_ERROR (demangle_type_ptr (dm));
1881 /* A C99 complex type. */
1882 result_append (dm, "complex ");
1884 RETURN_IF_ERROR (demangle_type (dm));
1888 /* A C99 imaginary type. */
1889 result_append (dm, "imaginary ");
1891 RETURN_IF_ERROR (demangle_type (dm));
1895 /* Vendor extended type qualifier. */
1897 RETURN_IF_ERROR (demangle_source_name (dm));
1898 result_append_char (dm, ' ');
1899 RETURN_IF_ERROR (demangle_type (dm));
1903 return "Unexpected character in <type>.";
1906 /* Unqualified builin types are not substitution candidates. */
1907 if (!is_builtin_type)
1908 /* Add a new substitution for the type. If this type was a
1909 <template-param>, pass its index since from the point of
1910 substitutions, a <template-param> token is a substitution
1911 candidate distinct from the type that is substituted for it. */
1912 substitution_add (dm, start, template_p, template_parm);
1914 /* Pop off template argument lists added during mangling of this
1916 pop_to_template_arg_list (dm, old_arg_list);
1921 /* C++ source names of builtin types, indexed by the mangled code
1922 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
1923 static const char *const builtin_type_names[26] =
1925 "signed char", /* a */
1929 "long double", /* e */
1931 "__float128", /* g */
1932 "unsigned char", /* h */
1937 "unsigned long", /* m */
1939 "unsigned __int128", /* o */
1944 "unsigned short", /* t */
1948 "long long", /* x */
1949 "unsigned long long", /* y */
1953 /* Demangles and emits a <builtin-type>.
1955 <builtin-type> ::= v # void
1960 ::= h # unsigned char
1962 ::= t # unsigned short
1964 ::= j # unsigned int
1966 ::= m # unsigned long
1967 ::= x # long long, __int64
1968 ::= y # unsigned long long, __int64
1970 ::= o # unsigned __int128
1973 ::= e # long double, __float80
1976 ::= u <source-name> # vendor extended type */
1979 demangle_builtin_type (dm)
1983 char code = peek_char (dm);
1985 DEMANGLE_TRACE ("builtin-type", dm);
1990 RETURN_IF_ERROR (demangle_source_name (dm));
1993 else if (code >= 'a' && code <= 'z')
1995 const char *type_name = builtin_type_names[code - 'a'];
1996 if (type_name == NULL)
1997 return "Unrecognized <builtin-type> code.";
1999 result_append (dm, type_name);
2004 return "Non-alphabetic <builtin-type> code.";
2007 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2008 restrict) at the current position. The qualifiers are appended to
2009 QUALIFIERS. Returns STATUS_OK. */
2012 demangle_CV_qualifiers (dm, qualifiers)
2014 dyn_string_t qualifiers;
2016 DEMANGLE_TRACE ("CV-qualifiers", dm);
2020 switch (peek_char (dm))
2023 dyn_string_append_space (qualifiers);
2024 dyn_string_append_cstr (qualifiers, "restrict");
2028 dyn_string_append_space (qualifiers);
2029 dyn_string_append_cstr (qualifiers, "volatile");
2033 dyn_string_append_space (qualifiers);
2034 dyn_string_append_cstr (qualifiers, "const");
2045 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2046 position in the result string of the start of the function
2047 identifier, at which the function's return type will be inserted.
2049 <function-type> ::= F [Y] <bare-function-type> E */
2052 demangle_function_type (dm, function_name_pos)
2054 int function_name_pos;
2056 DEMANGLE_TRACE ("function-type", dm);
2057 RETURN_IF_ERROR (demangle_char (dm, 'F'));
2058 if (peek_char (dm) == 'Y')
2060 /* Indicate this function has C linkage if in verbose mode. */
2062 result_append (dm, " [extern \"C\"] ");
2065 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2066 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2070 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2071 position in the result string at which the function return type
2072 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2073 function's return type is assumed not to be encoded.
2075 <bare-function-type> ::= <signature type>+ */
2078 demangle_bare_function_type (dm, return_type_pos)
2080 int return_type_pos;
2082 /* Sequence is the index of the current function parameter, counting
2083 from zero. The value -1 denotes the return type. */
2085 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2087 DEMANGLE_TRACE ("bare-function-type", dm);
2089 result_append_char (dm, '(');
2090 while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2093 /* We're decoding the function's return type. */
2095 dyn_string_t return_type;
2097 /* Decode the return type off to the side. */
2099 RETURN_IF_ERROR (demangle_type (dm));
2100 return_type = (dyn_string_t) result_pop (dm);
2102 /* Add a space to the end of the type. */
2103 dyn_string_append_space (return_type);
2105 /* Insert the return type where we've been asked to. */
2106 dyn_string_insert (result_string (dm), return_type_pos,
2108 dyn_string_delete (return_type);
2112 /* Skip `void' parameter types. One should only occur as
2113 the only type in a parameter list; in that case, we want
2114 to print `foo ()' instead of `foo (void)'. */
2115 if (peek_char (dm) == 'v')
2117 /* Consume the v. */
2121 /* Separate parameter types by commas. */
2123 result_append (dm, ", ");
2124 /* Demangle the type. */
2125 RETURN_IF_ERROR (demangle_type (dm));
2130 result_append_char (dm, ')');
2135 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2136 non-zero if the type is a template-id, zero otherwise.
2138 <class-enum-type> ::= <name> */
2141 demangle_class_enum_type (dm, template_p)
2145 DEMANGLE_TRACE ("class-enum-type", dm);
2147 RETURN_IF_ERROR (demangle_name (dm, template_p));
2151 /* Demangles and emits an <array-type>.
2153 <array-type> ::= A [<dimension number>] _ <element type> */
2156 demangle_array_type (dm)
2159 dyn_string_t array_size = dyn_string_new (10);
2161 RETURN_IF_ERROR (demangle_char (dm, 'A'));
2163 /* Demangle the array size into array_size. */
2164 RETURN_IF_ERROR (demangle_number_literally (dm, array_size, 10, 0));
2166 /* Demangle the base type of the array. */
2167 RETURN_IF_ERROR (demangle_char (dm, '_'));
2168 RETURN_IF_ERROR (demangle_type (dm));
2170 /* Emit the array dimension syntax. */
2171 result_append_char (dm, '[');
2172 result_append_string (dm, array_size);
2173 result_append_char (dm, ']');
2174 dyn_string_delete (array_size);
2179 /* Demangles and emits a <template-param>. The zero-indexed position
2180 in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
2182 <template-param> ::= T_ # first template parameter
2183 ::= T <parameter-2 number> _ */
2186 demangle_template_param (dm, template_parm_number)
2188 int *template_parm_number;
2191 template_arg_list_t current_arg_list = current_template_arg_list (dm);
2194 DEMANGLE_TRACE ("template-param", dm);
2196 /* Make sure there is a template argmust list in which to look up
2197 this parameter reference. */
2198 if (current_arg_list == NULL)
2199 return "Template parameter outside of template.";
2201 RETURN_IF_ERROR (demangle_char (dm, 'T'));
2202 if (peek_char (dm) == '_')
2206 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2209 RETURN_IF_ERROR (demangle_char (dm, '_'));
2211 arg = template_arg_list_get_arg (current_arg_list, parm_number);
2213 /* parm_number exceeded the number of arguments in the current
2214 template argument list. */
2215 return "Template parameter number out of bounds.";
2216 result_append_string (dm, (dyn_string_t) arg);
2218 if (peek_char (dm) == 'I')
2219 RETURN_IF_ERROR (demangle_template_args (dm));
2221 *template_parm_number = parm_number;
2225 /* Demangles and emits a <template-args>.
2227 <template-args> ::= I <template-arg>+ E */
2230 demangle_template_args (dm)
2234 template_arg_list_t arg_list = template_arg_list_new ();
2236 /* Preserve the most recently demangled source name. */
2237 dyn_string_t old_last_source_name = dm->last_source_name;
2238 dm->last_source_name = dyn_string_new (0);
2240 DEMANGLE_TRACE ("template-args", dm);
2242 RETURN_IF_ERROR (demangle_char (dm, 'I'));
2243 result_append_char (dm, '<');
2251 result_append (dm, ", ");
2253 /* Capture the template arg. */
2255 RETURN_IF_ERROR (demangle_template_arg (dm));
2256 arg = result_pop (dm);
2258 /* Emit it in the demangled name. */
2259 result_append_string (dm, (dyn_string_t) arg);
2261 /* Save it for use in expanding <template-param>s. */
2262 template_arg_list_add_arg (arg_list, arg);
2264 while (peek_char (dm) != 'E');
2265 /* Append the '>'. */
2266 result_close_template_list (dm);
2268 /* Consume the 'E'. */
2271 /* Restore the most recent demangled source name. */
2272 dyn_string_delete (dm->last_source_name);
2273 dm->last_source_name = old_last_source_name;
2275 /* Push the list onto the top of the stack of template argument
2276 lists, so that arguments from it are used from now on when
2277 expanding <template-param>s. */
2278 push_template_arg_list (dm, arg_list);
2283 /* This function, which does not correspond to a production in the
2284 mangling spec, handles the `literal' production for both
2285 <template-arg> and <expr-primary>. It does not expect or consume
2286 the initial `L' or final `E'. The demangling is given by:
2288 <literal> ::= <type> </value/ number>
2290 and the emitted output is `(type)number'. */
2293 demangle_literal (dm)
2296 dyn_string_t value = dyn_string_new (0);
2297 char peek = peek_char (dm);
2299 DEMANGLE_TRACE ("literal", dm);
2301 if (!flag_verbose && peek >= 'a' && peek <= 'z')
2303 /* If not in verbose mode and this is a builtin type, see if we
2304 can produce simpler numerical output. In particular, for
2305 integer types shorter than `long', just write the number
2306 without type information; for bools, write `true' or `false'.
2307 Other refinements could be made here too. */
2309 /* This constant string is used to map from <builtin-type> codes
2310 (26 letters of the alphabet) to codes that determine how the
2311 value will be displayed. The codes are:
2315 A space means the value will be represented using cast
2317 static const char *const code_map = "ibi iii ll ii i ";
2319 char code = code_map[peek - 'a'];
2320 /* FIXME: Implement demangling of floats and doubles. */
2322 return STATUS_UNIMPLEMENTED;
2325 /* It's a boolean. */
2328 /* Consume the b. */
2330 /* Look at the next character. It should be 0 or 1,
2331 corresponding to false or true, respectively. */
2332 value = peek_char (dm);
2334 result_append (dm, "false");
2335 else if (value == '1')
2336 result_append (dm, "true");
2338 return "Unrecognized bool constant.";
2339 /* Consume the 0 or 1. */
2343 else if (code == 'i' || code == 'l')
2345 /* It's an integer or long. */
2347 /* Consume the type character. */
2349 /* Demangle the number and write it out. */
2350 RETURN_IF_ERROR (demangle_number_literally (dm, value, 10, 1));
2351 result_append_string (dm, value);
2352 /* For long integers, append an l. */
2354 result_append_char (dm, code);
2357 /* ...else code == ' ', so fall through to represent this
2358 literal's type explicitly using cast syntax. */
2361 result_append_char (dm, '(');
2362 RETURN_IF_ERROR (demangle_type (dm));
2363 result_append_char (dm, ')');
2365 RETURN_IF_ERROR (demangle_number_literally (dm, value, 10, 1));
2366 result_append_string (dm, value);
2367 dyn_string_delete (value);
2372 /* Demangles and emits a <template-arg>.
2374 <template-arg> ::= <type> # type
2375 ::= L <type> <value number> E # literal
2376 ::= LZ <encoding> E # external name
2377 ::= X <expression> E # expression */
2380 demangle_template_arg (dm)
2383 DEMANGLE_TRACE ("template-arg", dm);
2385 switch (peek_char (dm))
2390 if (peek_char (dm) == 'Z')
2392 /* External name. */
2394 /* FIXME: Standard is contradictory here. */
2395 RETURN_IF_ERROR (demangle_encoding (dm));
2398 RETURN_IF_ERROR (demangle_literal (dm));
2399 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2405 RETURN_IF_ERROR (demangle_expression (dm));
2409 RETURN_IF_ERROR (demangle_type (dm));
2416 /* Demangles and emits an <expression>.
2418 <expression> ::= <unary operator-name> <expression>
2419 ::= <binary operator-name> <expression> <expression>
2421 ::= <scope-expression> */
2424 demangle_expression (dm)
2427 char peek = peek_char (dm);
2429 DEMANGLE_TRACE ("expression", dm);
2431 if (peek == 'L' || peek == 'T')
2432 RETURN_IF_ERROR (demangle_expr_primary (dm));
2433 else if (peek == 's' && peek_char_next (dm) == 'r')
2434 RETURN_IF_ERROR (demangle_scope_expression (dm));
2436 /* An operator expression. */
2439 dyn_string_t operator_name;
2441 /* We have an operator name. Since we want to output binary
2442 operations in infix notation, capture the operator name
2445 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
2446 operator_name = (dyn_string_t) result_pop (dm);
2448 /* If it's binary, do an operand first. */
2451 result_append_char (dm, '(');
2452 RETURN_IF_ERROR (demangle_expression (dm));
2453 result_append_char (dm, ')');
2456 /* Now emit the operator, followed by its second (if binary) or
2457 only (if unary) operand. */
2458 result_append_string (dm, operator_name);
2459 dyn_string_delete (operator_name);
2460 result_append_char (dm, '(');
2461 RETURN_IF_ERROR (demangle_expression (dm));
2462 result_append_char (dm, ')');
2464 /* The ternary operator takes a third operand. */
2467 result_append (dm, ":(");
2468 RETURN_IF_ERROR (demangle_expression (dm));
2469 result_append_char (dm, ')');
2476 /* Demangles and emits a <scope-expression>.
2478 <scope-expression> ::= sr <qualifying type> <source-name>
2479 ::= sr <qualifying type> <encoding> */
2482 demangle_scope_expression (dm)
2485 RETURN_IF_ERROR (demangle_char (dm, 's'));
2486 RETURN_IF_ERROR (demangle_char (dm, 'r'));
2487 RETURN_IF_ERROR (demangle_type (dm));
2488 result_append (dm, "::");
2489 RETURN_IF_ERROR (demangle_encoding (dm));
2493 /* Demangles and emits an <expr-primary>.
2495 <expr-primary> ::= <template-param>
2496 ::= L <type> <value number> E # literal
2497 ::= L <mangled-name> E # external name */
2500 demangle_expr_primary (dm)
2503 char peek = peek_char (dm);
2506 DEMANGLE_TRACE ("expr-primary", dm);
2509 RETURN_IF_ERROR (demangle_template_param (dm, &unused));
2510 else if (peek == 'L')
2512 /* Consume the `L'. */
2514 peek = peek_char (dm);
2517 RETURN_IF_ERROR (demangle_mangled_name (dm));
2519 RETURN_IF_ERROR (demangle_literal (dm));
2521 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2524 return STATUS_ERROR;
2529 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2530 if the substitution is the name of a template, zero otherwise. If
2531 the substitution token is St, which corresponds to the `::std::'
2532 namespace and can appear in a non-nested name, sets
2533 *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.
2535 <substitution> ::= S <seq-id> _
2539 ::= Sa # ::std::allocator
2540 ::= Sb # ::std::basic_string
2541 ::= Ss # ::std::basic_string<char,
2542 ::std::char_traits<char>,
2543 ::std::allocator<char> >
2544 ::= Si # ::std::basic_istream<char,
2545 std::char_traits<char> >
2546 ::= So # ::std::basic_ostream<char,
2547 std::char_traits<char> >
2548 ::= Sd # ::std::basic_iostream<char,
2549 std::char_traits<char> >
2553 demangle_substitution (dm, template_p, special_std_substitution)
2556 int *special_std_substitution;
2562 DEMANGLE_TRACE ("substitution", dm);
2564 RETURN_IF_ERROR (demangle_char (dm, 'S'));
2565 *special_std_substitution = 0;
2567 /* Scan the substitution sequence index. A missing number denotes
2569 peek = peek_char (dm);
2572 /* If the following character is 0-9 or a capital letter, interpret
2573 the sequence up to the next underscore as a base-36 substitution
2575 else if (isdigit ((unsigned char) peek)
2576 || (peek >= 'A' && peek <= 'Z'))
2577 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
2583 result_append (dm, "std");
2584 *special_std_substitution = 1;
2588 result_append (dm, "std::allocator");
2589 dyn_string_copy_cstr (dm->last_source_name, "allocator");
2593 result_append (dm, "std::basic_string");
2594 dyn_string_copy_cstr (dm->last_source_name, "basic_string");
2600 result_append (dm, "std::string");
2601 dyn_string_copy_cstr (dm->last_source_name, "string");
2605 result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >");
2606 dyn_string_copy_cstr (dm->last_source_name, "basic_string");
2613 result_append (dm, "std::istream");
2614 dyn_string_copy_cstr (dm->last_source_name, "istream");
2618 result_append (dm, "std::basic_istream<char, std::char_traints<char> >");
2619 dyn_string_copy_cstr (dm->last_source_name, "basic_istream");
2626 result_append (dm, "std::ostream");
2627 dyn_string_copy_cstr (dm->last_source_name, "ostream");
2631 result_append (dm, "std::basic_ostream<char, std::char_traits<char> >");
2632 dyn_string_copy_cstr (dm->last_source_name, "basic_ostream");
2639 result_append (dm, "std::iostream");
2640 dyn_string_copy_cstr (dm->last_source_name, "iostream");
2644 result_append (dm, "std::basic_iostream<char, std::char_traits<char> >");
2645 dyn_string_copy_cstr (dm->last_source_name, "basic_iostream");
2650 return "Unrecognized <substitution>.";
2657 /* Look up the substitution text. Since `S_' is the most recent
2658 substitution, `S0_' is the second-most-recent, etc., shift the
2659 numbering by one. */
2660 text = substitution_get (dm, seq_id + 1, template_p);
2662 return "Substitution number out of range.";
2664 /* Emit the substitution text. */
2665 result_append_string (dm, text);
2667 RETURN_IF_ERROR (demangle_char (dm, '_'));
2671 /* Demangles and emits a <local-name>.
2673 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2674 := Z <function encoding> E s [<discriminator>] */
2677 demangle_local_name (dm)
2680 DEMANGLE_TRACE ("local-name", dm);
2682 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
2683 RETURN_IF_ERROR (demangle_encoding (dm));
2684 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2685 result_append (dm, "'s ");
2687 if (peek_char (dm) == 's')
2689 /* Local character string literal. */
2690 result_append (dm, "string literal");
2691 /* Consume the s. */
2693 RETURN_IF_ERROR (demangle_discriminator (dm, 0));
2698 result_append (dm, "local ");
2699 /* Local name for some other entity. Demangle its name. */
2700 RETURN_IF_ERROR (demangle_name (dm, &unused));
2701 RETURN_IF_ERROR (demangle_discriminator (dm, 1));
2707 /* Optimonally demangles and emits a <discriminator>. If there is no
2708 <discriminator> at the current position in the mangled string, the
2709 descriminator is assumed to be zero. Emit the discriminator number
2710 in parentheses, unless SUPPRESS_FIRST is non-zero and the
2711 discriminator is zero.
2713 <discriminator> ::= _ <number> */
2716 demangle_discriminator (dm, suppress_first)
2720 /* Output for <discriminator>s to the demangled name is completely
2721 supressed if not in verbose mode. */
2723 if (peek_char (dm) == '_')
2725 /* Consume the underscore. */
2728 result_append (dm, " [#");
2729 /* Check if there's a number following the underscore. */
2730 if (isdigit ((unsigned char) peek_char (dm)))
2733 /* Demangle the number. */
2734 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
2736 /* Write the discriminator. The mangled number is two
2737 less than the discriminator ordinal, counting from
2739 int_to_dyn_string (discriminator + 2,
2740 (dyn_string_t) dm->result);
2745 /* A missing digit correspond to one. */
2746 result_append_char (dm, '1');
2749 result_append_char (dm, ']');
2751 else if (!suppress_first)
2754 result_append (dm, " [#0]");
2760 /* Demangle NAME into RESULT, which must be an initialized
2761 dyn_string_t. On success, returns STATUS_OK. On failure, returns
2762 an error message, and the contents of RESULT are unchanged. */
2765 cp_demangle (name, result)
2767 dyn_string_t result;
2770 int length = strlen (name);
2772 if (length > 2 && name[0] == '_' && name[1] == 'Z')
2774 demangling_t dm = demangling_new (name);
2777 status = demangle_mangled_name (dm);
2779 if (status == STATUS_OK)
2781 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
2782 dyn_string_copy (result, demangled);
2783 dyn_string_delete (demangled);
2786 demangling_delete (dm);
2790 /* It's evidently not a mangled C++ name. It could be the name
2791 of something with C linkage, though, so just copy NAME into
2793 dyn_string_copy_cstr (result, name);
2800 /* Variant entry point for integration with the existing cplus-dem
2801 demangler. Attempts to demangle MANGLED. If the demangling
2802 succeeds, returns a buffer, allocated with malloc, containing the
2803 demangled name. The caller must deallocate the buffer using free.
2804 If the demangling failes, returns NULL. */
2807 cplus_demangle_new_abi (mangled)
2808 const char* mangled;
2810 /* Create a dyn_string to hold the demangled name. */
2811 dyn_string_t demangled = dyn_string_new (0);
2812 /* Attempt the demangling. */
2813 status_t status = cp_demangle ((char *) mangled, demangled);
2814 if (status == STATUS_OK)
2815 /* Demangling succeeded. */
2817 /* Grab the demangled result from the dyn_string. It was
2818 allocated with malloc, so we can return it directly. */
2819 char *return_value = dyn_string_release (demangled);
2820 /* The dyn_string can go away. */
2821 dyn_string_delete (demangled);
2822 /* Hand back the demangled name. */
2823 return return_value;
2826 /* Demangling failed. */
2828 dyn_string_delete (demangled);
2833 #ifdef STANDALONE_DEMANGLER
2837 static void print_usage
2838 PARAMS ((FILE* fp, int exit_value));
2840 /* Non-zero if CHAR is a character than can occur in a mangled name. */
2841 #define is_mangled_char(CHAR) \
2842 (isalnum ((unsigned char) (CHAR)) || (CHAR) == '_')
2844 /* The name of this program, as invoked. */
2845 const char* program_name;
2847 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
2850 print_usage (fp, exit_value)
2854 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
2855 fprintf (fp, "Options:\n", program_name);
2856 fprintf (fp, " -h,--help Display this message.\n");
2857 fprintf (fp, " -s,--strict Demangle standard names only.\n");
2858 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
2859 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
2864 /* Option specification for getopt_long. */
2865 static struct option long_options[] =
2867 { "help", no_argument, NULL, 'h' },
2868 { "strict", no_argument, NULL, 's' },
2869 { "verbose", no_argument, NULL, 'v' },
2870 { NULL, no_argument, NULL, 0 },
2873 /* Main entry for a demangling filter executable. It will demangle
2874 its command line arguments, if any. If none are provided, it will
2875 filter stdin to stdout, replacing any recognized mangled C++ names
2876 with their demangled equivalents. */
2887 /* Use the program name of this program, as invoked. */
2888 program_name = argv[0];
2890 /* Parse options. */
2893 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
2896 case '?': /* Unrecognized option. */
2897 print_usage (stderr, 1);
2901 print_usage (stdout, 0);
2913 while (opt_char != -1);
2916 /* No command line arguments were provided. Filter stdin. */
2918 dyn_string_t mangled = dyn_string_new (3);
2919 dyn_string_t demangled = dyn_string_new (0);
2922 /* Read all of input. */
2923 while (!feof (stdin))
2925 char c = getchar ();
2927 /* The first character of a mangled name is an underscore. */
2932 /* It's not a mangled name. Print the character and go
2939 /* The second character of a mangled name is a capital `Z'. */
2944 /* It's not a mangled name. Print the previous
2945 underscore, the `Z', and go on. */
2951 /* Start keeping track of the candidate mangled name. */
2952 dyn_string_append_char (mangled, '_');
2953 dyn_string_append_char (mangled, 'Z');
2955 /* Pile characters into mangled until we hit one that can't
2956 occur in a mangled name. */
2958 while (!feof (stdin) && is_mangled_char (c))
2960 dyn_string_append_char (mangled, c);
2966 /* Attempt to demangle the name. */
2967 status = cp_demangle (dyn_string_buf (mangled), demangled);
2969 /* If the demangling succeeded, great! Print out the
2970 demangled version. */
2971 if (status == STATUS_OK)
2972 fputs (dyn_string_buf (demangled), stdout);
2973 /* Otherwise, it might not have been a mangled name. Just
2974 print out the original text. */
2976 fputs (dyn_string_buf (mangled), stdout);
2978 /* If we haven't hit EOF yet, we've read one character that
2979 can't occur in a mangled name, so print it out. */
2983 /* Clear the candidate mangled name, to start afresh next
2984 time we hit a `_Z'. */
2985 dyn_string_clear (mangled);
2988 dyn_string_delete (mangled);
2989 dyn_string_delete (demangled);
2992 /* Demangle command line arguments. */
2994 dyn_string_t result = dyn_string_new (0);
2996 /* Loop over command line arguments. */
2997 for (i = optind; i < argc; ++i)
2999 /* Attempt to demangle. */
3000 status = cp_demangle (argv[i], result);
3002 /* If it worked, print the demangled name. */
3003 if (status == STATUS_OK)
3004 printf ("%s\n", dyn_string_buf (result));
3005 /* If not, print the error message to stderr instead. */
3007 fprintf (stderr, "%s\n", status);
3009 dyn_string_delete (result);
3015 #endif /* STANDALONE_DEMANGLER */