1 /* Demangler for IA64 / g++ standard C++ ABI.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This file is part of GNU CC.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /* This file implements demangling of C++ names mangled according to
23 the IA64 / g++ standard C++ ABI. Use the cp_demangle function to
24 demangle a mangled name, or compile with the preprocessor macro
25 STANDALONE_DEMANGLER defined to create a demangling filter
26 executable (functionally similar to c++filt, but includes this
33 #include <sys/types.h>
46 #include "libiberty.h"
47 #include "dyn-string.h"
50 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
51 and other debugging output, will be generated. */
52 #ifdef CP_DEMANGLE_DEBUG
53 #define DEMANGLE_TRACE(PRODUCTION, DM) \
54 fprintf (stderr, " -> %-24s at position %3d\n", \
55 (PRODUCTION), current_position (DM));
57 #define DEMANGLE_TRACE(PRODUCTION, DM)
60 /* Don't include <ctype.h>, to prevent additional unresolved symbols
61 from being dragged into the C++ runtime library. */
62 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
63 #define IS_ALPHA(CHAR) \
64 (((CHAR) >= 'a' && (CHAR) <= 'z') \
65 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
67 /* The prefix prepended by GCC to an identifier represnting the
68 anonymous namespace. */
69 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
71 /* If flag_verbose is zero, some simplifications will be made to the
72 output to make it easier to read and supress details that are
73 generally not of interest to the average C++ programmer.
74 Otherwise, the demangled representation will attempt to convey as
75 much information as the mangled form. */
76 static int flag_verbose;
78 /* If flag_strict is non-zero, demangle strictly according to the
79 specification -- don't demangle special g++ manglings. */
80 static int flag_strict;
82 /* String_list_t is an extended form of dyn_string_t which provides a link
83 field. A string_list_t may safely be cast to and used as a
86 struct string_list_def
88 struct dyn_string string;
89 struct string_list_def *next;
92 typedef struct string_list_def *string_list_t;
94 /* Data structure representing a potential substitution. */
96 struct substitution_def
98 /* The demangled text of the substitution. */
101 /* Whether this substitution represents a template item. */
105 /* Data structure representing a template argument list. */
107 struct template_arg_list_def
109 /* The next (lower) template argument list in the stack of currently
110 active template arguments. */
111 struct template_arg_list_def *next;
113 /* The first element in the list of template arguments in
114 left-to-right order. */
115 string_list_t first_argument;
117 /* The last element in the arguments lists. */
118 string_list_t last_argument;
121 typedef struct template_arg_list_def *template_arg_list_t;
123 /* Data structure to maintain the state of the current demangling. */
125 struct demangling_def
127 /* The full mangled name being mangled. */
130 /* Pointer into name at the current position. */
133 /* Stack for strings containing demangled result generated so far.
134 Text is emitted to the topmost (first) string. */
135 string_list_t result;
137 /* The number of presently available substitutions. */
138 int num_substitutions;
140 /* The allocated size of the substitutions array. */
141 int substitutions_allocated;
143 /* An array of available substitutions. The number of elements in
144 the array is given by num_substitions, and the allocated array
145 size in substitutions_size.
147 The most recent substition is at the end, so
149 - `S_' corresponds to substititutions[num_substitutions - 1]
150 - `S0_' corresponds to substititutions[num_substitutions - 2]
153 struct substitution_def *substitutions;
155 /* The stack of template argument lists. */
156 template_arg_list_t template_arg_lists;
158 /* The most recently demangled source-name. */
159 dyn_string_t last_source_name;
162 typedef struct demangling_def *demangling_t;
164 /* This type is the standard return code from most functions. Values
165 other than STATUS_OK contain descriptive messages. */
166 typedef const char *status_t;
168 /* Special values that can be used as a status_t. */
169 #define STATUS_OK NULL
170 #define STATUS_ERROR "Error."
171 #define STATUS_UNIMPLEMENTED "Unimplemented."
172 #define STATUS_INTERNAL_ERROR "Internal error."
174 /* This status code indicates a failure in malloc or realloc. */
175 static const char *const status_allocation_failed = "Allocation failed.";
176 #define STATUS_ALLOCATION_FAILED status_allocation_failed
178 /* Non-zero if STATUS indicates that no error has occurred. */
179 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
181 /* Evaluate EXPR, which must produce a status_t. If the status code
182 indicates an error, return from the current function with that
184 #define RETURN_IF_ERROR(EXPR) \
188 if (!STATUS_NO_ERROR (s)) \
193 static status_t int_to_dyn_string
194 PARAMS ((int, dyn_string_t));
195 static string_list_t string_list_new
197 static void string_list_delete
198 PARAMS ((string_list_t));
199 static status_t result_add_separated_char
200 PARAMS ((demangling_t, int));
201 static status_t result_push
202 PARAMS ((demangling_t));
203 static string_list_t result_pop
204 PARAMS ((demangling_t));
205 static int substitution_start
206 PARAMS ((demangling_t));
207 static status_t substitution_add
208 PARAMS ((demangling_t, int, int));
209 static dyn_string_t substitution_get
210 PARAMS ((demangling_t, int, int *));
211 #ifdef CP_DEMANGLE_DEBUG
212 static void substitutions_print
213 PARAMS ((demangling_t, FILE *));
215 static template_arg_list_t template_arg_list_new
217 static void template_arg_list_delete
218 PARAMS ((template_arg_list_t));
219 static void template_arg_list_add_arg
220 PARAMS ((template_arg_list_t, string_list_t));
221 static string_list_t template_arg_list_get_arg
222 PARAMS ((template_arg_list_t, int));
223 static void push_template_arg_list
224 PARAMS ((demangling_t, template_arg_list_t));
225 static void pop_to_template_arg_list
226 PARAMS ((demangling_t, template_arg_list_t));
227 #ifdef CP_DEMANGLE_DEBUG
228 static void template_arg_list_print
229 PARAMS ((template_arg_list_t, FILE *));
231 static template_arg_list_t current_template_arg_list
232 PARAMS ((demangling_t));
233 static demangling_t demangling_new
234 PARAMS ((const char *));
235 static void demangling_delete
236 PARAMS ((demangling_t));
238 /* The last character of DS. Warning: DS is evaluated twice. */
239 #define dyn_string_last_char(DS) \
240 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
242 /* Append a space character (` ') to DS if it does not already end
243 with one. Evaluates to 1 on success, or 0 on allocation failure. */
244 #define dyn_string_append_space(DS) \
245 ((dyn_string_length (DS) > 0 \
246 && dyn_string_last_char (DS) != ' ') \
247 ? dyn_string_append_char ((DS), ' ') \
250 /* Returns the index of the current position in the mangled name. */
251 #define current_position(DM) ((DM)->next - (DM)->name)
253 /* Returns the character at the current position of the mangled name. */
254 #define peek_char(DM) (*((DM)->next))
256 /* Returns the character one past the current position of the mangled
258 #define peek_char_next(DM) \
259 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
261 /* Returns the character at the current position, and advances the
262 current position to the next character. */
263 #define next_char(DM) (*((DM)->next)++)
265 /* Returns non-zero if the current position is the end of the mangled
266 name, i.e. one past the last character. */
267 #define end_of_name_p(DM) (peek_char (DM) == '\0')
269 /* Advances the current position by one character. */
270 #define advance_char(DM) (++(DM)->next)
272 /* Returns the string containing the current demangled result. */
273 #define result_string(DM) (&(DM)->result->string)
275 /* Appends a dyn_string_t to the demangled result. */
276 #define result_append_string(DM, STRING) \
277 (dyn_string_append (&(DM)->result->string, (STRING)) \
278 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
280 /* Appends NUL-terminated string CSTR to the demangled result. */
281 #define result_append(DM, CSTR) \
282 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
283 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
285 /* Appends character CHAR to the demangled result. */
286 #define result_append_char(DM, CHAR) \
287 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \
288 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
290 /* Inserts a dyn_string_t to the demangled result at position POS. */
291 #define result_insert_string(DM, POS, STRING) \
292 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
293 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
295 /* Inserts NUL-terminated string CSTR to the demangled result at
297 #define result_insert(DM, POS, CSTR) \
298 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
299 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
301 /* Inserts character CHAR to the demangled result at position POS. */
302 #define result_insert_char(DM, POS, CHAR) \
303 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
304 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
306 /* The length of the current demangled result. */
307 #define result_length(DM) \
308 dyn_string_length (&(DM)->result->string)
310 /* Appends a space to the demangled result if the last character is
312 #define result_append_space(DM) \
313 (dyn_string_append_space (&(DM)->result->string) \
314 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
316 /* Appends a (less-than, greater-than) character to the result in DM
317 to (open, close) a template argument or parameter list. Appends a
318 space first if necessary to prevent spurious elision of angle
319 brackets with the previous character. */
320 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
321 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
323 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
324 success. On failure, deletes DS and returns an error code. */
327 int_to_dyn_string (value, ds)
334 /* Handle zero up front. */
337 if (!dyn_string_append_char (ds, '0'))
338 return STATUS_ALLOCATION_FAILED;
342 /* For negative numbers, emit a minus sign. */
345 if (!dyn_string_append_char (ds, '-'))
346 return STATUS_ALLOCATION_FAILED;
350 /* Find the power of 10 of the first digit. */
358 /* Write the digits. */
361 int digit = value / mask;
363 if (!dyn_string_append_char (ds, '0' + digit))
364 return STATUS_ALLOCATION_FAILED;
366 value -= digit * mask;
373 /* Creates a new string list node. The contents of the string are
374 empty, but the initial buffer allocation is LENGTH. The string
375 list node should be deleted with string_list_delete. Returns NULL
376 if allocation fails. */
379 string_list_new (length)
382 string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
385 if (!dyn_string_init ((dyn_string_t) s, length))
390 /* Deletes the entire string list starting at NODE. */
393 string_list_delete (node)
398 string_list_t next = node->next;
404 /* Appends CHARACTER to the demangled result. If the current trailing
405 character of the result is CHARACTER, a space is inserted first. */
408 result_add_separated_char (dm, character)
412 dyn_string_t s = &dm->result->string;
414 /* Add a space if the last character is already a closing angle
415 bracket, so that a nested template arg list doesn't look like
416 it's closed with a right-shift operator. */
417 if (dyn_string_last_char (s) == character)
419 if (!dyn_string_append_char (s, ' '))
420 return STATUS_ALLOCATION_FAILED;
423 /* Add closing angle brackets. */
424 if (!dyn_string_append_char (s, character))
425 return STATUS_ALLOCATION_FAILED;
430 /* Allocates and pushes a new string onto the demangled results stack
431 for DM. Subsequent demangling with DM will emit to the new string.
432 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
433 allocation failure. */
439 string_list_t new_string = string_list_new (0);
440 if (new_string == NULL)
441 /* Allocation failed. */
442 return STATUS_ALLOCATION_FAILED;
444 /* Link the new string to the front of the list of result strings. */
445 new_string->next = (string_list_t) dm->result;
446 dm->result = new_string;
450 /* Removes and returns the topmost element on the demangled results
451 stack for DM. The caller assumes ownership for the returned
458 string_list_t top = dm->result;
459 dm->result = top->next;
463 /* Returns the start position of a fragment of the demangled result
464 that will be a substitution candidate. Should be called at the
465 start of productions that can add substitutions. */
468 substitution_start (dm)
471 return result_length (dm);
474 /* Adds the suffix of the current demangled result of DM starting at
475 START_POSITION as a potential substitution. If TEMPLATE_P is
476 non-zero, this potential substitution is a template-id. */
479 substitution_add (dm, start_position, template_p)
484 dyn_string_t result = result_string (dm);
485 dyn_string_t substitution = dyn_string_new (0);
488 if (substitution == NULL)
489 return STATUS_ALLOCATION_FAILED;
491 /* Extract the substring of the current demangling result that
492 represents the subsitution candidate. */
493 if (!dyn_string_substring (substitution,
494 result, start_position, result_length (dm)))
496 dyn_string_delete (substitution);
497 return STATUS_ALLOCATION_FAILED;
500 /* If there's no room for the new entry, grow the array. */
501 if (dm->substitutions_allocated == dm->num_substitutions)
503 size_t new_array_size;
504 if (dm->substitutions_allocated > 0)
505 dm->substitutions_allocated *= 2;
507 dm->substitutions_allocated = 2;
509 sizeof (struct substitution_def) * dm->substitutions_allocated;
511 dm->substitutions = (struct substitution_def *)
512 realloc (dm->substitutions, new_array_size);
513 if (dm->substitutions == NULL)
514 /* Realloc failed. */
516 dyn_string_delete (substitution);
517 return STATUS_ALLOCATION_FAILED;
521 /* Add the substitution to the array. */
522 i = dm->num_substitutions++;
523 dm->substitutions[i].text = substitution;
524 dm->substitutions[i].template_p = template_p;
526 #ifdef CP_DEMANGLE_DEBUG
527 substitutions_print (dm, stderr);
533 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
534 non-zero if the substitution is a template-id, zero otherwise.
535 N is numbered from zero. DM retains ownership of the returned
536 string. If N is negative, or equal to or greater than the current
537 number of substitution candidates, returns NULL. */
540 substitution_get (dm, n, template_p)
545 struct substitution_def *sub;
547 /* Make sure N is in the valid range. */
548 if (n < 0 || n >= dm->num_substitutions)
551 sub = &(dm->substitutions[n]);
552 *template_p = sub->template_p;
556 #ifdef CP_DEMANGLE_DEBUG
557 /* Debugging routine to print the current substitutions to FP. */
560 substitutions_print (dm, fp)
565 int num = dm->num_substitutions;
567 fprintf (fp, "SUBSTITUTIONS:\n");
568 for (seq_id = -1; seq_id < num - 1; ++seq_id)
571 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
574 fprintf (fp, " S_ ");
576 fprintf (fp, " S%d_", seq_id);
577 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
581 #endif /* CP_DEMANGLE_DEBUG */
583 /* Creates a new template argument list. Returns NULL if allocation
586 static template_arg_list_t
587 template_arg_list_new ()
589 template_arg_list_t new_list =
590 (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
591 if (new_list == NULL)
593 /* Initialize the new list to have no arguments. */
594 new_list->first_argument = NULL;
595 new_list->last_argument = NULL;
596 /* Return the new list. */
600 /* Deletes a template argument list and the template arguments it
604 template_arg_list_delete (list)
605 template_arg_list_t list;
607 /* If there are any arguments on LIST, delete them. */
608 if (list->first_argument != NULL)
609 string_list_delete (list->first_argument);
614 /* Adds ARG to the template argument list ARG_LIST. */
617 template_arg_list_add_arg (arg_list, arg)
618 template_arg_list_t arg_list;
621 if (arg_list->first_argument == NULL)
622 /* If there were no arguments before, ARG is the first one. */
623 arg_list->first_argument = arg;
625 /* Make ARG the last argument on the list. */
626 arg_list->last_argument->next = arg;
627 /* Make ARG the last on the list. */
628 arg_list->last_argument = arg;
632 /* Returns the template arugment at position INDEX in template
633 argument list ARG_LIST. */
636 template_arg_list_get_arg (arg_list, index)
637 template_arg_list_t arg_list;
640 string_list_t arg = arg_list->first_argument;
641 /* Scan down the list of arguments to find the one at position
647 /* Ran out of arguments before INDEX hit zero. That's an
651 /* Return the argument at position INDEX. */
655 /* Pushes ARG_LIST onto the top of the template argument list stack. */
658 push_template_arg_list (dm, arg_list)
660 template_arg_list_t arg_list;
662 arg_list->next = dm->template_arg_lists;
663 dm->template_arg_lists = arg_list;
664 #ifdef CP_DEMANGLE_DEBUG
665 fprintf (stderr, " ** pushing template arg list\n");
666 template_arg_list_print (arg_list, stderr);
670 /* Pops and deletes elements on the template argument list stack until
671 arg_list is the topmost element. If arg_list is NULL, all elements
672 are popped and deleted. */
675 pop_to_template_arg_list (dm, arg_list)
677 template_arg_list_t arg_list;
679 while (dm->template_arg_lists != arg_list)
681 template_arg_list_t top = dm->template_arg_lists;
682 /* Disconnect the topmost element from the list. */
683 dm->template_arg_lists = top->next;
684 /* Delete the popped element. */
685 template_arg_list_delete (top);
686 #ifdef CP_DEMANGLE_DEBUG
687 fprintf (stderr, " ** removing template arg list\n");
692 #ifdef CP_DEMANGLE_DEBUG
694 /* Prints the contents of ARG_LIST to FP. */
697 template_arg_list_print (arg_list, fp)
698 template_arg_list_t arg_list;
704 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
705 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
708 fprintf (fp, " T_ : ");
710 fprintf (fp, " T%d_ : ", index);
712 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
716 #endif /* CP_DEMANGLE_DEBUG */
718 /* Returns the topmost element on the stack of template argument
719 lists. If there is no list of template arguments, returns NULL. */
721 static template_arg_list_t
722 current_template_arg_list (dm)
725 return dm->template_arg_lists;
728 /* Allocates a demangling_t object for demangling mangled NAME. A new
729 result must be pushed before the returned object can be used.
730 Returns NULL if allocation fails. */
733 demangling_new (name)
737 dm = (demangling_t) malloc (sizeof (struct demangling_def));
744 dm->num_substitutions = 0;
745 dm->substitutions_allocated = 10;
746 dm->template_arg_lists = NULL;
747 dm->last_source_name = dyn_string_new (0);
748 if (dm->last_source_name == NULL)
750 dm->substitutions = (struct substitution_def *)
751 malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
752 if (dm->substitutions == NULL)
754 dyn_string_delete (dm->last_source_name);
761 /* Deallocates a demangling_t object and all memory associated with
765 demangling_delete (dm)
769 template_arg_list_t arg_list = dm->template_arg_lists;
771 /* Delete the stack of template argument lists. */
772 while (arg_list != NULL)
774 template_arg_list_t next = arg_list->next;
775 template_arg_list_delete (arg_list);
778 /* Delete the list of substitutions. */
779 for (i = dm->num_substitutions; --i >= 0; )
780 dyn_string_delete (dm->substitutions[i].text);
781 free (dm->substitutions);
782 /* Delete the demangled result. */
783 string_list_delete (dm->result);
784 /* Delete the stored identifier name. */
785 dyn_string_delete (dm->last_source_name);
786 /* Delete the context object itself. */
790 /* These functions demangle an alternative of the corresponding
791 production in the mangling spec. The first argument of each is a
792 demangling context structure for the current demangling
793 operation. Most emit demangled text directly to the topmost result
794 string on the result string stack in the demangling context
797 static status_t demangle_char
798 PARAMS ((demangling_t, int));
799 static status_t demangle_mangled_name
800 PARAMS ((demangling_t));
801 static status_t demangle_encoding
802 PARAMS ((demangling_t));
803 static status_t demangle_name
804 PARAMS ((demangling_t, int *));
805 static status_t demangle_nested_name
806 PARAMS ((demangling_t, int *));
807 static status_t demangle_prefix
808 PARAMS ((demangling_t, int *));
809 static status_t demangle_unqualified_name
810 PARAMS ((demangling_t, int *));
811 static status_t demangle_source_name
812 PARAMS ((demangling_t));
813 static status_t demangle_number
814 PARAMS ((demangling_t, int *, int, int));
815 static status_t demangle_number_literally
816 PARAMS ((demangling_t, dyn_string_t, int, int));
817 static status_t demangle_identifier
818 PARAMS ((demangling_t, int, dyn_string_t));
819 static status_t demangle_operator_name
820 PARAMS ((demangling_t, int, int *));
821 static status_t demangle_nv_offset
822 PARAMS ((demangling_t));
823 static status_t demangle_v_offset
824 PARAMS ((demangling_t));
825 static status_t demangle_call_offset
826 PARAMS ((demangling_t));
827 static status_t demangle_special_name
828 PARAMS ((demangling_t));
829 static status_t demangle_ctor_dtor_name
830 PARAMS ((demangling_t));
831 static status_t demangle_type_ptr
832 PARAMS ((demangling_t, int *, int));
833 static status_t demangle_type
834 PARAMS ((demangling_t));
835 static status_t demangle_CV_qualifiers
836 PARAMS ((demangling_t, dyn_string_t));
837 static status_t demangle_builtin_type
838 PARAMS ((demangling_t));
839 static status_t demangle_function_type
840 PARAMS ((demangling_t, int *));
841 static status_t demangle_bare_function_type
842 PARAMS ((demangling_t, int *));
843 static status_t demangle_class_enum_type
844 PARAMS ((demangling_t, int *));
845 static status_t demangle_array_type
846 PARAMS ((demangling_t));
847 static status_t demangle_template_param
848 PARAMS ((demangling_t));
849 static status_t demangle_template_args
850 PARAMS ((demangling_t));
851 static status_t demangle_literal
852 PARAMS ((demangling_t));
853 static status_t demangle_template_arg
854 PARAMS ((demangling_t));
855 static status_t demangle_expression
856 PARAMS ((demangling_t));
857 static status_t demangle_scope_expression
858 PARAMS ((demangling_t));
859 static status_t demangle_expr_primary
860 PARAMS ((demangling_t));
861 static status_t demangle_substitution
862 PARAMS ((demangling_t, int *));
863 static status_t demangle_local_name
864 PARAMS ((demangling_t));
865 static status_t demangle_discriminator
866 PARAMS ((demangling_t, int));
867 static status_t cp_demangle
868 PARAMS ((const char *, dyn_string_t));
870 static status_t cp_demangle_type
871 PARAMS ((const char*, dyn_string_t));
874 /* When passed to demangle_bare_function_type, indicates that the
875 function's return type is not encoded before its parameter types. */
876 #define BFT_NO_RETURN_TYPE NULL
878 /* Check that the next character is C. If so, consume it. If not,
882 demangle_char (dm, c)
886 static char *error_message = NULL;
888 if (peek_char (dm) == c)
895 if (error_message == NULL)
896 error_message = strdup ("Expected ?");
897 error_message[9] = c;
898 return error_message;
902 /* Demangles and emits a <mangled-name>.
904 <mangled-name> ::= _Z <encoding> */
907 demangle_mangled_name (dm)
910 DEMANGLE_TRACE ("mangled-name", dm);
911 RETURN_IF_ERROR (demangle_char (dm, '_'));
912 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
913 RETURN_IF_ERROR (demangle_encoding (dm));
917 /* Demangles and emits an <encoding>.
919 <encoding> ::= <function name> <bare-function-type>
921 ::= <special-name> */
924 demangle_encoding (dm)
927 int encode_return_type;
929 template_arg_list_t old_arg_list = current_template_arg_list (dm);
930 char peek = peek_char (dm);
932 DEMANGLE_TRACE ("encoding", dm);
934 /* Remember where the name starts. If it turns out to be a template
935 function, we'll have to insert the return type here. */
936 start_position = result_length (dm);
938 if (peek == 'G' || peek == 'T')
939 RETURN_IF_ERROR (demangle_special_name (dm));
942 /* Now demangle the name. */
943 RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
945 /* If there's anything left, the name was a function name, with
946 maybe its return type, and its parameters types, following. */
947 if (!end_of_name_p (dm)
948 && peek_char (dm) != 'E')
950 if (encode_return_type)
951 /* Template functions have their return type encoded. The
952 return type should be inserted at start_position. */
954 (demangle_bare_function_type (dm, &start_position));
956 /* Non-template functions don't have their return type
959 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
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, encode_return_type)
987 int *encode_return_type;
989 int start = substitution_start (dm);
990 char peek = peek_char (dm);
991 int is_std_substitution = 0;
993 /* Generally, the return type is encoded if the function is a
994 template-id, and suppressed otherwise. There are a few cases,
995 though, in which the return type is not encoded even for a
996 templated function. In these cases, this flag is set. */
997 int suppress_return_type = 0;
999 DEMANGLE_TRACE ("name", dm);
1004 /* This is a <nested-name>. */
1005 RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type));
1009 RETURN_IF_ERROR (demangle_local_name (dm));
1010 *encode_return_type = 0;
1014 /* The `St' substitution allows a name nested in std:: to appear
1015 without being enclosed in a nested name. */
1016 if (peek_char_next (dm) == 't')
1018 (void) next_char (dm);
1019 (void) next_char (dm);
1020 RETURN_IF_ERROR (result_append (dm, "std::"));
1022 (demangle_unqualified_name (dm, &suppress_return_type));
1023 is_std_substitution = 1;
1026 RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1027 /* Check if a template argument list immediately follows.
1028 If so, then we just demangled an <unqualified-template-name>. */
1029 if (peek_char (dm) == 'I')
1031 /* A template name of the form std::<unqualified-name> is a
1032 substitution candidate. */
1033 if (is_std_substitution)
1034 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1035 /* Demangle the <template-args> here. */
1036 RETURN_IF_ERROR (demangle_template_args (dm));
1037 *encode_return_type = !suppress_return_type;
1040 *encode_return_type = 0;
1045 /* This is an <unscoped-name> or <unscoped-template-name>. */
1046 RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type));
1048 /* If the <unqualified-name> is followed by template args, this
1049 is an <unscoped-template-name>. */
1050 if (peek_char (dm) == 'I')
1052 /* Add a substitution for the unqualified template name. */
1053 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1055 RETURN_IF_ERROR (demangle_template_args (dm));
1056 *encode_return_type = !suppress_return_type;
1059 *encode_return_type = 0;
1067 /* Demangles and emits a <nested-name>.
1069 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1072 demangle_nested_name (dm, encode_return_type)
1074 int *encode_return_type;
1078 DEMANGLE_TRACE ("nested-name", dm);
1080 RETURN_IF_ERROR (demangle_char (dm, 'N'));
1082 peek = peek_char (dm);
1083 if (peek == 'r' || peek == 'V' || peek == 'K')
1087 /* Snarf up and emit CV qualifiers. */
1088 dyn_string_t cv_qualifiers = dyn_string_new (24);
1089 if (cv_qualifiers == NULL)
1090 return STATUS_ALLOCATION_FAILED;
1092 demangle_CV_qualifiers (dm, cv_qualifiers);
1093 status = result_append_string (dm, cv_qualifiers);
1094 dyn_string_delete (cv_qualifiers);
1095 RETURN_IF_ERROR (status);
1096 RETURN_IF_ERROR (result_append_space (dm));
1099 RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
1100 /* No need to demangle the final <unqualified-name>; demangle_prefix
1102 RETURN_IF_ERROR (demangle_char (dm, 'E'));
1107 /* Demangles and emits a <prefix>.
1109 <prefix> ::= <prefix> <unqualified-name>
1110 ::= <template-prefix> <template-args>
1114 <template-prefix> ::= <prefix>
1115 ::= <substitution> */
1118 demangle_prefix (dm, encode_return_type)
1120 int *encode_return_type;
1122 int start = substitution_start (dm);
1125 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1126 After <template-args>, it is set to non-zero; after everything
1127 else it is set to zero. */
1129 /* Generally, the return type is encoded if the function is a
1130 template-id, and suppressed otherwise. There are a few cases,
1131 though, in which the return type is not encoded even for a
1132 templated function. In these cases, this flag is set. */
1133 int suppress_return_type = 0;
1135 DEMANGLE_TRACE ("prefix", dm);
1141 if (end_of_name_p (dm))
1142 return "Unexpected end of name in <compound-name>.";
1144 peek = peek_char (dm);
1146 /* We'll initialize suppress_return_type to false, and set it to true
1147 if we end up demangling a constructor name. However, make
1148 sure we're not actually about to demangle template arguments
1149 -- if so, this is the <template-args> following a
1150 <template-prefix>, so we'll want the previous flag value
1153 suppress_return_type = 0;
1155 if (IS_DIGIT ((unsigned char) peek)
1156 || (peek >= 'a' && peek <= 'z')
1157 || peek == 'C' || peek == 'D'
1160 /* We have another level of scope qualification. */
1162 RETURN_IF_ERROR (result_append (dm, "::"));
1167 /* The substitution determines whether this is a
1169 RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1172 /* It's just a name. */
1174 (demangle_unqualified_name (dm, &suppress_return_type));
1175 *encode_return_type = 0;
1178 else if (peek == 'Z')
1179 RETURN_IF_ERROR (demangle_local_name (dm));
1180 else if (peek == 'I')
1182 RETURN_IF_ERROR (demangle_template_args (dm));
1184 /* Now we want to indicate to the caller that we've
1185 demangled template arguments, thus the prefix was a
1186 <template-prefix>. That's so that the caller knows to
1187 demangle the function's return type, if this turns out to
1188 be a function name. But, if it's a member template
1189 constructor or a templated conversion operator, report it
1190 as untemplated. Those never get encoded return types. */
1191 *encode_return_type = !suppress_return_type;
1193 else if (peek == 'E')
1197 return "Unexpected character in <compound-name>.";
1200 && peek_char (dm) != 'E')
1201 /* Add a new substitution for the prefix thus far. */
1202 RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type));
1206 /* Demangles and emits an <unqualified-name>. If this
1207 <unqualified-name> is for a special function type that should never
1208 have its return type encoded (particularly, a constructor or
1209 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1212 <unqualified-name> ::= <operator-name>
1214 ::= <source-name> */
1217 demangle_unqualified_name (dm, suppress_return_type)
1219 int *suppress_return_type;
1221 char peek = peek_char (dm);
1223 DEMANGLE_TRACE ("unqualified-name", dm);
1225 /* By default, don't force suppression of the return type (though
1226 non-template functions still don't get a return type encoded). */
1227 *suppress_return_type = 0;
1229 if (IS_DIGIT ((unsigned char) peek))
1230 RETURN_IF_ERROR (demangle_source_name (dm));
1231 else if (peek >= 'a' && peek <= 'z')
1235 /* Conversion operators never have a return type encoded. */
1236 if (peek == 'c' && peek_char_next (dm) == 'v')
1237 *suppress_return_type = 1;
1239 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1241 else if (peek == 'C' || peek == 'D')
1243 /* Constructors never have a return type encoded. */
1245 *suppress_return_type = 1;
1247 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1250 return "Unexpected character in <unqualified-name>.";
1255 /* Demangles and emits <source-name>.
1257 <source-name> ::= <length number> <identifier> */
1260 demangle_source_name (dm)
1265 DEMANGLE_TRACE ("source-name", dm);
1267 /* Decode the length of the identifier. */
1268 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1270 return "Zero length in <source-name>.";
1272 /* Now the identifier itself. It's placed into last_source_name,
1273 where it can be used to build a constructor or destructor name. */
1274 RETURN_IF_ERROR (demangle_identifier (dm, length,
1275 dm->last_source_name));
1278 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1283 /* Demangles a number, either a <number> or a <positive-number> at the
1284 current position, consuming all consecutive digit characters. Sets
1285 *VALUE to the resulting numberand returns STATUS_OK. The number is
1286 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1287 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1289 <number> ::= [n] <positive-number>
1291 <positive-number> ::= <decimal integer> */
1294 demangle_number (dm, value, base, is_signed)
1300 dyn_string_t number = dyn_string_new (10);
1302 DEMANGLE_TRACE ("number", dm);
1305 return STATUS_ALLOCATION_FAILED;
1307 demangle_number_literally (dm, number, base, is_signed);
1308 *value = strtol (dyn_string_buf (number), NULL, base);
1309 dyn_string_delete (number);
1314 /* Demangles a number at the current position. The digits (and minus
1315 sign, if present) that make up the number are appended to STR.
1316 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1317 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1318 accepted. Does not consume a trailing underscore or other
1319 terminating character. */
1322 demangle_number_literally (dm, str, base, is_signed)
1328 DEMANGLE_TRACE ("number*", dm);
1330 if (base != 10 && base != 36)
1331 return STATUS_INTERNAL_ERROR;
1333 /* An `n' denotes a negative number. */
1334 if (is_signed && peek_char (dm) == 'n')
1336 /* Skip past the n. */
1338 /* The normal way to write a negative number is with a minus
1340 if (!dyn_string_append_char (str, '-'))
1341 return STATUS_ALLOCATION_FAILED;
1344 /* Loop until we hit a non-digit. */
1347 char peek = peek_char (dm);
1348 if (IS_DIGIT ((unsigned char) peek)
1349 || (base == 36 && peek >= 'A' && peek <= 'Z'))
1351 /* Accumulate digits. */
1352 if (!dyn_string_append_char (str, next_char (dm)))
1353 return STATUS_ALLOCATION_FAILED;
1356 /* Not a digit? All done. */
1363 /* Demangles an identifier at the current position of LENGTH
1364 characters and places it in IDENTIFIER. */
1367 demangle_identifier (dm, length, identifier)
1370 dyn_string_t identifier;
1372 DEMANGLE_TRACE ("identifier", dm);
1374 dyn_string_clear (identifier);
1375 if (!dyn_string_resize (identifier, length))
1376 return STATUS_ALLOCATION_FAILED;
1378 while (length-- > 0)
1380 if (end_of_name_p (dm))
1381 return "Unexpected end of name in <identifier>.";
1382 if (!dyn_string_append_char (identifier, next_char (dm)))
1383 return STATUS_ALLOCATION_FAILED;
1386 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1387 followed by the source file name and some random characters.
1388 Unless we're in strict mode, decipher these names appropriately. */
1391 char *name = dyn_string_buf (identifier);
1392 int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
1394 /* Compare the first, fixed part. */
1395 if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
1397 name += prefix_length;
1398 /* The next character might be a period, an underscore, or
1399 dollar sign, depending on the target architecture's
1400 assembler's capabilities. After that comes an `N'. */
1401 if ((*name == '.' || *name == '_' || *name == '$')
1402 && *(name + 1) == 'N')
1403 /* This looks like the anonymous namespace identifier.
1404 Replace it with something comprehensible. */
1405 dyn_string_copy_cstr (identifier, "(anonymous namespace)");
1412 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1413 the short form is emitted; otherwise the full source form
1414 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1415 operands that the operator takes.
1466 ::= cv <type> # cast
1467 ::= v [0-9] <source-name> # vendor extended operator */
1470 demangle_operator_name (dm, short_name, num_args)
1475 struct operator_code
1477 /* The mangled code for this operator. */
1479 /* The source name of this operator. */
1481 /* The number of arguments this operator takes. */
1485 static const struct operator_code operators[] =
1496 { "da", " delete[]", 1 },
1498 { "dl", " delete" , 1 },
1506 { "lS", "<<=" , 2 },
1515 { "na", " new[]" , 1 },
1519 { "nw", " new" , 1 },
1525 { "pm", "->*" , 2 },
1531 { "rS", ">>=" , 2 },
1534 { "sz", " sizeof" , 1 }
1537 const int num_operators =
1538 sizeof (operators) / sizeof (struct operator_code);
1540 int c0 = next_char (dm);
1541 int c1 = next_char (dm);
1542 const struct operator_code* p1 = operators;
1543 const struct operator_code* p2 = operators + num_operators;
1545 DEMANGLE_TRACE ("operator-name", dm);
1547 /* Is this a vendor-extended operator? */
1548 if (c0 == 'v' && IS_DIGIT (c1))
1550 RETURN_IF_ERROR (result_append (dm, "operator "));
1551 RETURN_IF_ERROR (demangle_source_name (dm));
1556 /* Is this a conversion operator? */
1557 if (c0 == 'c' && c1 == 'v')
1559 RETURN_IF_ERROR (result_append (dm, "operator "));
1560 /* Demangle the converted-to type. */
1561 RETURN_IF_ERROR (demangle_type (dm));
1566 /* Perform a binary search for the operator code. */
1569 const struct operator_code* p = p1 + (p2 - p1) / 2;
1570 char match0 = p->code[0];
1571 char match1 = p->code[1];
1573 if (c0 == match0 && c1 == match1)
1577 RETURN_IF_ERROR (result_append (dm, "operator"));
1578 RETURN_IF_ERROR (result_append (dm, p->name));
1579 *num_args = p->num_args;
1585 /* Couldn't find it. */
1586 return "Unknown code in <operator-name>.";
1589 if (c0 < match0 || (c0 == match0 && c1 < match1))
1596 /* Demangles and omits an <nv-offset>.
1598 <nv-offset> ::= <offset number> # non-virtual base override */
1601 demangle_nv_offset (dm)
1604 dyn_string_t number;
1605 status_t status = STATUS_OK;
1607 DEMANGLE_TRACE ("h-offset", dm);
1609 /* Demangle the offset. */
1610 number = dyn_string_new (4);
1612 return STATUS_ALLOCATION_FAILED;
1613 demangle_number_literally (dm, number, 10, 1);
1615 /* Don't display the offset unless in verbose mode. */
1618 status = result_append (dm, " [nv:");
1619 if (STATUS_NO_ERROR (status))
1620 status = result_append_string (dm, number);
1621 if (STATUS_NO_ERROR (status))
1622 status = result_append_char (dm, ']');
1626 dyn_string_delete (number);
1627 RETURN_IF_ERROR (status);
1631 /* Demangles and emits a <v-offset>.
1633 <v-offset> ::= <offset number> _ <virtual offset number>
1634 # virtual base override, with vcall offset */
1637 demangle_v_offset (dm)
1640 dyn_string_t number;
1641 status_t status = STATUS_OK;
1643 DEMANGLE_TRACE ("v-offset", dm);
1645 /* Demangle the offset. */
1646 number = dyn_string_new (4);
1648 return STATUS_ALLOCATION_FAILED;
1649 demangle_number_literally (dm, number, 10, 1);
1651 /* Don't display the offset unless in verbose mode. */
1654 status = result_append (dm, " [v:");
1655 if (STATUS_NO_ERROR (status))
1656 status = result_append_string (dm, number);
1657 if (STATUS_NO_ERROR (status))
1658 result_append_char (dm, ',');
1660 dyn_string_delete (number);
1661 RETURN_IF_ERROR (status);
1663 /* Demangle the separator. */
1664 RETURN_IF_ERROR (demangle_char (dm, '_'));
1666 /* Demangle the vcall offset. */
1667 number = dyn_string_new (4);
1669 return STATUS_ALLOCATION_FAILED;
1670 demangle_number_literally (dm, number, 10, 1);
1672 /* Don't display the vcall offset unless in verbose mode. */
1675 status = result_append_string (dm, number);
1676 if (STATUS_NO_ERROR (status))
1677 status = result_append_char (dm, ']');
1679 dyn_string_delete (number);
1680 RETURN_IF_ERROR (status);
1685 /* Demangles and emits a <call-offset>.
1687 <call-offset> ::= h <nv-offset> _
1688 ::= v <v-offset> _ */
1691 demangle_call_offset (dm)
1694 DEMANGLE_TRACE ("call-offset", dm);
1696 switch (peek_char (dm))
1700 /* Demangle the offset. */
1701 RETURN_IF_ERROR (demangle_nv_offset (dm));
1702 /* Demangle the separator. */
1703 RETURN_IF_ERROR (demangle_char (dm, '_'));
1708 /* Demangle the offset. */
1709 RETURN_IF_ERROR (demangle_v_offset (dm));
1710 /* Demangle the separator. */
1711 RETURN_IF_ERROR (demangle_char (dm, '_'));
1715 return "Unrecognized <call-offset>.";
1721 /* Demangles and emits a <special-name>.
1723 <special-name> ::= GV <object name> # Guard variable
1724 ::= TV <type> # virtual table
1726 ::= TI <type> # typeinfo structure
1727 ::= TS <type> # typeinfo name
1729 Other relevant productions include thunks:
1731 <special-name> ::= T <call-offset> <base encoding>
1732 # base is the nominal target function of thunk
1734 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1735 # base is the nominal target function of thunk
1736 # first call-offset is 'this' adjustment
1737 # second call-offset is result adjustment
1741 <call-offset> ::= h <nv-offset> _
1744 Also demangles the special g++ manglings,
1746 <special-name> ::= TC <type> <offset number> _ <base type>
1747 # construction vtable
1748 ::= TF <type> # typeinfo function (old ABI only)
1749 ::= TJ <type> # java Class structure */
1752 demangle_special_name (dm)
1755 dyn_string_t number;
1757 char peek = peek_char (dm);
1759 DEMANGLE_TRACE ("special-name", dm);
1763 /* A guard variable name. Consume the G. */
1765 RETURN_IF_ERROR (demangle_char (dm, 'V'));
1766 RETURN_IF_ERROR (result_append (dm, "guard variable for "));
1767 RETURN_IF_ERROR (demangle_name (dm, &unused));
1769 else if (peek == 'T')
1771 status_t status = STATUS_OK;
1773 /* Other C++ implementation miscellania. Consume the T. */
1776 switch (peek_char (dm))
1779 /* Virtual table. */
1781 RETURN_IF_ERROR (result_append (dm, "vtable for "));
1782 RETURN_IF_ERROR (demangle_type (dm));
1786 /* VTT structure. */
1788 RETURN_IF_ERROR (result_append (dm, "VTT for "));
1789 RETURN_IF_ERROR (demangle_type (dm));
1793 /* Typeinfo structure. */
1795 RETURN_IF_ERROR (result_append (dm, "typeinfo for "));
1796 RETURN_IF_ERROR (demangle_type (dm));
1800 /* Typeinfo function. Used only in old ABI with new mangling. */
1802 RETURN_IF_ERROR (result_append (dm, "typeinfo fn for "));
1803 RETURN_IF_ERROR (demangle_type (dm));
1807 /* Character string containing type name, used in typeinfo. */
1809 RETURN_IF_ERROR (result_append (dm, "typeinfo name for "));
1810 RETURN_IF_ERROR (demangle_type (dm));
1814 /* The java Class variable corresponding to a C++ class. */
1816 RETURN_IF_ERROR (result_append (dm, "java Class for "));
1817 RETURN_IF_ERROR (demangle_type (dm));
1821 /* Non-virtual thunk. */
1823 RETURN_IF_ERROR (result_append (dm, "non-virtual thunk"));
1824 RETURN_IF_ERROR (demangle_nv_offset (dm));
1825 /* Demangle the separator. */
1826 RETURN_IF_ERROR (demangle_char (dm, '_'));
1827 /* Demangle and emit the target name and function type. */
1828 RETURN_IF_ERROR (result_append (dm, " to "));
1829 RETURN_IF_ERROR (demangle_encoding (dm));
1833 /* Virtual thunk. */
1835 RETURN_IF_ERROR (result_append (dm, "virtual thunk"));
1836 RETURN_IF_ERROR (demangle_v_offset (dm));
1837 /* Demangle the separator. */
1838 RETURN_IF_ERROR (demangle_char (dm, '_'));
1839 /* Demangle and emit the target function. */
1840 RETURN_IF_ERROR (result_append (dm, " to "));
1841 RETURN_IF_ERROR (demangle_encoding (dm));
1845 /* Covariant return thunk. */
1847 RETURN_IF_ERROR (result_append (dm, "covariant return thunk"));
1848 RETURN_IF_ERROR (demangle_call_offset (dm));
1849 RETURN_IF_ERROR (demangle_call_offset (dm));
1850 /* Demangle and emit the target function. */
1851 RETURN_IF_ERROR (result_append (dm, " to "));
1852 RETURN_IF_ERROR (demangle_encoding (dm));
1856 /* TC is a special g++ mangling for a construction vtable. */
1859 dyn_string_t derived_type;
1862 RETURN_IF_ERROR (result_append (dm, "construction vtable for "));
1864 /* Demangle the derived type off to the side. */
1865 RETURN_IF_ERROR (result_push (dm));
1866 RETURN_IF_ERROR (demangle_type (dm));
1867 derived_type = (dyn_string_t) result_pop (dm);
1869 /* Demangle the offset. */
1870 number = dyn_string_new (4);
1873 dyn_string_delete (derived_type);
1874 return STATUS_ALLOCATION_FAILED;
1876 demangle_number_literally (dm, number, 10, 1);
1877 /* Demangle the underscore separator. */
1878 status = demangle_char (dm, '_');
1880 /* Demangle the base type. */
1881 if (STATUS_NO_ERROR (status))
1882 status = demangle_type (dm);
1884 /* Emit the derived type. */
1885 if (STATUS_NO_ERROR (status))
1886 status = result_append (dm, "-in-");
1887 if (STATUS_NO_ERROR (status))
1888 status = result_append_string (dm, derived_type);
1889 dyn_string_delete (derived_type);
1891 /* Don't display the offset unless in verbose mode. */
1894 status = result_append_char (dm, ' ');
1895 if (STATUS_NO_ERROR (status))
1896 result_append_string (dm, number);
1898 dyn_string_delete (number);
1899 RETURN_IF_ERROR (status);
1902 /* If flag_strict, fall through. */
1905 return "Unrecognized <special-name>.";
1909 return STATUS_ERROR;
1914 /* Demangles and emits a <ctor-dtor-name>.
1917 ::= C1 # complete object (in-charge) ctor
1918 ::= C2 # base object (not-in-charge) ctor
1919 ::= C3 # complete object (in-charge) allocating ctor
1920 ::= D0 # deleting (in-charge) dtor
1921 ::= D1 # complete object (in-charge) dtor
1922 ::= D2 # base object (not-in-charge) dtor */
1925 demangle_ctor_dtor_name (dm)
1928 static const char *const ctor_flavors[] =
1934 static const char *const dtor_flavors[] =
1936 "in-charge deleting",
1942 char peek = peek_char (dm);
1944 DEMANGLE_TRACE ("ctor-dtor-name", dm);
1948 /* A constructor name. Consume the C. */
1950 if (peek_char (dm) < '1' || peek_char (dm) > '3')
1951 return "Unrecognized constructor.";
1952 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1953 /* Print the flavor of the constructor if in verbose mode. */
1954 flavor = next_char (dm) - '1';
1957 RETURN_IF_ERROR (result_append (dm, "["));
1958 RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor]));
1959 RETURN_IF_ERROR (result_append_char (dm, ']'));
1962 else if (peek == 'D')
1964 /* A destructor name. Consume the D. */
1966 if (peek_char (dm) < '0' || peek_char (dm) > '2')
1967 return "Unrecognized destructor.";
1968 RETURN_IF_ERROR (result_append_char (dm, '~'));
1969 RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1970 /* Print the flavor of the destructor if in verbose mode. */
1971 flavor = next_char (dm) - '0';
1974 RETURN_IF_ERROR (result_append (dm, " ["));
1975 RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor]));
1976 RETURN_IF_ERROR (result_append_char (dm, ']'));
1980 return STATUS_ERROR;
1985 /* Handle pointer, reference, and pointer-to-member cases for
1986 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1987 build a pointer/reference type. We snarf all these, plus the
1988 following <type>, all at once since we need to know whether we have
1989 a pointer to data or pointer to function to construct the right
1990 output syntax. C++'s pointer syntax is hairy.
1992 This function adds substitution candidates for every nested
1993 pointer/reference type it processes, including the outermost, final
1994 type, assuming the substitution starts at SUBSTITUTION_START in the
1995 demangling result. For example, if this function demangles
1996 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
1997 `Foo**', in that order.
1999 *INSERT_POS is a quantity used internally, when this function calls
2000 itself recursively, to figure out where to insert pointer
2001 punctuation on the way up. On entry to this function, INSERT_POS
2002 should point to a temporary value, but that value need not be
2007 ::= <pointer-to-member-type>
2009 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2012 demangle_type_ptr (dm, insert_pos, substitution_start)
2015 int substitution_start;
2019 int is_substitution_candidate = 1;
2021 DEMANGLE_TRACE ("type*", dm);
2023 /* Scan forward, collecting pointers and references into symbols,
2024 until we hit something else. Then emit the type. */
2025 next = peek_char (dm);
2028 /* A pointer. Snarf the `P'. */
2030 /* Demangle the underlying type. */
2031 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2032 substitution_start));
2033 /* Insert an asterisk where we're told to; it doesn't
2034 necessarily go at the end. */
2035 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
2036 /* The next (outermost) pointer or reference character should go
2040 else if (next == 'R')
2042 /* A reference. Snarf the `R'. */
2044 /* Demangle the underlying type. */
2045 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2046 substitution_start));
2047 /* Insert an ampersand where we're told to; it doesn't
2048 necessarily go at the end. */
2049 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
2050 /* The next (outermost) pointer or reference character should go
2054 else if (next == 'M')
2056 /* A pointer-to-member. */
2057 dyn_string_t class_type;
2062 /* Capture the type of which this is a pointer-to-member. */
2063 RETURN_IF_ERROR (result_push (dm));
2064 RETURN_IF_ERROR (demangle_type (dm));
2065 class_type = (dyn_string_t) result_pop (dm);
2067 if (peek_char (dm) == 'F')
2068 /* A pointer-to-member function. We want output along the
2069 lines of `void (C::*) (int, int)'. Demangle the function
2070 type, which would in this case give `void () (int, int)'
2071 and set *insert_pos to the spot between the first
2073 status = demangle_type_ptr (dm, insert_pos, substitution_start);
2076 /* A pointer-to-member variable. Demangle the type of the
2077 pointed-to member. */
2078 status = demangle_type (dm);
2079 /* Make it pretty. */
2080 if (STATUS_NO_ERROR (status))
2081 status = result_append_space (dm);
2082 /* The pointer-to-member notation (e.g. `C::*') follows the
2084 *insert_pos = result_length (dm);
2087 /* Build the pointer-to-member notation. */
2088 if (STATUS_NO_ERROR (status))
2089 status = result_insert (dm, *insert_pos, "::*");
2090 if (STATUS_NO_ERROR (status))
2091 status = result_insert_string (dm, *insert_pos, class_type);
2092 /* There may be additional levels of (pointer or reference)
2093 indirection in this type. If so, the `*' and `&' should be
2094 added after the pointer-to-member notation (e.g. `C::*&' for
2095 a reference to a pointer-to-member of class C). */
2096 *insert_pos += dyn_string_length (class_type) + 3;
2099 dyn_string_delete (class_type);
2101 RETURN_IF_ERROR (status);
2103 else if (next == 'F')
2105 /* Ooh, tricky, a pointer-to-function. When we demangle the
2106 function type, the return type should go at the very
2108 *insert_pos = result_length (dm);
2109 /* The parentheses indicate this is a function pointer or
2111 RETURN_IF_ERROR (result_append (dm, "()"));
2112 /* Now demangle the function type. The return type will be
2113 inserted before the `()', and the argument list will go after
2115 RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
2116 /* We should now have something along the lines of
2117 `void () (int, int)'. The pointer or reference characters
2118 have to inside the first set of parentheses. *insert_pos has
2119 already been updated to point past the end of the return
2120 type. Move it one character over so it points inside the
2126 /* No more pointer or reference tokens; this is therefore a
2127 pointer to data. Finish up by demangling the underlying
2129 RETURN_IF_ERROR (demangle_type (dm));
2130 /* The pointer or reference characters follow the underlying
2131 type, as in `int*&'. */
2132 *insert_pos = result_length (dm);
2133 /* Because of the production <type> ::= <substitution>,
2134 demangle_type will already have added the underlying type as
2135 a substitution candidate. Don't do it again. */
2136 is_substitution_candidate = 0;
2139 if (is_substitution_candidate)
2140 RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
2145 /* Demangles and emits a <type>.
2147 <type> ::= <builtin-type>
2149 ::= <class-enum-type>
2151 ::= <pointer-to-member-type>
2152 ::= <template-param>
2153 ::= <template-template-param> <template-args>
2154 ::= <CV-qualifiers> <type>
2155 ::= P <type> # pointer-to
2156 ::= R <type> # reference-to
2157 ::= C <type> # complex pair (C 2000)
2158 ::= G <type> # imaginary (C 2000)
2159 ::= U <source-name> <type> # vendor extended type qualifier
2160 ::= <substitution> */
2166 int start = substitution_start (dm);
2167 char peek = peek_char (dm);
2169 int encode_return_type = 0;
2170 template_arg_list_t old_arg_list = current_template_arg_list (dm);
2173 /* A <type> can be a <substitution>; therefore, this <type> is a
2174 substitution candidate unless a special condition holds (see
2176 int is_substitution_candidate = 1;
2178 DEMANGLE_TRACE ("type", dm);
2180 /* A <class-enum-type> can start with a digit (a <source-name>), an
2181 N (a <nested-name>), or a Z (a <local-name>). */
2182 if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
2183 RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type));
2184 /* Lower-case letters begin <builtin-type>s, except for `r', which
2185 denotes restrict. */
2186 else if (peek >= 'a' && peek <= 'z' && peek != 'r')
2188 RETURN_IF_ERROR (demangle_builtin_type (dm));
2189 /* Built-in types are not substitution candidates. */
2190 is_substitution_candidate = 0;
2198 /* CV-qualifiers (including restrict). We have to demangle
2199 them off to the side, since C++ syntax puts them in a funny
2200 place for qualified pointer and reference types. */
2203 dyn_string_t cv_qualifiers = dyn_string_new (24);
2205 if (cv_qualifiers == NULL)
2206 return STATUS_ALLOCATION_FAILED;
2208 demangle_CV_qualifiers (dm, cv_qualifiers);
2210 /* If the qualifiers apply to a pointer or reference, they
2211 need to come after the whole qualified type. */
2212 if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
2214 status = demangle_type (dm);
2215 if (STATUS_NO_ERROR (status))
2216 status = result_append_space (dm);
2217 if (STATUS_NO_ERROR (status))
2218 status = result_append_string (dm, cv_qualifiers);
2220 /* Otherwise, the qualifiers come first. */
2223 status = result_append_string (dm, cv_qualifiers);
2224 if (STATUS_NO_ERROR (status))
2225 status = result_append_space (dm);
2226 if (STATUS_NO_ERROR (status))
2227 status = demangle_type (dm);
2230 dyn_string_delete (cv_qualifiers);
2231 RETURN_IF_ERROR (status);
2236 return "Non-pointer or -reference function type.";
2239 RETURN_IF_ERROR (demangle_array_type (dm));
2243 /* It's either a <template-param> or a
2244 <template-template-param>. In either case, demangle the
2246 RETURN_IF_ERROR (demangle_template_param (dm));
2248 /* Check for a template argument list; if one is found, it's a
2249 <template-template-param> ::= <template-param>
2250 ::= <substitution> */
2251 if (peek_char (dm) == 'I')
2253 /* Add a substitution candidate. The template parameter
2254 `T' token is a substitution candidate by itself,
2255 without the template argument list. */
2256 RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2258 /* Now demangle the template argument list. */
2259 RETURN_IF_ERROR (demangle_template_args (dm));
2260 /* The entire type, including the template template
2261 parameter and its argument list, will be added as a
2262 substitution candidate below. */
2268 /* First check if this is a special substitution. If it is,
2269 this is a <class-enum-type>. Special substitutions have a
2270 letter following the `S'; other substitutions have a digit
2272 peek_next = peek_char_next (dm);
2273 if (IS_DIGIT (peek_next) || peek_next == '_')
2275 RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type));
2277 /* The substituted name may have been a template name.
2278 Check if template arguments follow, and if so, demangle
2280 if (peek_char (dm) == 'I')
2281 RETURN_IF_ERROR (demangle_template_args (dm));
2283 /* A substitution token is not itself a substitution
2284 candidate. (However, if the substituted template is
2285 instantiated, the resulting type is.) */
2286 is_substitution_candidate = 0;
2290 /* Now some trickiness. We have a special substitution
2291 here. Often, the special substitution provides the
2292 name of a template that's subsequently instantiated,
2293 for instance `SaIcE' => std::allocator<char>. In these
2294 cases we need to add a substitution candidate for the
2295 entire <class-enum-type> and thus don't want to clear
2296 the is_substitution_candidate flag.
2298 However, it's possible that what we have here is a
2299 substitution token representing an entire type, such as
2300 `Ss' => std::string. In this case, we mustn't add a
2301 new substitution candidate for this substitution token.
2302 To detect this case, remember where the start of the
2303 substitution token is. */
2304 const char *next = dm->next;
2305 /* Now demangle the <class-enum-type>. */
2307 (demangle_class_enum_type (dm, &encode_return_type));
2308 /* If all that was just demangled is the two-character
2309 special substitution token, supress the addition of a
2310 new candidate for it. */
2311 if (dm->next == next + 2)
2312 is_substitution_candidate = 0;
2320 RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
2321 /* demangle_type_ptr adds all applicable substitution
2323 is_substitution_candidate = 0;
2327 /* A C99 complex type. */
2328 RETURN_IF_ERROR (result_append (dm, "complex "));
2330 RETURN_IF_ERROR (demangle_type (dm));
2334 /* A C99 imaginary type. */
2335 RETURN_IF_ERROR (result_append (dm, "imaginary "));
2337 RETURN_IF_ERROR (demangle_type (dm));
2341 /* Vendor-extended type qualifier. */
2343 RETURN_IF_ERROR (demangle_source_name (dm));
2344 RETURN_IF_ERROR (result_append_char (dm, ' '));
2345 RETURN_IF_ERROR (demangle_type (dm));
2349 return "Unexpected character in <type>.";
2352 if (is_substitution_candidate)
2353 /* Add a new substitution for the type. If this type was a
2354 <template-param>, pass its index since from the point of
2355 substitutions; a <template-param> token is a substitution
2356 candidate distinct from the type that is substituted for it. */
2357 RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2359 /* Pop off template argument lists added during mangling of this
2361 pop_to_template_arg_list (dm, old_arg_list);
2366 /* C++ source names of builtin types, indexed by the mangled code
2367 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2368 static const char *const builtin_type_names[26] =
2370 "signed char", /* a */
2374 "long double", /* e */
2376 "__float128", /* g */
2377 "unsigned char", /* h */
2382 "unsigned long", /* m */
2384 "unsigned __int128", /* o */
2389 "unsigned short", /* t */
2393 "long long", /* x */
2394 "unsigned long long", /* y */
2398 /* Demangles and emits a <builtin-type>.
2400 <builtin-type> ::= v # void
2405 ::= h # unsigned char
2407 ::= t # unsigned short
2409 ::= j # unsigned int
2411 ::= m # unsigned long
2412 ::= x # long long, __int64
2413 ::= y # unsigned long long, __int64
2415 ::= o # unsigned __int128
2418 ::= e # long double, __float80
2421 ::= u <source-name> # vendor extended type */
2424 demangle_builtin_type (dm)
2428 char code = peek_char (dm);
2430 DEMANGLE_TRACE ("builtin-type", dm);
2435 RETURN_IF_ERROR (demangle_source_name (dm));
2438 else if (code >= 'a' && code <= 'z')
2440 const char *type_name = builtin_type_names[code - 'a'];
2441 if (type_name == NULL)
2442 return "Unrecognized <builtin-type> code.";
2444 RETURN_IF_ERROR (result_append (dm, type_name));
2449 return "Non-alphabetic <builtin-type> code.";
2452 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2453 restrict) at the current position. The qualifiers are appended to
2454 QUALIFIERS. Returns STATUS_OK. */
2457 demangle_CV_qualifiers (dm, qualifiers)
2459 dyn_string_t qualifiers;
2461 DEMANGLE_TRACE ("CV-qualifiers", dm);
2465 switch (peek_char (dm))
2468 if (!dyn_string_append_space (qualifiers))
2469 return STATUS_ALLOCATION_FAILED;
2470 if (!dyn_string_append_cstr (qualifiers, "restrict"))
2471 return STATUS_ALLOCATION_FAILED;
2475 if (!dyn_string_append_space (qualifiers))
2476 return STATUS_ALLOCATION_FAILED;
2477 if (!dyn_string_append_cstr (qualifiers, "volatile"))
2478 return STATUS_ALLOCATION_FAILED;
2482 if (!dyn_string_append_space (qualifiers))
2483 return STATUS_ALLOCATION_FAILED;
2484 if (!dyn_string_append_cstr (qualifiers, "const"))
2485 return STATUS_ALLOCATION_FAILED;
2496 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2497 position in the result string of the start of the function
2498 identifier, at which the function's return type will be inserted;
2499 *FUNCTION_NAME_POS is updated to position past the end of the
2500 function's return type.
2502 <function-type> ::= F [Y] <bare-function-type> E */
2505 demangle_function_type (dm, function_name_pos)
2507 int *function_name_pos;
2509 DEMANGLE_TRACE ("function-type", dm);
2510 RETURN_IF_ERROR (demangle_char (dm, 'F'));
2511 if (peek_char (dm) == 'Y')
2513 /* Indicate this function has C linkage if in verbose mode. */
2515 RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] "));
2518 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2519 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2523 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2524 position in the result string at which the function return type
2525 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2526 function's return type is assumed not to be encoded.
2528 <bare-function-type> ::= <signature type>+ */
2531 demangle_bare_function_type (dm, return_type_pos)
2533 int *return_type_pos;
2535 /* Sequence is the index of the current function parameter, counting
2536 from zero. The value -1 denotes the return type. */
2538 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2540 DEMANGLE_TRACE ("bare-function-type", dm);
2542 RETURN_IF_ERROR (result_append_char (dm, '('));
2543 while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2546 /* We're decoding the function's return type. */
2548 dyn_string_t return_type;
2549 status_t status = STATUS_OK;
2551 /* Decode the return type off to the side. */
2552 RETURN_IF_ERROR (result_push (dm));
2553 RETURN_IF_ERROR (demangle_type (dm));
2554 return_type = (dyn_string_t) result_pop (dm);
2556 /* Add a space to the end of the type. Insert the return
2557 type where we've been asked to. */
2558 if (!dyn_string_append_space (return_type))
2559 status = STATUS_ALLOCATION_FAILED;
2560 if (STATUS_NO_ERROR (status))
2562 if (!dyn_string_insert (result_string (dm), *return_type_pos,
2564 status = STATUS_ALLOCATION_FAILED;
2566 *return_type_pos += dyn_string_length (return_type);
2569 dyn_string_delete (return_type);
2570 RETURN_IF_ERROR (status);
2574 /* Skip `void' parameter types. One should only occur as
2575 the only type in a parameter list; in that case, we want
2576 to print `foo ()' instead of `foo (void)'. */
2577 if (peek_char (dm) == 'v')
2578 /* Consume the v. */
2582 /* Separate parameter types by commas. */
2584 RETURN_IF_ERROR (result_append (dm, ", "));
2585 /* Demangle the type. */
2586 RETURN_IF_ERROR (demangle_type (dm));
2592 RETURN_IF_ERROR (result_append_char (dm, ')'));
2594 /* We should have demangled at least one parameter type (which would
2595 be void, for a function that takes no parameters), plus the
2596 return type, if we were supposed to demangle that. */
2598 return "Missing function return type.";
2599 else if (sequence == 0)
2600 return "Missing function parameter.";
2605 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2606 non-zero if the type is a template-id, zero otherwise.
2608 <class-enum-type> ::= <name> */
2611 demangle_class_enum_type (dm, encode_return_type)
2613 int *encode_return_type;
2615 DEMANGLE_TRACE ("class-enum-type", dm);
2617 RETURN_IF_ERROR (demangle_name (dm, encode_return_type));
2621 /* Demangles and emits an <array-type>.
2623 <array-type> ::= A [<dimension number>] _ <element type>
2624 ::= A <dimension expression> _ <element type> */
2627 demangle_array_type (dm)
2630 status_t status = STATUS_OK;
2631 dyn_string_t array_size = NULL;
2634 RETURN_IF_ERROR (demangle_char (dm, 'A'));
2636 /* Demangle the array size into array_size. */
2637 peek = peek_char (dm);
2639 /* Array bound is omitted. This is a C99-style VLA. */
2641 else if (IS_DIGIT (peek_char (dm)))
2643 /* It looks like a constant array bound. */
2644 array_size = dyn_string_new (10);
2645 if (array_size == NULL)
2646 return STATUS_ALLOCATION_FAILED;
2647 status = demangle_number_literally (dm, array_size, 10, 0);
2651 /* Anything is must be an expression for a nont-constant array
2652 bound. This happens if the array type occurs in a template
2653 and the array bound references a template parameter. */
2654 RETURN_IF_ERROR (result_push (dm));
2655 RETURN_IF_ERROR (demangle_expression (dm));
2656 array_size = (dyn_string_t) result_pop (dm);
2658 /* array_size may have been allocated by now, so we can't use
2659 RETURN_IF_ERROR until it's been deallocated. */
2661 /* Demangle the base type of the array. */
2662 if (STATUS_NO_ERROR (status))
2663 status = demangle_char (dm, '_');
2664 if (STATUS_NO_ERROR (status))
2665 status = demangle_type (dm);
2667 /* Emit the array dimension syntax. */
2668 if (STATUS_NO_ERROR (status))
2669 status = result_append_char (dm, '[');
2670 if (STATUS_NO_ERROR (status) && array_size != NULL)
2671 status = result_append_string (dm, array_size);
2672 if (STATUS_NO_ERROR (status))
2673 status = result_append_char (dm, ']');
2674 if (array_size != NULL)
2675 dyn_string_delete (array_size);
2677 RETURN_IF_ERROR (status);
2682 /* Demangles and emits a <template-param>.
2684 <template-param> ::= T_ # first template parameter
2685 ::= T <parameter-2 number> _ */
2688 demangle_template_param (dm)
2692 template_arg_list_t current_arg_list = current_template_arg_list (dm);
2695 DEMANGLE_TRACE ("template-param", dm);
2697 /* Make sure there is a template argmust list in which to look up
2698 this parameter reference. */
2699 if (current_arg_list == NULL)
2700 return "Template parameter outside of template.";
2702 RETURN_IF_ERROR (demangle_char (dm, 'T'));
2703 if (peek_char (dm) == '_')
2707 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2710 RETURN_IF_ERROR (demangle_char (dm, '_'));
2712 arg = template_arg_list_get_arg (current_arg_list, parm_number);
2714 /* parm_number exceeded the number of arguments in the current
2715 template argument list. */
2716 return "Template parameter number out of bounds.";
2717 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2722 /* Demangles and emits a <template-args>.
2724 <template-args> ::= I <template-arg>+ E */
2727 demangle_template_args (dm)
2731 dyn_string_t old_last_source_name;
2732 template_arg_list_t arg_list = template_arg_list_new ();
2734 if (arg_list == NULL)
2735 return STATUS_ALLOCATION_FAILED;
2737 /* Preserve the most recently demangled source name. */
2738 old_last_source_name = dm->last_source_name;
2739 dm->last_source_name = dyn_string_new (0);
2741 DEMANGLE_TRACE ("template-args", dm);
2743 if (dm->last_source_name == NULL)
2744 return STATUS_ALLOCATION_FAILED;
2746 RETURN_IF_ERROR (demangle_char (dm, 'I'));
2747 RETURN_IF_ERROR (result_open_template_list (dm));
2755 RETURN_IF_ERROR (result_append (dm, ", "));
2757 /* Capture the template arg. */
2758 RETURN_IF_ERROR (result_push (dm));
2759 RETURN_IF_ERROR (demangle_template_arg (dm));
2760 arg = result_pop (dm);
2762 /* Emit it in the demangled name. */
2763 RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2765 /* Save it for use in expanding <template-param>s. */
2766 template_arg_list_add_arg (arg_list, arg);
2768 while (peek_char (dm) != 'E');
2769 /* Append the '>'. */
2770 RETURN_IF_ERROR (result_close_template_list (dm));
2772 /* Consume the 'E'. */
2775 /* Restore the most recent demangled source name. */
2776 dyn_string_delete (dm->last_source_name);
2777 dm->last_source_name = old_last_source_name;
2779 /* Push the list onto the top of the stack of template argument
2780 lists, so that arguments from it are used from now on when
2781 expanding <template-param>s. */
2782 push_template_arg_list (dm, arg_list);
2787 /* This function, which does not correspond to a production in the
2788 mangling spec, handles the `literal' production for both
2789 <template-arg> and <expr-primary>. It does not expect or consume
2790 the initial `L' or final `E'. The demangling is given by:
2792 <literal> ::= <type> </value/ number>
2794 and the emitted output is `(type)number'. */
2797 demangle_literal (dm)
2800 char peek = peek_char (dm);
2801 dyn_string_t value_string;
2804 DEMANGLE_TRACE ("literal", dm);
2806 if (!flag_verbose && peek >= 'a' && peek <= 'z')
2808 /* If not in verbose mode and this is a builtin type, see if we
2809 can produce simpler numerical output. In particular, for
2810 integer types shorter than `long', just write the number
2811 without type information; for bools, write `true' or `false'.
2812 Other refinements could be made here too. */
2814 /* This constant string is used to map from <builtin-type> codes
2815 (26 letters of the alphabet) to codes that determine how the
2816 value will be displayed. The codes are:
2820 A space means the value will be represented using cast
2822 static const char *const code_map = "ibi iii ll ii i ";
2824 char code = code_map[peek - 'a'];
2825 /* FIXME: Implement demangling of floats and doubles. */
2827 return STATUS_UNIMPLEMENTED;
2830 /* It's a boolean. */
2833 /* Consume the b. */
2835 /* Look at the next character. It should be 0 or 1,
2836 corresponding to false or true, respectively. */
2837 value = peek_char (dm);
2839 RETURN_IF_ERROR (result_append (dm, "false"));
2840 else if (value == '1')
2841 RETURN_IF_ERROR (result_append (dm, "true"));
2843 return "Unrecognized bool constant.";
2844 /* Consume the 0 or 1. */
2848 else if (code == 'i' || code == 'l')
2850 /* It's an integer or long. */
2852 /* Consume the type character. */
2855 /* Demangle the number and write it out. */
2856 value_string = dyn_string_new (0);
2857 status = demangle_number_literally (dm, value_string, 10, 1);
2858 if (STATUS_NO_ERROR (status))
2859 status = result_append_string (dm, value_string);
2860 /* For long integers, append an l. */
2861 if (code == 'l' && STATUS_NO_ERROR (status))
2862 status = result_append_char (dm, code);
2863 dyn_string_delete (value_string);
2865 RETURN_IF_ERROR (status);
2868 /* ...else code == ' ', so fall through to represent this
2869 literal's type explicitly using cast syntax. */
2872 RETURN_IF_ERROR (result_append_char (dm, '('));
2873 RETURN_IF_ERROR (demangle_type (dm));
2874 RETURN_IF_ERROR (result_append_char (dm, ')'));
2876 value_string = dyn_string_new (0);
2877 if (value_string == NULL)
2878 return STATUS_ALLOCATION_FAILED;
2880 status = demangle_number_literally (dm, value_string, 10, 1);
2881 if (STATUS_NO_ERROR (status))
2882 status = result_append_string (dm, value_string);
2883 dyn_string_delete (value_string);
2884 RETURN_IF_ERROR (status);
2889 /* Demangles and emits a <template-arg>.
2891 <template-arg> ::= <type> # type
2892 ::= L <type> <value number> E # literal
2893 ::= LZ <encoding> E # external name
2894 ::= X <expression> E # expression */
2897 demangle_template_arg (dm)
2900 DEMANGLE_TRACE ("template-arg", dm);
2902 switch (peek_char (dm))
2907 if (peek_char (dm) == 'Z')
2909 /* External name. */
2911 /* FIXME: Standard is contradictory here. */
2912 RETURN_IF_ERROR (demangle_encoding (dm));
2915 RETURN_IF_ERROR (demangle_literal (dm));
2916 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2922 RETURN_IF_ERROR (demangle_expression (dm));
2923 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2927 RETURN_IF_ERROR (demangle_type (dm));
2934 /* Demangles and emits an <expression>.
2936 <expression> ::= <unary operator-name> <expression>
2937 ::= <binary operator-name> <expression> <expression>
2939 ::= <scope-expression> */
2942 demangle_expression (dm)
2945 char peek = peek_char (dm);
2947 DEMANGLE_TRACE ("expression", dm);
2949 if (peek == 'L' || peek == 'T')
2950 RETURN_IF_ERROR (demangle_expr_primary (dm));
2951 else if (peek == 's' && peek_char_next (dm) == 'r')
2952 RETURN_IF_ERROR (demangle_scope_expression (dm));
2954 /* An operator expression. */
2957 status_t status = STATUS_OK;
2958 dyn_string_t operator_name;
2960 /* We have an operator name. Since we want to output binary
2961 operations in infix notation, capture the operator name
2963 RETURN_IF_ERROR (result_push (dm));
2964 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
2965 operator_name = (dyn_string_t) result_pop (dm);
2967 /* If it's binary, do an operand first. */
2970 status = result_append_char (dm, '(');
2971 if (STATUS_NO_ERROR (status))
2972 status = demangle_expression (dm);
2973 if (STATUS_NO_ERROR (status))
2974 status = result_append_char (dm, ')');
2977 /* Emit the operator. */
2978 if (STATUS_NO_ERROR (status))
2979 status = result_append_string (dm, operator_name);
2980 dyn_string_delete (operator_name);
2981 RETURN_IF_ERROR (status);
2983 /* Emit its second (if binary) or only (if unary) operand. */
2984 RETURN_IF_ERROR (result_append_char (dm, '('));
2985 RETURN_IF_ERROR (demangle_expression (dm));
2986 RETURN_IF_ERROR (result_append_char (dm, ')'));
2988 /* The ternary operator takes a third operand. */
2991 RETURN_IF_ERROR (result_append (dm, ":("));
2992 RETURN_IF_ERROR (demangle_expression (dm));
2993 RETURN_IF_ERROR (result_append_char (dm, ')'));
3000 /* Demangles and emits a <scope-expression>.
3002 <scope-expression> ::= sr <qualifying type> <source-name>
3003 ::= sr <qualifying type> <encoding> */
3006 demangle_scope_expression (dm)
3009 RETURN_IF_ERROR (demangle_char (dm, 's'));
3010 RETURN_IF_ERROR (demangle_char (dm, 'r'));
3011 RETURN_IF_ERROR (demangle_type (dm));
3012 RETURN_IF_ERROR (result_append (dm, "::"));
3013 RETURN_IF_ERROR (demangle_encoding (dm));
3017 /* Demangles and emits an <expr-primary>.
3019 <expr-primary> ::= <template-param>
3020 ::= L <type> <value number> E # literal
3021 ::= L <mangled-name> E # external name */
3024 demangle_expr_primary (dm)
3027 char peek = peek_char (dm);
3029 DEMANGLE_TRACE ("expr-primary", dm);
3032 RETURN_IF_ERROR (demangle_template_param (dm));
3033 else if (peek == 'L')
3035 /* Consume the `L'. */
3037 peek = peek_char (dm);
3040 RETURN_IF_ERROR (demangle_mangled_name (dm));
3042 RETURN_IF_ERROR (demangle_literal (dm));
3044 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3047 return STATUS_ERROR;
3052 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3053 if the substitution is the name of a template, zero otherwise.
3055 <substitution> ::= S <seq-id> _
3059 ::= Sa # ::std::allocator
3060 ::= Sb # ::std::basic_string
3061 ::= Ss # ::std::basic_string<char,
3062 ::std::char_traits<char>,
3063 ::std::allocator<char> >
3064 ::= Si # ::std::basic_istream<char,
3065 std::char_traits<char> >
3066 ::= So # ::std::basic_ostream<char,
3067 std::char_traits<char> >
3068 ::= Sd # ::std::basic_iostream<char,
3069 std::char_traits<char> >
3073 demangle_substitution (dm, template_p)
3081 DEMANGLE_TRACE ("substitution", dm);
3083 RETURN_IF_ERROR (demangle_char (dm, 'S'));
3085 /* Scan the substitution sequence index. A missing number denotes
3087 peek = peek_char (dm);
3090 /* If the following character is 0-9 or a capital letter, interpret
3091 the sequence up to the next underscore as a base-36 substitution
3093 else if (IS_DIGIT ((unsigned char) peek)
3094 || (peek >= 'A' && peek <= 'Z'))
3095 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
3098 const char *new_last_source_name = NULL;
3103 RETURN_IF_ERROR (result_append (dm, "std"));
3107 RETURN_IF_ERROR (result_append (dm, "std::allocator"));
3108 new_last_source_name = "allocator";
3113 RETURN_IF_ERROR (result_append (dm, "std::basic_string"));
3114 new_last_source_name = "basic_string";
3121 RETURN_IF_ERROR (result_append (dm, "std::string"));
3122 new_last_source_name = "string";
3126 RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3127 new_last_source_name = "basic_string";
3135 RETURN_IF_ERROR (result_append (dm, "std::istream"));
3136 new_last_source_name = "istream";
3140 RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >"));
3141 new_last_source_name = "basic_istream";
3149 RETURN_IF_ERROR (result_append (dm, "std::ostream"));
3150 new_last_source_name = "ostream";
3154 RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >"));
3155 new_last_source_name = "basic_ostream";
3163 RETURN_IF_ERROR (result_append (dm, "std::iostream"));
3164 new_last_source_name = "iostream";
3168 RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >"));
3169 new_last_source_name = "basic_iostream";
3175 return "Unrecognized <substitution>.";
3178 /* Consume the character we just processed. */
3181 if (new_last_source_name != NULL)
3183 if (!dyn_string_copy_cstr (dm->last_source_name,
3184 new_last_source_name))
3185 return STATUS_ALLOCATION_FAILED;
3191 /* Look up the substitution text. Since `S_' is the most recent
3192 substitution, `S0_' is the second-most-recent, etc., shift the
3193 numbering by one. */
3194 text = substitution_get (dm, seq_id + 1, template_p);
3196 return "Substitution number out of range.";
3198 /* Emit the substitution text. */
3199 RETURN_IF_ERROR (result_append_string (dm, text));
3201 RETURN_IF_ERROR (demangle_char (dm, '_'));
3205 /* Demangles and emits a <local-name>.
3207 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3208 := Z <function encoding> E s [<discriminator>] */
3211 demangle_local_name (dm)
3214 DEMANGLE_TRACE ("local-name", dm);
3216 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
3217 RETURN_IF_ERROR (demangle_encoding (dm));
3218 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3219 RETURN_IF_ERROR (result_append (dm, "::"));
3221 if (peek_char (dm) == 's')
3223 /* Local character string literal. */
3224 RETURN_IF_ERROR (result_append (dm, "string literal"));
3225 /* Consume the s. */
3227 RETURN_IF_ERROR (demangle_discriminator (dm, 0));
3232 /* Local name for some other entity. Demangle its name. */
3233 RETURN_IF_ERROR (demangle_name (dm, &unused));
3234 RETURN_IF_ERROR (demangle_discriminator (dm, 1));
3240 /* Optimonally demangles and emits a <discriminator>. If there is no
3241 <discriminator> at the current position in the mangled string, the
3242 descriminator is assumed to be zero. Emit the discriminator number
3243 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3244 discriminator is zero.
3246 <discriminator> ::= _ <number> */
3249 demangle_discriminator (dm, suppress_first)
3253 /* Output for <discriminator>s to the demangled name is completely
3254 suppressed if not in verbose mode. */
3256 if (peek_char (dm) == '_')
3258 /* Consume the underscore. */
3261 RETURN_IF_ERROR (result_append (dm, " [#"));
3262 /* Check if there's a number following the underscore. */
3263 if (IS_DIGIT ((unsigned char) peek_char (dm)))
3266 /* Demangle the number. */
3267 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
3269 /* Write the discriminator. The mangled number is two
3270 less than the discriminator ordinal, counting from
3272 RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2,
3273 (dyn_string_t) dm->result));
3278 /* A missing digit correspond to one. */
3279 RETURN_IF_ERROR (result_append_char (dm, '1'));
3282 RETURN_IF_ERROR (result_append_char (dm, ']'));
3284 else if (!suppress_first)
3287 RETURN_IF_ERROR (result_append (dm, " [#0]"));
3293 /* Demangle NAME into RESULT, which must be an initialized
3294 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3295 an error message, and the contents of RESULT are unchanged. */
3298 cp_demangle (name, result)
3300 dyn_string_t result;
3303 int length = strlen (name);
3305 if (length > 2 && name[0] == '_' && name[1] == 'Z')
3307 demangling_t dm = demangling_new (name);
3309 return STATUS_ALLOCATION_FAILED;
3311 status = result_push (dm);
3312 if (status != STATUS_OK)
3314 demangling_delete (dm);
3318 status = demangle_mangled_name (dm);
3319 if (STATUS_NO_ERROR (status))
3321 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3322 if (!dyn_string_copy (result, demangled))
3323 return STATUS_ALLOCATION_FAILED;
3324 dyn_string_delete (demangled);
3327 demangling_delete (dm);
3331 /* It's evidently not a mangled C++ name. It could be the name
3332 of something with C linkage, though, so just copy NAME into
3334 if (!dyn_string_copy_cstr (result, name))
3335 return STATUS_ALLOCATION_FAILED;
3342 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3343 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3344 an error message, and the contents of RESULT are unchanged. */
3348 cp_demangle_type (type_name, result)
3349 const char* type_name;
3350 dyn_string_t result;
3353 demangling_t dm = demangling_new (type_name);
3356 return STATUS_ALLOCATION_FAILED;
3358 /* Demangle the type name. The demangled name is stored in dm. */
3359 status = result_push (dm);
3360 if (status != STATUS_OK)
3362 demangling_delete (dm);
3366 status = demangle_type (dm);
3368 if (STATUS_NO_ERROR (status))
3370 /* The demangling succeeded. Pop the result out of dm and copy
3372 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3373 if (!dyn_string_copy (result, demangled))
3374 return STATUS_ALLOCATION_FAILED;
3375 dyn_string_delete (demangled);
3379 demangling_delete (dm);
3384 extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
3386 /* ABI-mandated entry point in the C++ runtime library for performing
3387 demangling. MANGLED_NAME is a NUL-terminated character string
3388 containing the name to be demangled.
3390 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3391 *LENGTH bytes, into which the demangled name is stored. If
3392 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3393 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3394 is placed in a region of memory allocated with malloc.
3396 If LENGTH is non-NULL, the length of the buffer conaining the
3397 demangled name, is placed in *LENGTH.
3399 The return value is a pointer to the start of the NUL-terminated
3400 demangled name, or NULL if the demangling fails. The caller is
3401 responsible for deallocating this memory using free.
3403 *STATUS is set to one of the following values:
3404 0: The demangling operation succeeded.
3405 -1: A memory allocation failiure occurred.
3406 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3407 -3: One of the arguments is invalid.
3409 The demagling is performed using the C++ ABI mangling rules, with
3413 __cxa_demangle (mangled_name, output_buffer, length, status)
3414 const char *mangled_name;
3415 char *output_buffer;
3419 struct dyn_string demangled_name;
3425 if (mangled_name == NULL) {
3430 /* Did the caller provide a buffer for the demangled name? */
3431 if (output_buffer == NULL) {
3432 /* No; dyn_string will malloc a buffer for us. */
3433 if (!dyn_string_init (&demangled_name, 0))
3440 /* Yes. Check that the length was provided. */
3441 if (length == NULL) {
3445 /* Install the buffer into a dyn_string. */
3446 demangled_name.allocated = *length;
3447 demangled_name.length = 0;
3448 demangled_name.s = output_buffer;
3451 if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
3452 /* MANGLED_NAME apprears to be a function or variable name.
3453 Demangle it accordingly. */
3454 result = cp_demangle (mangled_name, &demangled_name);
3456 /* Try to demangled MANGLED_NAME as the name of a type. */
3457 result = cp_demangle_type (mangled_name, &demangled_name);
3459 if (result == STATUS_OK)
3460 /* The demangling succeeded. */
3462 /* If LENGTH isn't NULL, store the allocated buffer length
3463 there; the buffer may have been realloced by dyn_string
3466 *length = demangled_name.allocated;
3467 /* The operation was a success. */
3469 return dyn_string_buf (&demangled_name);
3471 else if (result == STATUS_ALLOCATION_FAILED)
3472 /* A call to malloc or realloc failed during the demangling
3479 /* The demangling failed for another reason, most probably because
3480 MANGLED_NAME isn't a valid mangled name. */
3482 /* If the buffer containing the demangled name wasn't provided
3483 by the caller, free it. */
3484 if (output_buffer == NULL)
3485 free (dyn_string_buf (&demangled_name));
3491 #else /* !IN_LIBGCC2 */
3493 /* Variant entry point for integration with the existing cplus-dem
3494 demangler. Attempts to demangle MANGLED. If the demangling
3495 succeeds, returns a buffer, allocated with malloc, containing the
3496 demangled name. The caller must deallocate the buffer using free.
3497 If the demangling failes, returns NULL. */
3500 cplus_demangle_new_abi (mangled)
3501 const char* mangled;
3503 /* Create a dyn_string to hold the demangled name. */
3504 dyn_string_t demangled = dyn_string_new (0);
3505 /* Attempt the demangling. */
3506 status_t status = cp_demangle ((char *) mangled, demangled);
3507 if (STATUS_NO_ERROR (status))
3508 /* Demangling succeeded. */
3510 /* Grab the demangled result from the dyn_string. It was
3511 allocated with malloc, so we can return it directly. */
3512 char *return_value = dyn_string_release (demangled);
3513 /* Hand back the demangled name. */
3514 return return_value;
3516 else if (status == STATUS_ALLOCATION_FAILED)
3518 fprintf (stderr, "Memory allocation failed.\n");
3522 /* Demangling failed. */
3524 dyn_string_delete (demangled);
3529 #endif /* IN_LIBGCC2 */
3531 #ifdef STANDALONE_DEMANGLER
3535 static void print_usage
3536 PARAMS ((FILE* fp, int exit_value));
3538 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3539 #define is_mangled_char(CHAR) \
3540 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3541 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3543 /* The name of this program, as invoked. */
3544 const char* program_name;
3546 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3549 print_usage (fp, exit_value)
3553 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
3554 fprintf (fp, "Options:\n");
3555 fprintf (fp, " -h,--help Display this message.\n");
3556 fprintf (fp, " -s,--strict Demangle standard names only.\n");
3557 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
3558 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3563 /* Option specification for getopt_long. */
3564 static struct option long_options[] =
3566 { "help", no_argument, NULL, 'h' },
3567 { "strict", no_argument, NULL, 's' },
3568 { "verbose", no_argument, NULL, 'v' },
3569 { NULL, no_argument, NULL, 0 },
3572 /* Main entry for a demangling filter executable. It will demangle
3573 its command line arguments, if any. If none are provided, it will
3574 filter stdin to stdout, replacing any recognized mangled C++ names
3575 with their demangled equivalents. */
3586 /* Use the program name of this program, as invoked. */
3587 program_name = argv[0];
3589 /* Parse options. */
3592 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
3595 case '?': /* Unrecognized option. */
3596 print_usage (stderr, 1);
3600 print_usage (stdout, 0);
3612 while (opt_char != -1);
3615 /* No command line arguments were provided. Filter stdin. */
3617 dyn_string_t mangled = dyn_string_new (3);
3618 dyn_string_t demangled = dyn_string_new (0);
3621 /* Read all of input. */
3622 while (!feof (stdin))
3624 char c = getchar ();
3626 /* The first character of a mangled name is an underscore. */
3631 /* It's not a mangled name. Print the character and go
3638 /* The second character of a mangled name is a capital `Z'. */
3643 /* It's not a mangled name. Print the previous
3644 underscore, the `Z', and go on. */
3650 /* Start keeping track of the candidate mangled name. */
3651 dyn_string_append_char (mangled, '_');
3652 dyn_string_append_char (mangled, 'Z');
3654 /* Pile characters into mangled until we hit one that can't
3655 occur in a mangled name. */
3657 while (!feof (stdin) && is_mangled_char (c))
3659 dyn_string_append_char (mangled, c);
3665 /* Attempt to demangle the name. */
3666 status = cp_demangle (dyn_string_buf (mangled), demangled);
3668 /* If the demangling succeeded, great! Print out the
3669 demangled version. */
3670 if (STATUS_NO_ERROR (status))
3671 fputs (dyn_string_buf (demangled), stdout);
3672 /* Abort on allocation failures. */
3673 else if (status == STATUS_ALLOCATION_FAILED)
3675 fprintf (stderr, "Memory allocation failed.\n");
3678 /* Otherwise, it might not have been a mangled name. Just
3679 print out the original text. */
3681 fputs (dyn_string_buf (mangled), stdout);
3683 /* If we haven't hit EOF yet, we've read one character that
3684 can't occur in a mangled name, so print it out. */
3688 /* Clear the candidate mangled name, to start afresh next
3689 time we hit a `_Z'. */
3690 dyn_string_clear (mangled);
3693 dyn_string_delete (mangled);
3694 dyn_string_delete (demangled);
3697 /* Demangle command line arguments. */
3699 dyn_string_t result = dyn_string_new (0);
3701 /* Loop over command line arguments. */
3702 for (i = optind; i < argc; ++i)
3704 /* Attempt to demangle. */
3705 status = cp_demangle (argv[i], result);
3707 /* If it worked, print the demangled name. */
3708 if (STATUS_NO_ERROR (status))
3709 printf ("%s\n", dyn_string_buf (result));
3710 /* Abort on allocaiton failures. */
3711 else if (status == STATUS_ALLOCATION_FAILED)
3713 fprintf (stderr, "Memory allocaiton failed.\n");
3716 /* If not, print the error message to stderr instead. */
3718 fprintf (stderr, "%s\n", status);
3720 dyn_string_delete (result);
3726 #endif /* STANDALONE_DEMANGLER */