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
41 #include "libiberty.h"
42 #include "dyn-string.h"
45 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
46 and other debugging output, will be generated. */
47 #ifdef CP_DEMANGLE_DEBUG
48 #define DEMANGLE_TRACE(PRODUCTION, DM) \
49 fprintf (stderr, " -> %-24s at position %3d\n", \
50 (PRODUCTION), current_position (DM));
52 #define DEMANGLE_TRACE(PRODUCTION, DM)
55 /* Don't include <ctype.h>, to prevent additional unresolved symbols
56 from being dragged into the C++ runtime library. */
57 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
58 #define IS_ALPHA(CHAR) \
59 (((CHAR) >= 'a' && (CHAR) <= 'z') \
60 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
62 /* If flag_verbose is zero, some simplifications will be made to the
63 output to make it easier to read and supress details that are
64 generally not of interest to the average C++ programmer.
65 Otherwise, the demangled representation will attempt to convey as
66 much information as the mangled form. */
67 static int flag_verbose;
69 /* If flag_strict is non-zero, demangle strictly according to the
70 specification -- don't demangle special g++ manglings. */
71 static int flag_strict;
73 /* String_list_t is an extended form of dyn_string_t which provides a link
74 field. A string_list_t may safely be cast to and used as a
77 struct string_list_def
79 struct dyn_string string;
80 struct string_list_def *next;
83 typedef struct string_list_def *string_list_t;
85 /* Data structure representing a potential substitution. */
87 struct substitution_def
89 /* The demangled text of the substitution. */
92 /* The template parameter that this represents, indexed from zero.
93 If this is not a template paramter number, the value is
95 int template_parm_number;
97 /* Whether this substitution represents a template item. */
101 #define NOT_TEMPLATE_PARM (-1)
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_close_template_list
198 PARAMS ((demangling_t));
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, 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 /* The length of the current demangled result. */
289 #define result_length(DM) \
290 dyn_string_length (&(DM)->result->string)
292 /* Appends a space to the demangled result if the last character is
294 #define result_append_space(DM) \
295 (dyn_string_append_space (&(DM)->result->string) \
296 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
298 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
299 success. On failure, deletes DS and returns an error code. */
302 int_to_dyn_string (value, ds)
309 /* Handle zero up front. */
312 if (!dyn_string_append_char (ds, '0'))
313 return STATUS_ALLOCATION_FAILED;
317 /* For negative numbers, emit a minus sign. */
320 if (!dyn_string_append_char (ds, '-'))
321 return STATUS_ALLOCATION_FAILED;
325 /* Find the power of 10 of the first digit. */
333 /* Write the digits. */
336 int digit = value / mask;
338 if (!dyn_string_append_char (ds, '0' + digit))
339 return STATUS_ALLOCATION_FAILED;
341 value -= digit * mask;
348 /* Creates a new string list node. The contents of the string are
349 empty, but the initial buffer allocation is LENGTH. The string
350 list node should be deleted with string_list_delete. Returns NULL
351 if allocation fails. */
354 string_list_new (length)
357 string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
360 if (!dyn_string_init ((dyn_string_t) s, length))
365 /* Deletes the entire string list starting at NODE. */
368 string_list_delete (node)
373 string_list_t next = node->next;
379 /* Appends a greater-than character to the demangled result. If the
380 last character is a greater-than character, a space is inserted
381 first, so that the two greater-than characters don't look like a
382 right shift token. */
385 result_close_template_list (dm)
388 dyn_string_t s = &dm->result->string;
390 /* Add a space if the last character is already a closing angle
391 bracket, so that a nested template arg list doesn't look like
392 it's closed with a right-shift operator. */
393 if (dyn_string_last_char (s) == '>')
395 if (!dyn_string_append_char (s, ' '))
396 return STATUS_ALLOCATION_FAILED;
399 /* Add closing angle brackets. */
400 if (!dyn_string_append_char (s, '>'))
401 return STATUS_ALLOCATION_FAILED;
406 /* Allocates and pushes a new string onto the demangled results stack
407 for DM. Subsequent demangling with DM will emit to the new string.
408 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
409 allocation failure. */
415 string_list_t new_string = string_list_new (0);
416 if (new_string == NULL)
417 /* Allocation failed. */
418 return STATUS_ALLOCATION_FAILED;
420 /* Link the new string to the front of the list of result strings. */
421 new_string->next = (string_list_t) dm->result;
422 dm->result = new_string;
426 /* Removes and returns the topmost element on the demangled results
427 stack for DM. The caller assumes ownership for the returned
434 string_list_t top = dm->result;
435 dm->result = top->next;
439 /* Returns the start position of a fragment of the demangled result
440 that will be a substitution candidate. Should be called at the
441 start of productions that can add substitutions. */
444 substitution_start (dm)
447 return result_length (dm);
450 /* Adds the suffix of the current demangled result of DM starting at
451 START_POSITION as a potential substitution. If TEMPLATE_P is
452 non-zero, this potential substitution is a template-id.
454 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
455 is for that particular <template-param>, and is distinct from other
456 otherwise-identical types and other <template-param>s with
457 different indices. */
460 substitution_add (dm, start_position, template_p, template_parm_number)
464 int template_parm_number;
466 dyn_string_t result = result_string (dm);
467 dyn_string_t substitution = dyn_string_new (0);
470 if (substitution == NULL)
471 return STATUS_ALLOCATION_FAILED;
473 /* Extract the substring of the current demangling result that
474 represents the subsitution candidate. */
475 if (!dyn_string_substring (substitution,
476 result, start_position, result_length (dm)))
478 dyn_string_delete (substitution);
479 return STATUS_ALLOCATION_FAILED;
482 /* Check whether SUBSTITUTION already occurs. */
483 for (i = 0; i < dm->num_substitutions; ++i)
484 if (dyn_string_eq (dm->substitutions[i].text, substitution)
485 && dm->substitutions[i].template_parm_number == template_parm_number)
486 /* Found SUBSTITUTION already present. */
488 /* Callers expect this function to take ownership of
489 SUBSTITUTION, so delete it. */
490 dyn_string_delete (substitution);
494 /* If there's no room for the new entry, grow the array. */
495 if (dm->substitutions_allocated == dm->num_substitutions)
497 size_t new_array_size;
498 dm->substitutions_allocated *= 2;
500 sizeof (struct substitution_def) * dm->substitutions_allocated;
502 dm->substitutions = (struct substitution_def *)
503 realloc (dm->substitutions, new_array_size);
504 if (dm->substitutions == NULL)
505 /* Realloc failed. */
507 dyn_string_delete (substitution);
508 return STATUS_ALLOCATION_FAILED;
512 /* Add the substitution to the array. */
513 dm->substitutions[i].text = substitution;
514 dm->substitutions[i].template_p = template_p;
515 dm->substitutions[i].template_parm_number = template_parm_number;
516 ++dm->num_substitutions;
518 #ifdef CP_DEMANGLE_DEBUG
519 substitutions_print (dm, stderr);
525 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
526 non-zero if the substitution is a template-id, zero otherwise.
527 N is numbered from zero. DM retains ownership of the returned
528 string. If N is negative, or equal to or greater than the current
529 number of substitution candidates, returns NULL. */
532 substitution_get (dm, n, template_p)
537 struct substitution_def *sub;
539 /* Make sure N is in the valid range. */
540 if (n < 0 || n >= dm->num_substitutions)
543 sub = &(dm->substitutions[n]);
544 *template_p = sub->template_p;
548 #ifdef CP_DEMANGLE_DEBUG
549 /* Debugging routine to print the current substitutions to FP. */
552 substitutions_print (dm, fp)
557 int num = dm->num_substitutions;
559 fprintf (fp, "SUBSTITUTIONS:\n");
560 for (seq_id = -1; seq_id < num - 1; ++seq_id)
563 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
566 fprintf (fp, " S_ ");
568 fprintf (fp, " S%d_", seq_id);
569 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
573 #endif /* CP_DEMANGLE_DEBUG */
575 /* Creates a new template argument list. Returns NULL if allocation
578 static template_arg_list_t
579 template_arg_list_new ()
581 template_arg_list_t new_list =
582 (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
583 if (new_list == NULL)
585 /* Initialize the new list to have no arguments. */
586 new_list->first_argument = NULL;
587 new_list->last_argument = NULL;
588 /* Return the new list. */
592 /* Deletes a template argument list and the template arguments it
596 template_arg_list_delete (list)
597 template_arg_list_t list;
599 /* If there are any arguments on LIST, delete them. */
600 if (list->first_argument != NULL)
601 string_list_delete (list->first_argument);
606 /* Adds ARG to the template argument list ARG_LIST. */
609 template_arg_list_add_arg (arg_list, arg)
610 template_arg_list_t arg_list;
613 if (arg_list->first_argument == NULL)
614 /* If there were no arguments before, ARG is the first one. */
615 arg_list->first_argument = arg;
617 /* Make ARG the last argument on the list. */
618 arg_list->last_argument->next = arg;
619 /* Make ARG the last on the list. */
620 arg_list->last_argument = arg;
624 /* Returns the template arugment at position INDEX in template
625 argument list ARG_LIST. */
628 template_arg_list_get_arg (arg_list, index)
629 template_arg_list_t arg_list;
632 string_list_t arg = arg_list->first_argument;
633 /* Scan down the list of arguments to find the one at position
639 /* Ran out of arguments before INDEX hit zero. That's an
643 /* Return the argument at position INDEX. */
647 /* Pushes ARG_LIST onto the top of the template argument list stack. */
650 push_template_arg_list (dm, arg_list)
652 template_arg_list_t arg_list;
654 arg_list->next = dm->template_arg_lists;
655 dm->template_arg_lists = arg_list;
656 #ifdef CP_DEMANGLE_DEBUG
657 fprintf (stderr, " ** pushing template arg list\n");
658 template_arg_list_print (arg_list, stderr);
662 /* Pops and deletes elements on the template argument list stack until
663 arg_list is the topmost element. If arg_list is NULL, all elements
664 are popped and deleted. */
667 pop_to_template_arg_list (dm, arg_list)
669 template_arg_list_t arg_list;
671 while (dm->template_arg_lists != arg_list)
673 template_arg_list_t top = dm->template_arg_lists;
674 /* Disconnect the topmost element from the list. */
675 dm->template_arg_lists = top->next;
676 /* Delete the popped element. */
677 template_arg_list_delete (top);
678 #ifdef CP_DEMANGLE_DEBUG
679 fprintf (stderr, " ** removing template arg list\n");
684 #ifdef CP_DEMANGLE_DEBUG
686 /* Prints the contents of ARG_LIST to FP. */
689 template_arg_list_print (arg_list, fp)
690 template_arg_list_t arg_list;
696 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
697 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
700 fprintf (fp, " T_ : ");
702 fprintf (fp, " T%d_ : ", index);
704 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
708 #endif /* CP_DEMANGLE_DEBUG */
710 /* Returns the topmost element on the stack of template argument
711 lists. If there is no list of template arguments, returns NULL. */
713 static template_arg_list_t
714 current_template_arg_list (dm)
717 return dm->template_arg_lists;
720 /* Allocates a demangling_t object for demangling mangled NAME. A new
721 result must be pushed before the returned object can be used.
722 Returns NULL if allocation fails. */
725 demangling_new (name)
729 dm = (demangling_t) malloc (sizeof (struct demangling_def));
736 dm->num_substitutions = 0;
737 dm->substitutions_allocated = 10;
738 dm->template_arg_lists = NULL;
739 dm->last_source_name = dyn_string_new (0);
740 if (dm->last_source_name == NULL)
742 dm->substitutions = (struct substitution_def *)
743 malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
744 if (dm->substitutions == NULL)
746 dyn_string_delete (dm->last_source_name);
753 /* Deallocates a demangling_t object and all memory associated with
757 demangling_delete (dm)
761 template_arg_list_t arg_list = dm->template_arg_lists;
763 /* Delete the stack of template argument lists. */
764 while (arg_list != NULL)
766 template_arg_list_t next = arg_list->next;
767 template_arg_list_delete (arg_list);
770 /* Delete the list of substitutions. */
771 for (i = dm->num_substitutions; --i >= 0; )
772 dyn_string_delete (dm->substitutions[i].text);
773 free (dm->substitutions);
774 /* Delete the demangled result. */
775 string_list_delete (dm->result);
776 /* Delete the stored identifier name. */
777 dyn_string_delete (dm->last_source_name);
778 /* Delete the context object itself. */
782 /* These functions demangle an alternative of the corresponding
783 production in the mangling spec. The first argument of each is a
784 demangling context structure for the current demangling
785 operation. Most emit demangled text directly to the topmost result
786 string on the result string stack in the demangling context
789 static status_t demangle_char
790 PARAMS ((demangling_t, int));
791 static status_t demangle_mangled_name
792 PARAMS ((demangling_t));
793 static status_t demangle_encoding
794 PARAMS ((demangling_t));
795 static status_t demangle_name
796 PARAMS ((demangling_t, int *));
797 static status_t demangle_nested_name
798 PARAMS ((demangling_t, int *));
799 static status_t demangle_prefix
800 PARAMS ((demangling_t, int *));
801 static status_t demangle_unqualified_name
802 PARAMS ((demangling_t));
803 static status_t demangle_source_name
804 PARAMS ((demangling_t));
805 static status_t demangle_number
806 PARAMS ((demangling_t, int *, int, int));
807 static status_t demangle_number_literally
808 PARAMS ((demangling_t, dyn_string_t, int, int));
809 static status_t demangle_identifier
810 PARAMS ((demangling_t, int, dyn_string_t));
811 static status_t demangle_operator_name
812 PARAMS ((demangling_t, int, int *));
813 static status_t demangle_special_name
814 PARAMS ((demangling_t));
815 static status_t demangle_ctor_dtor_name
816 PARAMS ((demangling_t));
817 static status_t demangle_type_ptr
818 PARAMS ((demangling_t));
819 static status_t demangle_type
820 PARAMS ((demangling_t));
821 static status_t demangle_CV_qualifiers
822 PARAMS ((demangling_t, dyn_string_t));
823 static status_t demangle_builtin_type
824 PARAMS ((demangling_t));
825 static status_t demangle_function_type
826 PARAMS ((demangling_t, int));
827 static status_t demangle_bare_function_type
828 PARAMS ((demangling_t, int));
829 static status_t demangle_class_enum_type
830 PARAMS ((demangling_t, int *));
831 static status_t demangle_array_type
832 PARAMS ((demangling_t));
833 static status_t demangle_template_param
834 PARAMS ((demangling_t, int *));
835 static status_t demangle_template_args
836 PARAMS ((demangling_t));
837 static status_t demangle_literal
838 PARAMS ((demangling_t));
839 static status_t demangle_template_arg
840 PARAMS ((demangling_t));
841 static status_t demangle_expression
842 PARAMS ((demangling_t));
843 static status_t demangle_scope_expression
844 PARAMS ((demangling_t));
845 static status_t demangle_expr_primary
846 PARAMS ((demangling_t));
847 static status_t demangle_substitution
848 PARAMS ((demangling_t, int *, int *));
849 static status_t demangle_local_name
850 PARAMS ((demangling_t));
851 static status_t demangle_discriminator
852 PARAMS ((demangling_t, int));
853 static status_t cp_demangle
854 PARAMS ((const char *, dyn_string_t));
855 static status_t cp_demangle_type
856 PARAMS ((const char*, dyn_string_t));
858 /* When passed to demangle_bare_function_type, indicates that the
859 function's return type is not encoded before its parameter types. */
860 #define BFT_NO_RETURN_TYPE -1
862 /* Check that the next character is C. If so, consume it. If not,
866 demangle_char (dm, c)
870 static char *error_message = NULL;
872 if (peek_char (dm) == c)
879 if (error_message == NULL)
880 error_message = strdup ("Expected ?");
881 error_message[9] = c;
882 return error_message;
886 /* Demangles and emits a <mangled-name>.
888 <mangled-name> ::= _Z <encoding> */
891 demangle_mangled_name (dm)
894 DEMANGLE_TRACE ("mangled-name", dm);
895 RETURN_IF_ERROR (demangle_char (dm, '_'));
896 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
897 RETURN_IF_ERROR (demangle_encoding (dm));
901 /* Demangles and emits an <encoding>.
903 <encoding> ::= <function name> <bare-function-type>
905 ::= <substitution> */
908 demangle_encoding (dm)
912 int special_std_substitution;
914 int start = substitution_start (dm);
915 template_arg_list_t old_arg_list = current_template_arg_list (dm);
916 char peek = peek_char (dm);
918 DEMANGLE_TRACE ("encoding", dm);
920 /* Remember where the name starts. If it turns out to be a template
921 function, we'll have to insert the return type here. */
922 start_position = result_length (dm);
926 RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
927 &special_std_substitution));
928 if (special_std_substitution)
930 /* This was the magic `std::' substitution. */
931 RETURN_IF_ERROR (result_append (dm, "::"));
932 RETURN_IF_ERROR (demangle_encoding (dm));
935 else if (peek == 'G' || peek == 'T')
936 RETURN_IF_ERROR (demangle_special_name (dm));
939 /* Now demangle the name. */
940 RETURN_IF_ERROR (demangle_name (dm, &template_p));
942 /* If there's anything left, the name was a function name, with
943 maybe its return type, and its parameters types, following. */
944 if (!end_of_name_p (dm)
945 && peek_char (dm) != 'E')
948 /* Template functions have their return type encoded. The
949 return type should be inserted at start_position. */
951 (demangle_bare_function_type (dm, start_position));
953 /* Non-template functions don't have their return type
956 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
959 RETURN_IF_ERROR (substitution_add (dm, start, template_p,
963 /* Pop off template argument lists that were built during the
964 mangling of this name, to restore the old template context. */
965 pop_to_template_arg_list (dm, old_arg_list);
970 /* Demangles and emits a <name>.
972 <name> ::= <unscoped-name>
973 ::= <unscoped-template-name> <template-args>
977 <unscoped-name> ::= <unqualified-name>
978 ::= St <unqualified-name> # ::std::
980 <unscoped-template-name>
982 ::= <substitution> */
985 demangle_name (dm, template_p)
989 int special_std_substitution;
990 int start = substitution_start (dm);
992 DEMANGLE_TRACE ("name", dm);
994 switch (peek_char (dm))
997 /* This is a <nested-name>. */
998 RETURN_IF_ERROR (demangle_nested_name (dm, template_p));
1002 RETURN_IF_ERROR (demangle_local_name (dm));
1006 /* The `St' substitution allows a name nested in std:: to appear
1007 without being enclosed in a nested name.
1008 <name> ::= St <unqualified-name> # ::std:: */
1009 if (peek_char_next (dm) == 't')
1011 (void) next_char (dm);
1012 (void) next_char (dm);
1013 RETURN_IF_ERROR (result_append (dm, "std::"));
1014 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1018 RETURN_IF_ERROR (demangle_substitution (dm, template_p,
1019 &special_std_substitution));
1020 if (special_std_substitution)
1022 /* This was the magic `std::' substitution. We can have
1023 a <nested-name> or one of the unscoped names
1025 RETURN_IF_ERROR (result_append (dm, "::"));
1026 RETURN_IF_ERROR (demangle_name (dm, template_p));
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,
1041 NOT_TEMPLATE_PARM));
1043 RETURN_IF_ERROR (demangle_template_args (dm));
1055 /* Demangles and emits a <nested-name>.
1057 <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */
1060 demangle_nested_name (dm, template_p)
1066 DEMANGLE_TRACE ("nested-name", dm);
1068 RETURN_IF_ERROR (demangle_char (dm, 'N'));
1070 peek = peek_char (dm);
1071 if (peek == 'r' || peek == 'V' || peek == 'K')
1075 /* Snarf up and emit CV qualifiers. */
1076 dyn_string_t cv_qualifiers = dyn_string_new (24);
1077 if (cv_qualifiers == NULL)
1078 return STATUS_ALLOCATION_FAILED;
1080 demangle_CV_qualifiers (dm, cv_qualifiers);
1081 status = result_append_string (dm, cv_qualifiers);
1082 dyn_string_delete (cv_qualifiers);
1083 RETURN_IF_ERROR (status);
1084 RETURN_IF_ERROR (result_append_space (dm));
1087 RETURN_IF_ERROR (demangle_prefix (dm, template_p));
1088 /* No need to demangle the final <component>; demangle_prefix will
1090 RETURN_IF_ERROR (demangle_char (dm, 'E'));
1095 /* Demangles and emits a <prefix>.
1097 <prefix> ::= <prefix> <component>
1098 ::= <template-prefix> <template-args>
1102 <template-prefix> ::= <prefix>
1105 <component> ::= <unqualified-name>
1109 demangle_prefix (dm, template_p)
1113 int start = substitution_start (dm);
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);
1127 if (end_of_name_p (dm))
1128 return "Unexpected end of name in <compound-name>.";
1130 peek = peek_char (dm);
1132 if (IS_DIGIT ((unsigned char) peek)
1133 || (peek >= 'a' && peek <= 'z')
1134 || peek == 'C' || peek == 'D'
1137 /* We have another level of scope qualification. */
1139 RETURN_IF_ERROR (result_append (dm, "::"));
1144 /* The substitution determines whether this is a
1146 RETURN_IF_ERROR (demangle_substitution (dm, template_p,
1150 RETURN_IF_ERROR (demangle_unqualified_name (dm));
1154 else if (peek == 'Z')
1155 RETURN_IF_ERROR (demangle_local_name (dm));
1156 else if (peek == 'I')
1159 return STATUS_INTERNAL_ERROR;
1160 /* The template name is a substitution candidate. */
1161 RETURN_IF_ERROR (substitution_add (dm, start, 0, NOT_TEMPLATE_PARM));
1162 RETURN_IF_ERROR (demangle_template_args (dm));
1165 else if (peek == 'E')
1169 return "Unexpected character in <compound-name>.";
1171 /* Add a new substitution for the prefix thus far. */
1172 RETURN_IF_ERROR (substitution_add (dm, start, *template_p,
1173 NOT_TEMPLATE_PARM));
1177 /* Demangles and emits an <unqualified-name>. If the
1178 <unqualified-name> is a function and the first element in the
1179 argument list should be taken to be its return type,
1180 ENCODE_RETURN_TYPE is non-zero.
1182 <unqualified-name> ::= <operator-name>
1184 ::= <source-name> */
1187 demangle_unqualified_name (dm)
1190 char peek = peek_char (dm);
1192 DEMANGLE_TRACE ("unqualified-name", dm);
1194 if (IS_DIGIT ((unsigned char) peek))
1195 RETURN_IF_ERROR (demangle_source_name (dm));
1196 else if (peek >= 'a' && peek <= 'z')
1199 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1201 else if (peek == 'C' || peek == 'D')
1202 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1204 return "Unexpected character in <unqualified-name>.";
1209 /* Demangles and emits <source-name>.
1211 <source-name> ::= <length number> <identifier> */
1214 demangle_source_name (dm)
1219 DEMANGLE_TRACE ("source-name", dm);
1221 /* Decode the length of the identifier. */
1222 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1224 return "Zero length in <source-name>.";
1226 /* Now the identifier itself. It's placed into last_source_name,
1227 where it can be used to build a constructor or destructor name. */
1228 RETURN_IF_ERROR (demangle_identifier (dm, length,
1229 dm->last_source_name));
1232 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1237 /* Demangles a number, either a <number> or a <positive-number> at the
1238 current position, consuming all consecutive digit characters. Sets
1239 *VALUE to the resulting numberand returns STATUS_OK. The number is
1240 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1241 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1243 <number> ::= [n] <positive-number>
1245 <positive-number> ::= <decimal integer> */
1248 demangle_number (dm, value, base, is_signed)
1254 dyn_string_t number = dyn_string_new (10);
1256 DEMANGLE_TRACE ("number", dm);
1259 return STATUS_ALLOCATION_FAILED;
1261 demangle_number_literally (dm, number, base, is_signed);
1262 *value = strtol (dyn_string_buf (number), NULL, base);
1263 dyn_string_delete (number);
1268 /* Demangles a number at the current position. The digits (and minus
1269 sign, if present) that make up the number are appended to STR.
1270 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1271 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1272 accepted. Does not consume a trailing underscore or other
1273 terminating character. */
1276 demangle_number_literally (dm, str, base, is_signed)
1282 DEMANGLE_TRACE ("number*", dm);
1284 if (base != 10 && base != 36)
1285 return STATUS_INTERNAL_ERROR;
1287 /* An `n' denotes a negative number. */
1288 if (is_signed && peek_char (dm) == 'n')
1290 /* Skip past the n. */
1292 /* The normal way to write a negative number is with a minus
1294 if (!dyn_string_append_char (str, '-'))
1295 return STATUS_ALLOCATION_FAILED;
1298 /* Loop until we hit a non-digit. */
1301 char peek = peek_char (dm);
1302 if (IS_DIGIT ((unsigned char) peek)
1303 || (base == 36 && peek >= 'A' && peek <= 'Z'))
1305 /* Accumulate digits. */
1306 if (!dyn_string_append_char (str, next_char (dm)))
1307 return STATUS_ALLOCATION_FAILED;
1310 /* Not a digit? All done. */
1317 /* Demangles an identifier at the current position of LENGTH
1318 characters and places it in IDENTIFIER. */
1321 demangle_identifier (dm, length, identifier)
1324 dyn_string_t identifier;
1326 DEMANGLE_TRACE ("identifier", dm);
1328 dyn_string_clear (identifier);
1329 if (!dyn_string_resize (identifier, length))
1330 return STATUS_ALLOCATION_FAILED;
1332 while (length-- > 0)
1334 if (end_of_name_p (dm))
1335 return "Unexpected end of name in <identifier>.";
1336 if (!dyn_string_append_char (identifier, next_char (dm)))
1337 return STATUS_ALLOCATION_FAILED;
1343 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1344 the short form is emitted; otherwise the full source form
1345 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1346 operands that the operator takes.
1397 ::= cv <type> # cast
1398 ::= vx <source-name> # vendor extended operator */
1401 demangle_operator_name (dm, short_name, num_args)
1406 struct operator_code
1408 /* The mangled code for this operator. */
1410 /* The source name of this operator. */
1412 /* The number of arguments this operator takes. */
1416 static const struct operator_code operators[] =
1427 { "da", " delete[]", 1 },
1429 { "dl", " delete" , 1 },
1437 { "lS", "<<=" , 2 },
1446 { "na", " new[]" , 1 },
1450 { "nw", " new" , 1 },
1456 { "pm", "->*" , 2 },
1461 { "rS", ">>=" , 2 },
1464 { "sz", " sizeof" , 1 }
1467 const int num_operators =
1468 sizeof (operators) / sizeof (struct operator_code);
1470 int c0 = next_char (dm);
1471 int c1 = next_char (dm);
1472 const struct operator_code* p1 = operators;
1473 const struct operator_code* p2 = operators + num_operators;
1475 DEMANGLE_TRACE ("operator-name", dm);
1477 /* Is this a vendor extended operator? */
1478 if (c0 == 'v' && c1 == 'x')
1480 RETURN_IF_ERROR (result_append (dm, "operator"));
1481 RETURN_IF_ERROR (demangle_source_name (dm));
1486 /* Is this a conversion operator? */
1487 if (c0 == 'c' && c1 == 'v')
1489 RETURN_IF_ERROR (result_append (dm, "operator "));
1490 /* Demangle the converted-to type. */
1491 RETURN_IF_ERROR (demangle_type (dm));
1496 /* Perform a binary search for the operator code. */
1499 const struct operator_code* p = p1 + (p2 - p1) / 2;
1500 char match0 = p->code[0];
1501 char match1 = p->code[1];
1503 if (c0 == match0 && c1 == match1)
1507 RETURN_IF_ERROR (result_append (dm, "operator"));
1508 RETURN_IF_ERROR (result_append (dm, p->name));
1509 *num_args = p->num_args;
1515 /* Couldn't find it. */
1516 return "Unknown code in <operator-name>.";
1519 if (c0 < match0 || (c0 == match0 && c1 < match1))
1526 /* Demangles and emits a <special-name>.
1528 <special-name> ::= GV <object name> # Guard variable
1529 ::= Th[n] <offset number> _ <base name> <base encoding>
1530 # non-virtual base override thunk
1531 ::= Tv[n] <offset number> _ <vcall offset number>
1533 # virtual base override thunk
1534 ::= TV <type> # virtual table
1536 ::= TI <type> # typeinfo structure
1537 ::= TS <type> # typeinfo name
1539 Also demangles the special g++ manglings,
1541 <special-name> ::= CT <type> <offset number> _ <base type>
1542 # construction vtable
1543 ::= TF <type> # typeinfo function (old ABI only)
1544 ::= TJ <type> # java Class structure */
1547 demangle_special_name (dm)
1550 dyn_string_t number;
1552 char peek = peek_char (dm);
1554 DEMANGLE_TRACE ("special-name", dm);
1558 /* A guard variable name. Consume the G. */
1560 RETURN_IF_ERROR (demangle_char (dm, 'V'));
1561 RETURN_IF_ERROR (result_append (dm, "guard variable for "));
1562 RETURN_IF_ERROR (demangle_name (dm, &unused));
1564 else if (peek == 'T')
1566 status_t status = STATUS_OK;
1568 /* Other C++ implementation miscellania. Consume the T. */
1571 switch (peek_char (dm))
1574 /* Virtual table. */
1576 RETURN_IF_ERROR (result_append (dm, "vtable for "));
1577 RETURN_IF_ERROR (demangle_type (dm));
1581 /* VTT structure. */
1583 RETURN_IF_ERROR (result_append (dm, "VTT for "));
1584 RETURN_IF_ERROR (demangle_type (dm));
1588 /* Typeinfo structure. */
1590 RETURN_IF_ERROR (result_append (dm, "typeinfo for "));
1591 RETURN_IF_ERROR (demangle_type (dm));
1595 /* Typeinfo function. Used only in old ABI with new mangling. */
1597 RETURN_IF_ERROR (result_append (dm, "typeinfo fn for "));
1598 RETURN_IF_ERROR (demangle_type (dm));
1602 /* Character string containing type name, used in typeinfo. */
1604 RETURN_IF_ERROR (result_append (dm, "typeinfo name for "));
1605 RETURN_IF_ERROR (demangle_type (dm));
1609 /* The java Class variable corresponding to a C++ class. */
1611 RETURN_IF_ERROR (result_append (dm, "java Class for "));
1612 RETURN_IF_ERROR (demangle_type (dm));
1616 /* Non-virtual thunk. */
1618 RETURN_IF_ERROR (result_append (dm, "non-virtual thunk"));
1619 /* Demangle and emit the offset. */
1620 number = dyn_string_new (4);
1622 return STATUS_ALLOCATION_FAILED;
1623 demangle_number_literally (dm, number, 10, 1);
1624 /* Don't display the offset unless in verbose mode. */
1627 status = result_append_char (dm, ' ');
1628 if (STATUS_NO_ERROR (status))
1629 status = result_append_string (dm, number);
1631 dyn_string_delete (number);
1632 RETURN_IF_ERROR (status);
1633 /* Demangle the separator. */
1634 RETURN_IF_ERROR (demangle_char (dm, '_'));
1635 /* Demangle and emit the target name and function type. */
1636 RETURN_IF_ERROR (result_append (dm, " to "));
1637 RETURN_IF_ERROR (demangle_encoding (dm));
1641 /* Virtual thunk. */
1643 RETURN_IF_ERROR (result_append (dm, "virtual thunk "));
1644 /* Demangle and emit the offset. */
1645 number = dyn_string_new (4);
1647 return STATUS_ALLOCATION_FAILED;
1648 demangle_number_literally (dm, number, 10, 1);
1649 /* Don't display the offset unless in verbose mode. */
1652 status = result_append_string (dm, number);
1653 if (STATUS_NO_ERROR (status))
1654 result_append_char (dm, ' ');
1656 dyn_string_delete (number);
1657 RETURN_IF_ERROR (status);
1658 /* Demangle the separator. */
1659 RETURN_IF_ERROR (demangle_char (dm, '_'));
1660 /* Demangle and emit the vcall offset. */
1661 number = dyn_string_new (4);
1663 return STATUS_ALLOCATION_FAILED;
1664 demangle_number_literally (dm, number, 10, 1);
1665 /* Don't display the vcall offset unless in verbose mode. */
1668 status = result_append_string (dm, number);
1669 if (STATUS_NO_ERROR (status))
1670 status = result_append_char (dm, ' ');
1672 dyn_string_delete (number);
1673 RETURN_IF_ERROR (status);
1674 /* Demangle the separator. */
1675 RETURN_IF_ERROR (demangle_char (dm, '_'));
1676 /* Demangle and emit the target function. */
1677 RETURN_IF_ERROR (result_append (dm, "to "));
1678 RETURN_IF_ERROR (demangle_encoding (dm));
1682 /* TC is a special g++ mangling for a construction vtable. */
1686 RETURN_IF_ERROR (result_append (dm, "construction vtable for "));
1687 RETURN_IF_ERROR (demangle_type (dm));
1688 /* Demangle the offset. */
1689 number = dyn_string_new (4);
1691 return STATUS_ALLOCATION_FAILED;
1692 demangle_number_literally (dm, number, 10, 1);
1693 /* Demangle the underscore separator. */
1694 RETURN_IF_ERROR (demangle_char (dm, '_'));
1695 /* Demangle the base type. */
1696 RETURN_IF_ERROR (result_append (dm, "-in-"));
1697 RETURN_IF_ERROR (demangle_type (dm));
1698 /* Don't display the offset unless in verbose mode. */
1701 status = result_append_char (dm, ' ');
1702 if (STATUS_NO_ERROR (status))
1703 result_append_string (dm, number);
1705 dyn_string_delete (number);
1706 RETURN_IF_ERROR (status);
1709 /* If flag_strict, fall through. */
1712 return "Unrecognized <special-name>.";
1716 return STATUS_ERROR;
1721 /* Demangles and emits a <ctor-dtor-name>.
1724 ::= C1 # complete object (in-charge) ctor
1725 ::= C2 # base object (not-in-charge) ctor
1726 ::= C3 # complete object (in-charge) allocating ctor
1727 ::= C4 # base object (not-in-charge) allocating ctor
1728 ::= D0 # deleting (in-charge) dtor
1729 ::= D1 # complete object (in-charge) dtor
1730 ::= D2 # base object (not-in-charge) dtor */
1733 demangle_ctor_dtor_name (dm)
1736 static const char *const ctor_flavors[] =
1740 "in-charge allocating",
1741 "not-in-charge allocating"
1743 static const char *const dtor_flavors[] =
1745 "in-charge deleting",
1751 char peek = peek_char (dm);
1753 DEMANGLE_TRACE ("ctor-dtor-name", dm);
1757 /* A constructor name. Consume the C. */
1759 if (peek_char (dm) < '1' || peek_char (dm) > '4')
1760 return "Unrecognized constructor.";
1761 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1762 /* Print the flavor of the constructor if in verbose mode. */
1763 flavor = next_char (dm) - '1';
1766 RETURN_IF_ERROR (result_append (dm, "["));
1767 RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor]));
1768 RETURN_IF_ERROR (result_append_char (dm, ']'));
1771 else if (peek == 'D')
1773 /* A destructor name. Consume the D. */
1775 if (peek_char (dm) < '0' || peek_char (dm) > '2')
1776 return "Unrecognized destructor.";
1777 RETURN_IF_ERROR (result_append_char (dm, '~'));
1778 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1779 /* Print the flavor of the destructor if in verbose mode. */
1780 flavor = next_char (dm) - '0';
1783 RETURN_IF_ERROR (result_append (dm, " ["));
1784 RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor]));
1785 RETURN_IF_ERROR (result_append_char (dm, ']'));
1789 return STATUS_ERROR;
1794 /* Handle pointer, reference, and pointer-to-member cases for
1795 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1796 build a pointer/reference type. We snarf all these, plus the
1797 following <type>, all at once since we need to know whether we have
1798 a pointer to data or pointer to function to construct the right
1799 output syntax. C++'s pointer syntax is hairy.
1803 ::= <pointer-to-member-type>
1805 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1808 demangle_type_ptr (dm)
1814 /* Collect pointer symbols into this string. */
1815 dyn_string_t symbols = dyn_string_new (10);
1817 DEMANGLE_TRACE ("type*", dm);
1819 if (symbols == NULL)
1820 return STATUS_ALLOCATION_FAILED;
1822 /* Scan forward, collecting pointers and references into symbols,
1823 until we hit something else. Then emit the type. */
1826 next = peek_char (dm);
1829 if (!dyn_string_append_char (symbols, '*'))
1830 return STATUS_ALLOCATION_FAILED;
1833 else if (next == 'R')
1835 if (!dyn_string_append_char (symbols, '&'))
1836 return STATUS_ALLOCATION_FAILED;
1839 else if (next == 'M')
1841 /* Pointer-to-member. */
1842 dyn_string_t class_type;
1847 /* Capture the type of which this is a pointer-to-member. */
1848 RETURN_IF_ERROR (result_push (dm));
1849 RETURN_IF_ERROR (demangle_type (dm));
1850 class_type = (dyn_string_t) result_pop (dm);
1852 /* Build the pointer-to-member notation. It comes before
1853 other pointer and reference qualifiers -- */
1854 if (!dyn_string_prepend_cstr (symbols, "::*"))
1855 return STATUS_ALLOCATION_FAILED;
1856 if (!dyn_string_prepend (symbols, class_type))
1857 return STATUS_ALLOCATION_FAILED;
1858 dyn_string_delete (class_type);
1860 if (peek_char (dm) == 'F')
1863 /* Demangle the type of the pointed-to member. */
1864 status = demangle_type (dm);
1865 /* Make it pretty. */
1866 if (STATUS_NO_ERROR (status))
1867 status = result_append_space (dm);
1868 /* Add the pointer-to-member syntax, and other pointer and
1869 reference symbols. */
1870 if (STATUS_NO_ERROR (status))
1871 status = result_append_string (dm, symbols);
1873 dyn_string_delete (symbols);
1875 RETURN_IF_ERROR (status);
1878 else if (next == 'F')
1880 /* Ooh, tricky, a pointer-to-function. */
1881 int position = result_length (dm);
1882 status = result_append_char (dm, '(');
1883 if (STATUS_NO_ERROR (status))
1884 status = result_append_string (dm, symbols);
1885 if (STATUS_NO_ERROR (status))
1886 status = result_append_char (dm, ')');
1887 dyn_string_delete (symbols);
1888 RETURN_IF_ERROR (status);
1890 RETURN_IF_ERROR (demangle_function_type (dm, position));
1895 /* No more pointe or reference tokens. Finish up. */
1896 status = demangle_type (dm);
1898 if (STATUS_NO_ERROR (status))
1899 status = result_append_string (dm, symbols);
1900 dyn_string_delete (symbols);
1901 RETURN_IF_ERROR (status);
1903 RETURN_IF_ERROR (status);
1909 /* Demangles and emits a <type>.
1911 <type> ::= <builtin-type>
1913 ::= <class-enum-type>
1915 ::= <pointer-to-member-type>
1916 ::= <template-param>
1917 ::= <CV-qualifiers> <type>
1918 ::= P <type> # pointer-to
1919 ::= R <type> # reference-to
1920 ::= C <type> # complex pair (C 2000)
1921 ::= G <type> # imaginary (C 2000)
1922 ::= U <source-name> <type> # vendor extended type qualifier
1923 ::= <substitution> */
1929 int start = substitution_start (dm);
1930 char peek = peek_char (dm);
1932 int special_std_substitution;
1933 int is_builtin_type = 0;
1934 template_arg_list_t old_arg_list = current_template_arg_list (dm);
1935 int template_parm = NOT_TEMPLATE_PARM;
1937 DEMANGLE_TRACE ("type", dm);
1939 /* A <class-enum-type> can start with a digit (a <source-name>), an
1940 N (a <nested-name>), or a Z (a <local-name>). */
1941 if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
1942 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
1943 else if (peek >= 'a' && peek <= 'z')
1945 RETURN_IF_ERROR (demangle_builtin_type (dm));
1946 is_builtin_type = 1;
1956 dyn_string_t cv_qualifiers = dyn_string_new (24);
1958 if (cv_qualifiers == NULL)
1959 return STATUS_ALLOCATION_FAILED;
1961 demangle_CV_qualifiers (dm, cv_qualifiers);
1963 /* If the qualifiers apply to a pointer or reference, they
1964 need to come after the whole qualified type. */
1965 if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
1967 status = demangle_type (dm);
1968 if (STATUS_NO_ERROR (status))
1969 status = result_append_space (dm);
1970 if (STATUS_NO_ERROR (status))
1971 status = result_append_string (dm, cv_qualifiers);
1973 /* Otherwise, the qualifiers come first. */
1976 status = result_append_string (dm, cv_qualifiers);
1977 if (STATUS_NO_ERROR (status))
1978 status = result_append_space (dm);
1979 if (STATUS_NO_ERROR (status))
1980 status = demangle_type (dm);
1983 dyn_string_delete (cv_qualifiers);
1984 RETURN_IF_ERROR (status);
1989 return "Non-pointer or -reference function type.";
1992 RETURN_IF_ERROR (demangle_array_type (dm));
1996 RETURN_IF_ERROR (demangle_template_param (dm, &template_parm));
2000 RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
2001 &special_std_substitution));
2002 if (special_std_substitution)
2004 /* This was the magic `std::' substitution. What follows
2005 must be a class name in that namespace. */
2006 RETURN_IF_ERROR (result_append (dm, "::"));
2007 RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
2014 RETURN_IF_ERROR (demangle_type_ptr (dm));
2018 /* A C99 complex type. */
2019 RETURN_IF_ERROR (result_append (dm, "complex "));
2021 RETURN_IF_ERROR (demangle_type (dm));
2025 /* A C99 imaginary type. */
2026 RETURN_IF_ERROR (result_append (dm, "imaginary "));
2028 RETURN_IF_ERROR (demangle_type (dm));
2032 /* Vendor extended type qualifier. */
2034 RETURN_IF_ERROR (demangle_source_name (dm));
2035 RETURN_IF_ERROR (result_append_char (dm, ' '));
2036 RETURN_IF_ERROR (demangle_type (dm));
2040 return "Unexpected character in <type>.";
2043 /* Unqualified builin types are not substitution candidates. */
2044 if (!is_builtin_type)
2045 /* Add a new substitution for the type. If this type was a
2046 <template-param>, pass its index since from the point of
2047 substitutions, a <template-param> token is a substitution
2048 candidate distinct from the type that is substituted for it. */
2049 RETURN_IF_ERROR (substitution_add (dm, start, template_p, template_parm));
2051 /* Pop off template argument lists added during mangling of this
2053 pop_to_template_arg_list (dm, old_arg_list);
2058 /* C++ source names of builtin types, indexed by the mangled code
2059 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2060 static const char *const builtin_type_names[26] =
2062 "signed char", /* a */
2066 "long double", /* e */
2068 "__float128", /* g */
2069 "unsigned char", /* h */
2074 "unsigned long", /* m */
2076 "unsigned __int128", /* o */
2081 "unsigned short", /* t */
2085 "long long", /* x */
2086 "unsigned long long", /* y */
2090 /* Demangles and emits a <builtin-type>.
2092 <builtin-type> ::= v # void
2097 ::= h # unsigned char
2099 ::= t # unsigned short
2101 ::= j # unsigned int
2103 ::= m # unsigned long
2104 ::= x # long long, __int64
2105 ::= y # unsigned long long, __int64
2107 ::= o # unsigned __int128
2110 ::= e # long double, __float80
2113 ::= u <source-name> # vendor extended type */
2116 demangle_builtin_type (dm)
2120 char code = peek_char (dm);
2122 DEMANGLE_TRACE ("builtin-type", dm);
2127 RETURN_IF_ERROR (demangle_source_name (dm));
2130 else if (code >= 'a' && code <= 'z')
2132 const char *type_name = builtin_type_names[code - 'a'];
2133 if (type_name == NULL)
2134 return "Unrecognized <builtin-type> code.";
2136 RETURN_IF_ERROR (result_append (dm, type_name));
2141 return "Non-alphabetic <builtin-type> code.";
2144 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2145 restrict) at the current position. The qualifiers are appended to
2146 QUALIFIERS. Returns STATUS_OK. */
2149 demangle_CV_qualifiers (dm, qualifiers)
2151 dyn_string_t qualifiers;
2153 DEMANGLE_TRACE ("CV-qualifiers", dm);
2157 switch (peek_char (dm))
2160 if (!dyn_string_append_space (qualifiers))
2161 return STATUS_ALLOCATION_FAILED;
2162 if (!dyn_string_append_cstr (qualifiers, "restrict"))
2163 return STATUS_ALLOCATION_FAILED;
2167 if (!dyn_string_append_space (qualifiers))
2168 return STATUS_ALLOCATION_FAILED;
2169 if (!dyn_string_append_cstr (qualifiers, "volatile"))
2170 return STATUS_ALLOCATION_FAILED;
2174 if (!dyn_string_append_space (qualifiers))
2175 return STATUS_ALLOCATION_FAILED;
2176 if (!dyn_string_append_cstr (qualifiers, "const"))
2177 return STATUS_ALLOCATION_FAILED;
2188 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2189 position in the result string of the start of the function
2190 identifier, at which the function's return type will be inserted.
2192 <function-type> ::= F [Y] <bare-function-type> E */
2195 demangle_function_type (dm, function_name_pos)
2197 int function_name_pos;
2199 DEMANGLE_TRACE ("function-type", dm);
2200 RETURN_IF_ERROR (demangle_char (dm, 'F'));
2201 if (peek_char (dm) == 'Y')
2203 /* Indicate this function has C linkage if in verbose mode. */
2205 RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] "));
2208 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2209 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2213 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2214 position in the result string at which the function return type
2215 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2216 function's return type is assumed not to be encoded.
2218 <bare-function-type> ::= <signature type>+ */
2221 demangle_bare_function_type (dm, return_type_pos)
2223 int return_type_pos;
2225 /* Sequence is the index of the current function parameter, counting
2226 from zero. The value -1 denotes the return type. */
2228 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2230 DEMANGLE_TRACE ("bare-function-type", dm);
2232 RETURN_IF_ERROR (result_append_char (dm, '('));
2233 while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2236 /* We're decoding the function's return type. */
2238 dyn_string_t return_type;
2239 status_t status = STATUS_OK;
2241 /* Decode the return type off to the side. */
2242 RETURN_IF_ERROR (result_push (dm));
2243 RETURN_IF_ERROR (demangle_type (dm));
2244 return_type = (dyn_string_t) result_pop (dm);
2246 /* Add a space to the end of the type. Insert the return
2247 type where we've been asked to. */
2248 if (!dyn_string_append_space (return_type)
2249 || !dyn_string_insert (result_string (dm), return_type_pos,
2251 status = STATUS_ALLOCATION_FAILED;
2253 dyn_string_delete (return_type);
2254 RETURN_IF_ERROR (status);
2258 /* Skip `void' parameter types. One should only occur as
2259 the only type in a parameter list; in that case, we want
2260 to print `foo ()' instead of `foo (void)'. */
2261 if (peek_char (dm) == 'v')
2263 /* Consume the v. */
2267 /* Separate parameter types by commas. */
2269 RETURN_IF_ERROR (result_append (dm, ", "));
2270 /* Demangle the type. */
2271 RETURN_IF_ERROR (demangle_type (dm));
2276 RETURN_IF_ERROR (result_append_char (dm, ')'));
2281 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2282 non-zero if the type is a template-id, zero otherwise.
2284 <class-enum-type> ::= <name> */
2287 demangle_class_enum_type (dm, template_p)
2291 DEMANGLE_TRACE ("class-enum-type", dm);
2293 RETURN_IF_ERROR (demangle_name (dm, template_p));
2297 /* Demangles and emits an <array-type>.
2299 <array-type> ::= A [<dimension number>] _ <element type> */
2302 demangle_array_type (dm)
2306 dyn_string_t array_size = dyn_string_new (10);
2308 if (array_size == NULL)
2309 return STATUS_ALLOCATION_FAILED;
2311 status = demangle_char (dm, 'A');
2313 /* Demangle the array size into array_size. */
2314 if (STATUS_NO_ERROR (status))
2315 status = demangle_number_literally (dm, array_size, 10, 0);
2317 /* Demangle the base type of the array. */
2318 if (STATUS_NO_ERROR (status))
2319 status = demangle_char (dm, '_');
2320 if (STATUS_NO_ERROR (status))
2321 status = demangle_type (dm);
2323 /* Emit the array dimension syntax. */
2324 if (STATUS_NO_ERROR (status))
2325 status = result_append_char (dm, '[');
2326 if (STATUS_NO_ERROR (status))
2327 status = result_append_string (dm, array_size);
2328 if (STATUS_NO_ERROR (status))
2329 status = result_append_char (dm, ']');
2330 dyn_string_delete (array_size);
2332 RETURN_IF_ERROR (status);
2337 /* Demangles and emits a <template-param>. The zero-indexed position
2338 in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
2340 <template-param> ::= T_ # first template parameter
2341 ::= T <parameter-2 number> _ */
2344 demangle_template_param (dm, template_parm_number)
2346 int *template_parm_number;
2349 template_arg_list_t current_arg_list = current_template_arg_list (dm);
2352 DEMANGLE_TRACE ("template-param", dm);
2354 /* Make sure there is a template argmust list in which to look up
2355 this parameter reference. */
2356 if (current_arg_list == NULL)
2357 return "Template parameter outside of template.";
2359 RETURN_IF_ERROR (demangle_char (dm, 'T'));
2360 if (peek_char (dm) == '_')
2364 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2367 RETURN_IF_ERROR (demangle_char (dm, '_'));
2369 arg = template_arg_list_get_arg (current_arg_list, parm_number);
2371 /* parm_number exceeded the number of arguments in the current
2372 template argument list. */
2373 return "Template parameter number out of bounds.";
2374 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2376 if (peek_char (dm) == 'I')
2377 RETURN_IF_ERROR (demangle_template_args (dm));
2379 *template_parm_number = parm_number;
2383 /* Demangles and emits a <template-args>.
2385 <template-args> ::= I <template-arg>+ E */
2388 demangle_template_args (dm)
2392 dyn_string_t old_last_source_name;
2393 template_arg_list_t arg_list = template_arg_list_new ();
2395 if (arg_list == NULL)
2396 return STATUS_ALLOCATION_FAILED;
2398 /* Preserve the most recently demangled source name. */
2399 old_last_source_name = dm->last_source_name;
2400 dm->last_source_name = dyn_string_new (0);
2402 DEMANGLE_TRACE ("template-args", dm);
2404 if (dm->last_source_name == NULL)
2405 return STATUS_ALLOCATION_FAILED;
2407 RETURN_IF_ERROR (demangle_char (dm, 'I'));
2408 RETURN_IF_ERROR (result_append_char (dm, '<'));
2416 RETURN_IF_ERROR (result_append (dm, ", "));
2418 /* Capture the template arg. */
2419 RETURN_IF_ERROR (result_push (dm));
2420 RETURN_IF_ERROR (demangle_template_arg (dm));
2421 arg = result_pop (dm);
2423 /* Emit it in the demangled name. */
2424 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2426 /* Save it for use in expanding <template-param>s. */
2427 template_arg_list_add_arg (arg_list, arg);
2429 while (peek_char (dm) != 'E');
2430 /* Append the '>'. */
2431 RETURN_IF_ERROR (result_close_template_list (dm));
2433 /* Consume the 'E'. */
2436 /* Restore the most recent demangled source name. */
2437 dyn_string_delete (dm->last_source_name);
2438 dm->last_source_name = old_last_source_name;
2440 /* Push the list onto the top of the stack of template argument
2441 lists, so that arguments from it are used from now on when
2442 expanding <template-param>s. */
2443 push_template_arg_list (dm, arg_list);
2448 /* This function, which does not correspond to a production in the
2449 mangling spec, handles the `literal' production for both
2450 <template-arg> and <expr-primary>. It does not expect or consume
2451 the initial `L' or final `E'. The demangling is given by:
2453 <literal> ::= <type> </value/ number>
2455 and the emitted output is `(type)number'. */
2458 demangle_literal (dm)
2461 char peek = peek_char (dm);
2462 dyn_string_t value_string;
2465 DEMANGLE_TRACE ("literal", dm);
2467 if (!flag_verbose && peek >= 'a' && peek <= 'z')
2469 /* If not in verbose mode and this is a builtin type, see if we
2470 can produce simpler numerical output. In particular, for
2471 integer types shorter than `long', just write the number
2472 without type information; for bools, write `true' or `false'.
2473 Other refinements could be made here too. */
2475 /* This constant string is used to map from <builtin-type> codes
2476 (26 letters of the alphabet) to codes that determine how the
2477 value will be displayed. The codes are:
2481 A space means the value will be represented using cast
2483 static const char *const code_map = "ibi iii ll ii i ";
2485 char code = code_map[peek - 'a'];
2486 /* FIXME: Implement demangling of floats and doubles. */
2488 return STATUS_UNIMPLEMENTED;
2491 /* It's a boolean. */
2494 /* Consume the b. */
2496 /* Look at the next character. It should be 0 or 1,
2497 corresponding to false or true, respectively. */
2498 value = peek_char (dm);
2500 RETURN_IF_ERROR (result_append (dm, "false"));
2501 else if (value == '1')
2502 RETURN_IF_ERROR (result_append (dm, "true"));
2504 return "Unrecognized bool constant.";
2505 /* Consume the 0 or 1. */
2509 else if (code == 'i' || code == 'l')
2511 /* It's an integer or long. */
2513 /* Consume the type character. */
2516 /* Demangle the number and write it out. */
2517 value_string = dyn_string_new (0);
2518 status = demangle_number_literally (dm, value_string, 10, 1);
2519 if (STATUS_NO_ERROR (status))
2520 status = result_append_string (dm, value_string);
2521 /* For long integers, append an l. */
2522 if (code == 'l' && STATUS_NO_ERROR (status))
2523 status = result_append_char (dm, code);
2524 dyn_string_delete (value_string);
2526 RETURN_IF_ERROR (status);
2529 /* ...else code == ' ', so fall through to represent this
2530 literal's type explicitly using cast syntax. */
2533 RETURN_IF_ERROR (result_append_char (dm, '('));
2534 RETURN_IF_ERROR (demangle_type (dm));
2535 RETURN_IF_ERROR (result_append_char (dm, ')'));
2537 value_string = dyn_string_new (0);
2538 if (value_string == NULL)
2539 return STATUS_ALLOCATION_FAILED;
2541 status = demangle_number_literally (dm, value_string, 10, 1);
2542 if (STATUS_NO_ERROR (status))
2543 status = result_append_string (dm, value_string);
2544 dyn_string_delete (value_string);
2545 RETURN_IF_ERROR (status);
2550 /* Demangles and emits a <template-arg>.
2552 <template-arg> ::= <type> # type
2553 ::= L <type> <value number> E # literal
2554 ::= LZ <encoding> E # external name
2555 ::= X <expression> E # expression */
2558 demangle_template_arg (dm)
2561 DEMANGLE_TRACE ("template-arg", dm);
2563 switch (peek_char (dm))
2568 if (peek_char (dm) == 'Z')
2570 /* External name. */
2572 /* FIXME: Standard is contradictory here. */
2573 RETURN_IF_ERROR (demangle_encoding (dm));
2576 RETURN_IF_ERROR (demangle_literal (dm));
2577 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2583 RETURN_IF_ERROR (demangle_expression (dm));
2587 RETURN_IF_ERROR (demangle_type (dm));
2594 /* Demangles and emits an <expression>.
2596 <expression> ::= <unary operator-name> <expression>
2597 ::= <binary operator-name> <expression> <expression>
2599 ::= <scope-expression> */
2602 demangle_expression (dm)
2605 char peek = peek_char (dm);
2607 DEMANGLE_TRACE ("expression", dm);
2609 if (peek == 'L' || peek == 'T')
2610 RETURN_IF_ERROR (demangle_expr_primary (dm));
2611 else if (peek == 's' && peek_char_next (dm) == 'r')
2612 RETURN_IF_ERROR (demangle_scope_expression (dm));
2614 /* An operator expression. */
2617 status_t status = STATUS_OK;
2618 dyn_string_t operator_name;
2620 /* We have an operator name. Since we want to output binary
2621 operations in infix notation, capture the operator name
2623 RETURN_IF_ERROR (result_push (dm));
2624 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
2625 operator_name = (dyn_string_t) result_pop (dm);
2627 /* If it's binary, do an operand first. */
2630 status = result_append_char (dm, '(');
2631 if (STATUS_NO_ERROR (status))
2632 status = demangle_expression (dm);
2633 if (STATUS_NO_ERROR (status))
2634 status = result_append_char (dm, ')');
2637 /* Emit the operator. */
2638 if (STATUS_NO_ERROR (status))
2639 status = result_append_string (dm, operator_name);
2640 dyn_string_delete (operator_name);
2641 RETURN_IF_ERROR (status);
2643 /* Emit its second (if binary) or only (if unary) operand. */
2644 RETURN_IF_ERROR (result_append_char (dm, '('));
2645 RETURN_IF_ERROR (demangle_expression (dm));
2646 RETURN_IF_ERROR (result_append_char (dm, ')'));
2648 /* The ternary operator takes a third operand. */
2651 RETURN_IF_ERROR (result_append (dm, ":("));
2652 RETURN_IF_ERROR (demangle_expression (dm));
2653 RETURN_IF_ERROR (result_append_char (dm, ')'));
2660 /* Demangles and emits a <scope-expression>.
2662 <scope-expression> ::= sr <qualifying type> <source-name>
2663 ::= sr <qualifying type> <encoding> */
2666 demangle_scope_expression (dm)
2669 RETURN_IF_ERROR (demangle_char (dm, 's'));
2670 RETURN_IF_ERROR (demangle_char (dm, 'r'));
2671 RETURN_IF_ERROR (demangle_type (dm));
2672 RETURN_IF_ERROR (result_append (dm, "::"));
2673 RETURN_IF_ERROR (demangle_encoding (dm));
2677 /* Demangles and emits an <expr-primary>.
2679 <expr-primary> ::= <template-param>
2680 ::= L <type> <value number> E # literal
2681 ::= L <mangled-name> E # external name */
2684 demangle_expr_primary (dm)
2687 char peek = peek_char (dm);
2690 DEMANGLE_TRACE ("expr-primary", dm);
2693 RETURN_IF_ERROR (demangle_template_param (dm, &unused));
2694 else if (peek == 'L')
2696 /* Consume the `L'. */
2698 peek = peek_char (dm);
2701 RETURN_IF_ERROR (demangle_mangled_name (dm));
2703 RETURN_IF_ERROR (demangle_literal (dm));
2705 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2708 return STATUS_ERROR;
2713 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2714 if the substitution is the name of a template, zero otherwise. If
2715 the substitution token is St, which corresponds to the `::std::'
2716 namespace and can appear in a non-nested name, sets
2717 *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.
2719 <substitution> ::= S <seq-id> _
2723 ::= Sa # ::std::allocator
2724 ::= Sb # ::std::basic_string
2725 ::= Ss # ::std::basic_string<char,
2726 ::std::char_traits<char>,
2727 ::std::allocator<char> >
2728 ::= Si # ::std::basic_istream<char,
2729 std::char_traits<char> >
2730 ::= So # ::std::basic_ostream<char,
2731 std::char_traits<char> >
2732 ::= Sd # ::std::basic_iostream<char,
2733 std::char_traits<char> >
2737 demangle_substitution (dm, template_p, special_std_substitution)
2740 int *special_std_substitution;
2746 DEMANGLE_TRACE ("substitution", dm);
2748 RETURN_IF_ERROR (demangle_char (dm, 'S'));
2749 *special_std_substitution = 0;
2751 /* Scan the substitution sequence index. A missing number denotes
2753 peek = peek_char (dm);
2756 /* If the following character is 0-9 or a capital letter, interpret
2757 the sequence up to the next underscore as a base-36 substitution
2759 else if (IS_DIGIT ((unsigned char) peek)
2760 || (peek >= 'A' && peek <= 'Z'))
2761 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
2764 const char *new_last_source_name = NULL;
2769 RETURN_IF_ERROR (result_append (dm, "std"));
2770 *special_std_substitution = 1;
2774 RETURN_IF_ERROR (result_append (dm, "std::allocator"));
2775 new_last_source_name = "allocator";
2779 RETURN_IF_ERROR (result_append (dm, "std::basic_string"));
2780 new_last_source_name = "basic_string";
2786 RETURN_IF_ERROR (result_append (dm, "std::string"));
2787 new_last_source_name = "string";
2791 RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
2792 new_last_source_name = "basic_string";
2799 RETURN_IF_ERROR (result_append (dm, "std::istream"));
2800 new_last_source_name = "istream";
2804 RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >"));
2805 new_last_source_name = "basic_istream";
2812 RETURN_IF_ERROR (result_append (dm, "std::ostream"));
2813 new_last_source_name = "ostream";
2817 RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >"));
2818 new_last_source_name = "basic_ostream";
2825 RETURN_IF_ERROR (result_append (dm, "std::iostream"));
2826 new_last_source_name = "iostream";
2830 RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >"));
2831 new_last_source_name = "basic_iostream";
2836 return "Unrecognized <substitution>.";
2839 /* Consume the character we just processed. */
2842 if (new_last_source_name != NULL)
2844 if (!dyn_string_copy_cstr (dm->last_source_name,
2845 new_last_source_name))
2846 return STATUS_ALLOCATION_FAILED;
2852 /* Look up the substitution text. Since `S_' is the most recent
2853 substitution, `S0_' is the second-most-recent, etc., shift the
2854 numbering by one. */
2855 text = substitution_get (dm, seq_id + 1, template_p);
2857 return "Substitution number out of range.";
2859 /* Emit the substitution text. */
2860 RETURN_IF_ERROR (result_append_string (dm, text));
2862 RETURN_IF_ERROR (demangle_char (dm, '_'));
2866 /* Demangles and emits a <local-name>.
2868 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2869 := Z <function encoding> E s [<discriminator>] */
2872 demangle_local_name (dm)
2875 DEMANGLE_TRACE ("local-name", dm);
2877 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
2878 RETURN_IF_ERROR (demangle_encoding (dm));
2879 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2880 RETURN_IF_ERROR (result_append (dm, "'s "));
2882 if (peek_char (dm) == 's')
2884 /* Local character string literal. */
2885 RETURN_IF_ERROR (result_append (dm, "string literal"));
2886 /* Consume the s. */
2888 RETURN_IF_ERROR (demangle_discriminator (dm, 0));
2893 RETURN_IF_ERROR (result_append (dm, "local "));
2894 /* Local name for some other entity. Demangle its name. */
2895 RETURN_IF_ERROR (demangle_name (dm, &unused));
2896 RETURN_IF_ERROR (demangle_discriminator (dm, 1));
2902 /* Optimonally demangles and emits a <discriminator>. If there is no
2903 <discriminator> at the current position in the mangled string, the
2904 descriminator is assumed to be zero. Emit the discriminator number
2905 in parentheses, unless SUPPRESS_FIRST is non-zero and the
2906 discriminator is zero.
2908 <discriminator> ::= _ <number> */
2911 demangle_discriminator (dm, suppress_first)
2915 /* Output for <discriminator>s to the demangled name is completely
2916 supressed if not in verbose mode. */
2918 if (peek_char (dm) == '_')
2920 /* Consume the underscore. */
2923 RETURN_IF_ERROR (result_append (dm, " [#"));
2924 /* Check if there's a number following the underscore. */
2925 if (IS_DIGIT ((unsigned char) peek_char (dm)))
2928 /* Demangle the number. */
2929 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
2931 /* Write the discriminator. The mangled number is two
2932 less than the discriminator ordinal, counting from
2934 RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2,
2935 (dyn_string_t) dm->result));
2940 /* A missing digit correspond to one. */
2941 RETURN_IF_ERROR (result_append_char (dm, '1'));
2944 RETURN_IF_ERROR (result_append_char (dm, ']'));
2946 else if (!suppress_first)
2949 RETURN_IF_ERROR (result_append (dm, " [#0]"));
2955 /* Demangle NAME into RESULT, which must be an initialized
2956 dyn_string_t. On success, returns STATUS_OK. On failure, returns
2957 an error message, and the contents of RESULT are unchanged. */
2960 cp_demangle (name, result)
2962 dyn_string_t result;
2965 int length = strlen (name);
2967 if (length > 2 && name[0] == '_' && name[1] == 'Z')
2969 demangling_t dm = demangling_new (name);
2971 return STATUS_ALLOCATION_FAILED;
2973 status = result_push (dm);
2974 if (status != STATUS_OK)
2976 demangling_delete (dm);
2980 status = demangle_mangled_name (dm);
2981 if (STATUS_NO_ERROR (status))
2983 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
2984 if (!dyn_string_copy (result, demangled))
2985 return STATUS_ALLOCATION_FAILED;
2986 dyn_string_delete (demangled);
2989 demangling_delete (dm);
2993 /* It's evidently not a mangled C++ name. It could be the name
2994 of something with C linkage, though, so just copy NAME into
2996 if (!dyn_string_copy_cstr (result, name))
2997 return STATUS_ALLOCATION_FAILED;
3004 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3005 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3006 an error message, and the contents of RESULT are unchanged. */
3009 cp_demangle_type (type_name, result)
3010 const char* type_name;
3011 dyn_string_t result;
3014 demangling_t dm = demangling_new (type_name);
3017 return STATUS_ALLOCATION_FAILED;
3019 /* Demangle the type name. The demangled name is stored in dm. */
3020 status = result_push (dm);
3021 if (status != STATUS_OK)
3023 demangling_delete (dm);
3027 status = demangle_type (dm);
3029 if (STATUS_NO_ERROR (status))
3031 /* The demangling succeeded. Pop the result out of dm and copy
3033 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3034 if (!dyn_string_copy (result, demangled))
3035 return STATUS_ALLOCATION_FAILED;
3036 dyn_string_delete (demangled);
3040 demangling_delete (dm);
3048 extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
3050 /* ABI-mandated entry point in the C++ runtime library for performing
3051 demangling. MANGLED_NAME is a NUL-terminated character string
3052 containing the name to be demangled.
3054 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3055 *LENGTH bytes, into which the demangled name is stored. If
3056 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3057 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3058 is placed in a region of memory allocated with malloc.
3060 If LENGTH is non-NULL, the length of the buffer conaining the
3061 demangled name, is placed in *LENGTH.
3063 The return value is a pointer to the start of the NUL-terminated
3064 demangled name, or NULL if the demangling fails. The caller is
3065 responsible for deallocating this memory using free.
3067 *STATUS is set to one of the following values:
3068 0: The demangling operation succeeded.
3069 -1: A memory allocation failiure occurred.
3070 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3071 -3: One of the arguments is invalid.
3073 The demagling is performed using the C++ ABI mangling rules, with
3077 __cxa_demangle (mangled_name, output_buffer, length, status)
3078 const char *mangled_name;
3079 char *output_buffer;
3083 struct dyn_string demangled_name;
3089 if (mangled_name == NULL) {
3094 /* Did the caller provide a buffer for the demangled name? */
3095 if (output_buffer == NULL) {
3096 /* No; dyn_string will malloc a buffer for us. */
3097 if (!dyn_string_init (&demangled_name, 0))
3104 /* Yes. Check that the length was provided. */
3105 if (length == NULL) {
3109 /* Install the buffer into a dyn_string. */
3110 demangled_name.allocated = *length;
3111 demangled_name.length = 0;
3112 demangled_name.s = output_buffer;
3115 if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
3116 /* MANGLED_NAME apprears to be a function or variable name.
3117 Demangle it accordingly. */
3118 result = cp_demangle (mangled_name, &demangled_name);
3120 /* Try to demangled MANGLED_NAME as the name of a type. */
3121 result = cp_demangle_type (mangled_name, &demangled_name);
3123 if (result == STATUS_OK)
3124 /* The demangling succeeded. */
3126 /* If LENGTH isn't NULL, store the allocated buffer length
3127 there; the buffer may have been realloced by dyn_string
3130 *length = demangled_name.allocated;
3131 /* The operation was a success. */
3133 return dyn_string_buf (&demangled_name);
3135 else if (result == STATUS_ALLOCATION_FAILED)
3136 /* A call to malloc or realloc failed during the demangling
3143 /* The demangling failed for another reason, most probably because
3144 MANGLED_NAME isn't a valid mangled name. */
3146 /* If the buffer containing the demangled name wasn't provided
3147 by the caller, free it. */
3148 if (output_buffer == NULL)
3149 free (dyn_string_buf (&demangled_name));
3155 #else /* !IN_LIBGCC2 */
3157 /* Variant entry point for integration with the existing cplus-dem
3158 demangler. Attempts to demangle MANGLED. If the demangling
3159 succeeds, returns a buffer, allocated with malloc, containing the
3160 demangled name. The caller must deallocate the buffer using free.
3161 If the demangling failes, returns NULL. */
3164 cplus_demangle_new_abi (mangled)
3165 const char* mangled;
3167 /* Create a dyn_string to hold the demangled name. */
3168 dyn_string_t demangled = dyn_string_new (0);
3169 /* Attempt the demangling. */
3170 status_t status = cp_demangle ((char *) mangled, demangled);
3171 if (STATUS_NO_ERROR (status))
3172 /* Demangling succeeded. */
3174 /* Grab the demangled result from the dyn_string. It was
3175 allocated with malloc, so we can return it directly. */
3176 char *return_value = dyn_string_release (demangled);
3177 /* Hand back the demangled name. */
3178 return return_value;
3180 else if (status == STATUS_ALLOCATION_FAILED)
3182 fprintf (stderr, "Memory allocation failed.\n");
3186 /* Demangling failed. */
3188 dyn_string_delete (demangled);
3193 #endif /* IN_LIBGCC2 */
3195 #ifdef STANDALONE_DEMANGLER
3199 static void print_usage
3200 PARAMS ((FILE* fp, int exit_value));
3202 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3203 #define is_mangled_char(CHAR) \
3204 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) || (CHAR) == '_')
3206 /* The name of this program, as invoked. */
3207 const char* program_name;
3209 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3212 print_usage (fp, exit_value)
3216 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
3217 fprintf (fp, "Options:\n", program_name);
3218 fprintf (fp, " -h,--help Display this message.\n");
3219 fprintf (fp, " -s,--strict Demangle standard names only.\n");
3220 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
3221 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3226 /* Option specification for getopt_long. */
3227 static struct option long_options[] =
3229 { "help", no_argument, NULL, 'h' },
3230 { "strict", no_argument, NULL, 's' },
3231 { "verbose", no_argument, NULL, 'v' },
3232 { NULL, no_argument, NULL, 0 },
3235 /* Main entry for a demangling filter executable. It will demangle
3236 its command line arguments, if any. If none are provided, it will
3237 filter stdin to stdout, replacing any recognized mangled C++ names
3238 with their demangled equivalents. */
3249 /* Use the program name of this program, as invoked. */
3250 program_name = argv[0];
3252 /* Parse options. */
3255 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
3258 case '?': /* Unrecognized option. */
3259 print_usage (stderr, 1);
3263 print_usage (stdout, 0);
3275 while (opt_char != -1);
3278 /* No command line arguments were provided. Filter stdin. */
3280 dyn_string_t mangled = dyn_string_new (3);
3281 dyn_string_t demangled = dyn_string_new (0);
3284 /* Read all of input. */
3285 while (!feof (stdin))
3287 char c = getchar ();
3289 /* The first character of a mangled name is an underscore. */
3294 /* It's not a mangled name. Print the character and go
3301 /* The second character of a mangled name is a capital `Z'. */
3306 /* It's not a mangled name. Print the previous
3307 underscore, the `Z', and go on. */
3313 /* Start keeping track of the candidate mangled name. */
3314 dyn_string_append_char (mangled, '_');
3315 dyn_string_append_char (mangled, 'Z');
3317 /* Pile characters into mangled until we hit one that can't
3318 occur in a mangled name. */
3320 while (!feof (stdin) && is_mangled_char (c))
3322 dyn_string_append_char (mangled, c);
3328 /* Attempt to demangle the name. */
3329 status = cp_demangle (dyn_string_buf (mangled), demangled);
3331 /* If the demangling succeeded, great! Print out the
3332 demangled version. */
3333 if (STATUS_NO_ERROR (status))
3334 fputs (dyn_string_buf (demangled), stdout);
3335 /* Abort on allocation failures. */
3336 else if (status == STATUS_ALLOCATION_FAILED)
3338 fprintf (stderr, "Memory allocation failed.\n");
3341 /* Otherwise, it might not have been a mangled name. Just
3342 print out the original text. */
3344 fputs (dyn_string_buf (mangled), stdout);
3346 /* If we haven't hit EOF yet, we've read one character that
3347 can't occur in a mangled name, so print it out. */
3351 /* Clear the candidate mangled name, to start afresh next
3352 time we hit a `_Z'. */
3353 dyn_string_clear (mangled);
3356 dyn_string_delete (mangled);
3357 dyn_string_delete (demangled);
3360 /* Demangle command line arguments. */
3362 dyn_string_t result = dyn_string_new (0);
3364 /* Loop over command line arguments. */
3365 for (i = optind; i < argc; ++i)
3367 /* Attempt to demangle. */
3368 status = cp_demangle (argv[i], result);
3370 /* If it worked, print the demangled name. */
3371 if (STATUS_NO_ERROR (status))
3372 printf ("%s\n", dyn_string_buf (result));
3373 /* Abort on allocaiton failures. */
3374 if (status == STATUS_ALLOCATION_FAILED)
3376 fprintf (stderr, "Memory allocaiton failed.\n");
3379 /* If not, print the error message to stderr instead. */
3381 fprintf (stderr, "%s\n", status);
3383 dyn_string_delete (result);
3389 #endif /* STANDALONE_DEMANGLER */