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
36 #if defined(CP_DEMANGLE_DEBUG) || defined(STANDALONE_DEMANGLER)
45 #include "libiberty.h"
46 #include "dyn-string.h"
49 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
50 and other debugging output, will be generated. */
51 #ifdef CP_DEMANGLE_DEBUG
52 #define DEMANGLE_TRACE(PRODUCTION, DM) \
53 fprintf (stderr, " -> %-24s at position %3d\n", \
54 (PRODUCTION), current_position (DM));
56 #define DEMANGLE_TRACE(PRODUCTION, DM)
59 /* If flag_verbose is zero, some simplifications will be made to the
60 output to make it easier to read and supress details that are
61 generally not of interest to the average C++ programmer.
62 Otherwise, the demangled representation will attempt to convey as
63 much information as the mangled form. */
64 static int flag_verbose
;
66 /* If flag_strict is non-zero, demangle strictly according to the
67 specification -- don't demangle special g++ manglings. */
68 static int flag_strict
;
70 /* String_list_t is an extended form of dyn_string_t which provides a link
71 field. A string_list_t may safely be cast to and used as a
74 struct string_list_def
76 struct dyn_string string
;
77 struct string_list_def
*next
;
80 typedef struct string_list_def
*string_list_t
;
82 /* Data structure representing a potential substitution. */
84 struct substitution_def
86 /* The demangled text of the substitution. */
89 /* The template parameter that this represents, indexed from zero.
90 If this is not a template paramter number, the value is
92 int template_parm_number
;
94 /* Whether this substitution represents a template item. */
98 #define NOT_TEMPLATE_PARM (-1)
100 /* Data structure representing a template argument list. */
102 struct template_arg_list_def
104 /* The next (lower) template argument list in the stack of currently
105 active template arguments. */
106 struct template_arg_list_def
*next
;
108 /* The first element in the list of template arguments in
109 left-to-right order. */
110 string_list_t first_argument
;
112 /* The last element in the arguments lists. */
113 string_list_t last_argument
;
116 typedef struct template_arg_list_def
*template_arg_list_t
;
118 /* Data structure to maintain the state of the current demangling. */
120 struct demangling_def
122 /* The full mangled name being mangled. */
125 /* Pointer into name at the current position. */
128 /* Stack for strings containing demangled result generated so far.
129 Text is emitted to the topmost (first) string. */
130 string_list_t result
;
132 /* The number of presently available substitutions. */
133 int num_substitutions
;
135 /* The allocated size of the substitutions array. */
136 int substitutions_allocated
;
138 /* An array of available substitutions. The number of elements in
139 the array is given by num_substitions, and the allocated array
140 size in substitutions_size.
142 The most recent substition is at the end, so
144 - `S_' corresponds to substititutions[num_substitutions - 1]
145 - `S0_' corresponds to substititutions[num_substitutions - 2]
148 struct substitution_def
*substitutions
;
150 /* The stack of template argument lists. */
151 template_arg_list_t template_arg_lists
;
153 /* The most recently demangled source-name. */
154 dyn_string_t last_source_name
;
157 typedef struct demangling_def
*demangling_t
;
159 /* This type is the standard return code from most functions. Values
160 other than STATUS_OK contain descriptive messages. */
161 typedef const char *status_t
;
163 /* Special values that can be used as a status_t. */
164 #define STATUS_OK NULL
165 #define STATUS_ERROR "Error."
166 #define STATUS_UNIMPLEMENTED "Unimplemented."
167 #define STATUS_INTERNAL_ERROR "Internal error."
169 static void int_to_dyn_string
170 PARAMS ((int, dyn_string_t
));
171 static string_list_t string_list_new
173 static void string_list_delete
174 PARAMS ((string_list_t
));
175 static void result_close_template_list
176 PARAMS ((demangling_t
));
177 static void result_push
178 PARAMS ((demangling_t
));
179 static string_list_t result_pop
180 PARAMS ((demangling_t
));
181 static int substitution_start
182 PARAMS ((demangling_t
));
183 static void substitution_add
184 PARAMS ((demangling_t
, int, int, int));
185 static dyn_string_t substitution_get
186 PARAMS ((demangling_t
, int, int *));
187 #ifdef CP_DEMANGLE_DEBUG
188 static void substitutions_print
189 PARAMS ((demangling_t
, FILE *));
191 static template_arg_list_t template_arg_list_new
193 static void template_arg_list_delete
194 PARAMS ((template_arg_list_t
));
195 static void template_arg_list_add_arg
196 PARAMS ((template_arg_list_t
, string_list_t
));
197 static string_list_t template_arg_list_get_arg
198 PARAMS ((template_arg_list_t
, int));
199 static void push_template_arg_list
200 PARAMS ((demangling_t
, template_arg_list_t
));
201 static void pop_to_template_arg_list
202 PARAMS ((demangling_t
, template_arg_list_t
));
203 #ifdef CP_DEMANGLE_DEBUG
204 static void template_arg_list_print
205 PARAMS ((template_arg_list_t
, FILE *));
207 static template_arg_list_t current_template_arg_list
208 PARAMS ((demangling_t
));
209 static demangling_t demangling_new
211 static void demangling_delete
212 PARAMS ((demangling_t
));
214 /* The last character of DS. Warning: DS is evaluated twice. */
215 #define dyn_string_last_char(DS) \
216 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
218 /* Append a space character (` ') to DS if it does not already end
220 #define dyn_string_append_space(DS) \
223 if (dyn_string_length (DS) > 0 \
224 && dyn_string_last_char (DS) != ' ') \
225 dyn_string_append_char ((DS), ' '); \
229 /* Returns the index of the current position in the mangled name. */
230 #define current_position(DM) ((DM)->next - (DM)->name)
232 /* Returns the character at the current position of the mangled name. */
233 #define peek_char(DM) (*((DM)->next))
235 /* Returns the character one past the current position of the mangled
237 #define peek_char_next(DM) \
238 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
240 /* Returns the character at the current position, and advances the
241 current position to the next character. */
242 #define next_char(DM) (*((DM)->next)++)
244 /* Returns non-zero if the current position is the end of the mangled
245 name, i.e. one past the last character. */
246 #define end_of_name_p(DM) (peek_char (DM) == '\0')
248 /* Advances the current position by one character. */
249 #define advance_char(DM) (++(DM)->next)
251 /* Returns the string containing the current demangled result. */
252 #define result_string(DM) (&(DM)->result->string)
254 /* Appends a dyn_string_t to the demangled result. */
255 #define result_append_string(DM, STRING) \
256 dyn_string_append (&(DM)->result->string, (STRING))
258 /* Appends NUL-terminated string CSTR to the demangled result. */
259 #define result_append(DM, CSTR) \
260 dyn_string_append_cstr (&(DM)->result->string, (CSTR))
262 /* Appends character CHAR to the demangled result. */
263 #define result_append_char(DM, CHAR) \
264 dyn_string_append_char (&(DM)->result->string, (CHAR))
266 /* The length of the current demangled result. */
267 #define result_length(DM) \
268 dyn_string_length (&(DM)->result->string)
270 /* Appends a space to the demangled result if the last character is
272 #define result_append_space(DM) \
273 dyn_string_append_space (&(DM)->result->string)
275 /* Evaluate EXPR, which must produce a status_t. If the status code
276 indicates an error, return from the current function with that
278 #define RETURN_IF_ERROR(EXPR) \
282 if (s != STATUS_OK) \
287 /* Appends a base 10 representation of VALUE to DS. */
290 int_to_dyn_string (value
, ds
)
297 /* Handle zero up front. */
300 dyn_string_append_char (ds
, '0');
304 /* For negative numbers, emit a minus sign. */
307 dyn_string_append_char (ds
, '-');
311 /* Find the power of 10 of the first digit. */
319 /* Write the digits. */
322 int digit
= value
/ mask
;
323 dyn_string_append_char (ds
, '0' + digit
);
324 value
-= digit
* mask
;
329 /* Creates a new string list node. The contents of the string are
330 empty, but the initial buffer allocation is LENGTH. The string
331 list node should be deleted with string_list_delete. */
334 string_list_new (length
)
338 (string_list_t
) xmalloc (sizeof (struct string_list_def
));
339 dyn_string_init ((dyn_string_t
) s
, length
);
343 /* Deletes the entire string list starting at NODE. */
346 string_list_delete (node
)
351 string_list_t next
= node
->next
;
357 /* Appends a greater-than character to the demangled result. If the
358 last character is a greater-than character, a space is inserted
359 first, so that the two greater-than characters don't look like a
360 right shift token. */
363 result_close_template_list (dm
)
366 dyn_string_t s
= &dm
->result
->string
;
367 if (dyn_string_last_char (s
) == '>')
368 dyn_string_append_char (s
, ' ');
369 dyn_string_append_char (s
, '>');
372 /* Allocates and pushes a new string onto the demangled results stack
373 for DM. Subsequent demangling with DM will emit to the new string. */
379 string_list_t new_string
= string_list_new (0);
380 new_string
->next
= (string_list_t
) dm
->result
;
381 dm
->result
= new_string
;
384 /* Removes and returns the topmost element on the demangled results
385 stack for DM. The caller assumes ownership for the returned
392 string_list_t top
= dm
->result
;
393 dm
->result
= top
->next
;
397 /* Returns the start position of a fragment of the demangled result
398 that will be a substitution candidate. Should be called at the
399 start of productions that can add substitutions. */
402 substitution_start (dm
)
405 return result_length (dm
);
408 /* Adds the suffix of the current demangled result of DM starting at
409 START_POSITION as a potential substitution. If TEMPLATE_P is
410 non-zero, this potential substitution is a template-id.
412 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
413 is for that particular <template-param>, and is distinct from other
414 otherwise-identical types and other <template-param>s with
415 different indices. */
418 substitution_add (dm
, start_position
, template_p
, template_parm_number
)
422 int template_parm_number
;
424 dyn_string_t result
= result_string (dm
);
425 dyn_string_t substitution
= dyn_string_new (0);
428 dyn_string_substring (substitution
,
429 result
, start_position
, result_length (dm
));
431 /* Check whether SUBSTITUTION already occurs. */
432 for (i
= 0; i
< dm
->num_substitutions
; ++i
)
433 if (dyn_string_eq (dm
->substitutions
[i
].text
, substitution
)
434 && dm
->substitutions
[i
].template_parm_number
== template_parm_number
)
435 /* Found SUBSTITUTION already present. */
437 /* Callers expect this function to take ownership of
438 SUBSTITUTION, so delete it. */
439 dyn_string_delete (substitution
);
443 /* If there's no room for the new entry, grow the array. */
444 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
446 dm
->substitutions_allocated
*= 2;
447 dm
->substitutions
= (struct substitution_def
*)
448 xrealloc (dm
->substitutions
,
449 sizeof (struct substitution_def
)
450 * dm
->substitutions_allocated
);
453 /* Add the substitution to the array. */
454 dm
->substitutions
[i
].text
= substitution
;
455 dm
->substitutions
[i
].template_p
= template_p
;
456 dm
->substitutions
[i
].template_parm_number
= template_parm_number
;
457 ++dm
->num_substitutions
;
459 #ifdef CP_DEMANGLE_DEBUG
460 substitutions_print (dm
, stderr
);
464 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
465 non-zero if the substitution is a template-id, zero otherwise.
466 N is numbered from zero. DM retains ownership of the returned
467 string. If N is negative, or equal to or greater than the current
468 number of substitution candidates, returns NULL. */
471 substitution_get (dm
, n
, template_p
)
476 struct substitution_def
*sub
;
478 /* Make sure N is in the valid range. */
479 if (n
< 0 || n
>= dm
->num_substitutions
)
482 sub
= &(dm
->substitutions
[n
]);
483 *template_p
= sub
->template_p
;
487 #ifdef CP_DEMANGLE_DEBUG
488 /* Debugging routine to print the current substitutions to FP. */
491 substitutions_print (dm
, fp
)
496 int num
= dm
->num_substitutions
;
498 fprintf (fp
, "SUBSTITUTIONS:\n");
499 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
502 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
505 fprintf (fp
, " S_ ");
507 fprintf (fp
, " S%d_", seq_id
);
508 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
512 #endif /* CP_DEMANGLE_DEBUG */
514 /* Creates a new template argument list. */
516 static template_arg_list_t
517 template_arg_list_new ()
519 template_arg_list_t new_list
520 = (template_arg_list_t
) xmalloc (sizeof (struct template_arg_list_def
));
521 /* Initialize the new list to have no arguments. */
522 new_list
->first_argument
= NULL
;
523 new_list
->last_argument
= NULL
;
524 /* Return the new list. */
528 /* Deletes a template argument list and the template arguments it
532 template_arg_list_delete (list
)
533 template_arg_list_t list
;
535 /* If there are any arguments on LIST, delete them. */
536 if (list
->first_argument
!= NULL
)
537 string_list_delete (list
->first_argument
);
542 /* Adds ARG to the template argument list ARG_LIST. */
545 template_arg_list_add_arg (arg_list
, arg
)
546 template_arg_list_t arg_list
;
549 if (arg_list
->first_argument
== NULL
)
550 /* If there were no arguments before, ARG is the first one. */
551 arg_list
->first_argument
= arg
;
553 /* Make ARG the last argument on the list. */
554 arg_list
->last_argument
->next
= arg
;
555 /* Make ARG the last on the list. */
556 arg_list
->last_argument
= arg
;
560 /* Returns the template arugment at position INDEX in template
561 argument list ARG_LIST. */
564 template_arg_list_get_arg (arg_list
, index
)
565 template_arg_list_t arg_list
;
568 string_list_t arg
= arg_list
->first_argument
;
569 /* Scan down the list of arguments to find the one at position
575 /* Ran out of arguments before INDEX hit zero. That's an
579 /* Return the argument at position INDEX. */
583 /* Pushes ARG_LIST onto the top of the template argument list stack. */
586 push_template_arg_list (dm
, arg_list
)
588 template_arg_list_t arg_list
;
590 arg_list
->next
= dm
->template_arg_lists
;
591 dm
->template_arg_lists
= arg_list
;
592 #ifdef CP_DEMANGLE_DEBUG
593 fprintf (stderr
, " ** pushing template arg list\n");
594 template_arg_list_print (arg_list
, stderr
);
598 /* Pops and deletes elements on the template argument list stack until
599 arg_list is the topmost element. If arg_list is NULL, all elements
600 are popped and deleted. */
603 pop_to_template_arg_list (dm
, arg_list
)
605 template_arg_list_t arg_list
;
607 while (dm
->template_arg_lists
!= arg_list
)
609 template_arg_list_t top
= dm
->template_arg_lists
;
610 /* Disconnect the topmost element from the list. */
611 dm
->template_arg_lists
= top
->next
;
612 /* Delete the popped element. */
613 template_arg_list_delete (top
);
614 #ifdef CP_DEMANGLE_DEBUG
615 fprintf (stderr
, " ** removing template arg list\n");
620 #ifdef CP_DEMANGLE_DEBUG
622 /* Prints the contents of ARG_LIST to FP. */
625 template_arg_list_print (arg_list
, fp
)
626 template_arg_list_t arg_list
;
632 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
633 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
636 fprintf (fp
, " T_ : ");
638 fprintf (fp
, " T%d_ : ", index
);
640 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
644 #endif /* CP_DEMANGLE_DEBUG */
646 /* Returns the topmost element on the stack of template argument
647 lists. If there is no list of template arguments, returns NULL. */
649 static template_arg_list_t
650 current_template_arg_list (dm
)
653 return dm
->template_arg_lists
;
656 /* Allocates a demangling_t object for demangling mangled NAME. A new
657 result must be pushed before the returned object can be used. */
660 demangling_new (name
)
663 demangling_t dm
= (demangling_t
)
664 xmalloc (sizeof (struct demangling_def
));
669 dm
->last_source_name
= dyn_string_new (0);
670 dm
->num_substitutions
= 0;
671 dm
->substitutions_allocated
= 10;
672 dm
->substitutions
= (struct substitution_def
*)
673 xmalloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
674 dm
->template_arg_lists
= NULL
;
679 /* Deallocates a demangling_t object and all memory associated with
683 demangling_delete (dm
)
687 template_arg_list_t arg_list
= dm
->template_arg_lists
;
689 /* Delete the stack of template argument lists. */
690 while (arg_list
!= NULL
)
692 template_arg_list_t next
= arg_list
->next
;
693 template_arg_list_delete (arg_list
);
696 /* Delete the list of substitutions. */
697 for (i
= dm
->num_substitutions
; --i
>= 0; )
698 dyn_string_delete (dm
->substitutions
[i
].text
);
699 free (dm
->substitutions
);
700 /* Delete the demangled result. */
701 string_list_delete (dm
->result
);
702 /* Delete the stored identifier name. */
703 dyn_string_delete (dm
->last_source_name
);
704 /* Delete the context object itself. */
708 /* These functions demangle an alternative of the corresponding
709 production in the mangling spec. The first argument of each is a
710 demangling context structure for the current demangling
711 operation. Most emit demangled text directly to the topmost result
712 string on the result string stack in the demangling context
715 static status_t demangle_char
716 PARAMS ((demangling_t
, char));
717 static status_t demangle_mangled_name
718 PARAMS ((demangling_t
));
719 static status_t demangle_encoding
720 PARAMS ((demangling_t
));
721 static status_t demangle_name
722 PARAMS ((demangling_t
, int *));
723 static status_t demangle_nested_name
724 PARAMS ((demangling_t
, int *));
725 static status_t demangle_prefix
726 PARAMS ((demangling_t
, int *));
727 static status_t demangle_unqualified_name
728 PARAMS ((demangling_t
));
729 static status_t demangle_source_name
730 PARAMS ((demangling_t
));
731 static status_t demangle_number
732 PARAMS ((demangling_t
, int *, int, int));
733 static status_t demangle_number_literally
734 PARAMS ((demangling_t
, dyn_string_t
, int, int));
735 static status_t demangle_identifier
736 PARAMS ((demangling_t
, int, dyn_string_t
));
737 static status_t demangle_operator_name
738 PARAMS ((demangling_t
, int, int *));
739 static status_t demangle_special_name
740 PARAMS ((demangling_t
));
741 static status_t demangle_ctor_dtor_name
742 PARAMS ((demangling_t
));
743 static status_t demangle_type_ptr
744 PARAMS ((demangling_t
));
745 static status_t demangle_type
746 PARAMS ((demangling_t
));
747 static status_t demangle_CV_qualifiers
748 PARAMS ((demangling_t
, dyn_string_t
));
749 static status_t demangle_builtin_type
750 PARAMS ((demangling_t
));
751 static status_t demangle_function_type
752 PARAMS ((demangling_t
, int));
753 static status_t demangle_bare_function_type
754 PARAMS ((demangling_t
, int));
755 static status_t demangle_class_enum_type
756 PARAMS ((demangling_t
, int *));
757 static status_t demangle_array_type
758 PARAMS ((demangling_t
));
759 static status_t demangle_template_param
760 PARAMS ((demangling_t
, int *));
761 static status_t demangle_template_args
762 PARAMS ((demangling_t
));
763 static status_t demangle_literal
764 PARAMS ((demangling_t
));
765 static status_t demangle_template_arg
766 PARAMS ((demangling_t
));
767 static status_t demangle_expression
768 PARAMS ((demangling_t
));;
769 static status_t demangle_scope_expression
770 PARAMS ((demangling_t
));
771 static status_t demangle_expr_primary
772 PARAMS ((demangling_t
));;
773 static status_t demangle_substitution
774 PARAMS ((demangling_t
, int *, int *));
775 static status_t demangle_local_name
776 PARAMS ((demangling_t
));
777 static status_t demangle_discriminator
778 PARAMS ((demangling_t
, int));
779 static status_t cp_demangle
780 PARAMS ((char *, dyn_string_t
));
782 /* When passed to demangle_bare_function_type, indicates that the
783 function's return type is not encoded before its parameter types. */
784 #define BFT_NO_RETURN_TYPE -1
786 /* Check that the next character is C. If so, consume it. If not,
790 demangle_char (dm
, c
)
794 static char *error_message
= NULL
;
796 if (peek_char (dm
) == c
)
803 if (error_message
== NULL
)
804 error_message
= strdup ("Expected ?");
805 error_message
[9] = c
;
806 return error_message
;
810 /* Demangles and emits a <mangled-name>.
812 <mangled-name> ::= _Z <encoding> */
815 demangle_mangled_name (dm
)
818 DEMANGLE_TRACE ("mangled-name", dm
);
819 RETURN_IF_ERROR (demangle_char (dm
, '_'));
820 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
821 RETURN_IF_ERROR (demangle_encoding (dm
));
825 /* Demangles and emits an <encoding>.
827 <encoding> ::= <function name> <bare-function-type>
829 ::= <substitution> */
832 demangle_encoding (dm
)
836 int special_std_substitution
;
838 int start
= substitution_start (dm
);
839 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
840 char peek
= peek_char (dm
);
842 DEMANGLE_TRACE ("encoding", dm
);
844 /* Remember where the name starts. If it turns out to be a template
845 function, we'll have to insert the return type here. */
846 start_position
= result_length (dm
);
850 RETURN_IF_ERROR (demangle_substitution (dm
, &template_p
,
851 &special_std_substitution
));
852 if (special_std_substitution
)
854 /* This was the magic `std::' substitution. */
855 result_append (dm
, "::");
856 RETURN_IF_ERROR (demangle_encoding (dm
));
859 else if (peek
== 'G' || peek
== 'T')
860 RETURN_IF_ERROR (demangle_special_name (dm
));
863 /* Now demangle the name. */
864 RETURN_IF_ERROR (demangle_name (dm
, &template_p
));
866 /* If there's anything left, the name was a function name, with
867 maybe its return type, and its parameters types, following. */
868 if (!end_of_name_p (dm
)
869 && peek_char (dm
) != 'E')
872 /* Template functions have their return type encoded. The
873 return type should be inserted at start_position. */
875 (demangle_bare_function_type (dm
, start_position
));
877 /* Non-template functions don't have their return type
880 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
883 substitution_add (dm
, start
, template_p
, NOT_TEMPLATE_PARM
);
886 /* Pop off template argument lists that were built during the
887 mangling of this name, to restore the old template context. */
888 pop_to_template_arg_list (dm
, old_arg_list
);
893 /* Demangles and emits a <name>.
895 <name> ::= <unscoped-name>
896 ::= <unscoped-template-name> <template-args>
900 <unscoped-name> ::= <unqualified-name>
901 ::= St <unqualified-name> # ::std::
903 <unscoped-template-name>
905 ::= <substitution> */
908 demangle_name (dm
, template_p
)
912 int special_std_substitution
;
913 int start
= substitution_start (dm
);
915 DEMANGLE_TRACE ("name", dm
);
917 switch (peek_char (dm
))
920 /* This is a <nested-name>. */
921 RETURN_IF_ERROR (demangle_nested_name (dm
, template_p
));
925 RETURN_IF_ERROR (demangle_local_name (dm
));
929 /* The `St' substitution allows a name nested in std:: to appear
930 without being enclosed in a nested name.
931 <name> ::= St <unqualified-name> # ::std:: */
932 if (peek_char_next (dm
) == 't')
934 (void) next_char (dm
);
935 (void) next_char (dm
);
936 result_append (dm
, "std::");
937 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
941 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
,
942 &special_std_substitution
));
943 if (special_std_substitution
)
945 /* This was the magic `std::' substitution. We can have
946 a <nested-name> or one of the unscoped names
948 result_append (dm
, "::");
949 RETURN_IF_ERROR (demangle_name (dm
, template_p
));
955 /* This is an <unscoped-name> or <unscoped-template-name>. */
956 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
958 /* If the <unqualified-name> is followed by template args, this
959 is an <unscoped-template-name>. */
960 if (peek_char (dm
) == 'I')
962 /* Add a substitution for the unqualified template name. */
963 substitution_add (dm
, start
, 0, NOT_TEMPLATE_PARM
);
965 RETURN_IF_ERROR (demangle_template_args (dm
));
977 /* Demangles and emits a <nested-name>.
979 <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */
982 demangle_nested_name (dm
, template_p
)
988 DEMANGLE_TRACE ("nested-name", dm
);
990 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
992 peek
= peek_char (dm
);
993 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
995 /* Snarf up and emit CV qualifiers. */
996 dyn_string_t cv_qualifiers
= dyn_string_new (24);
997 demangle_CV_qualifiers (dm
, cv_qualifiers
);
998 result_append_string (dm
, cv_qualifiers
);
999 dyn_string_delete (cv_qualifiers
);
1000 result_append_space (dm
);
1003 RETURN_IF_ERROR (demangle_prefix (dm
, template_p
));
1004 /* No need to demangle the final <component>; demangle_prefix will
1006 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1011 /* Demangles and emits a <prefix>.
1013 <prefix> ::= <prefix> <component>
1014 ::= <template-prefix> <template-args>
1018 <template-prefix> ::= <prefix>
1021 <component> ::= <unqualified-name>
1025 demangle_prefix (dm
, template_p
)
1029 int start
= substitution_start (dm
);
1032 /* TEMPLATE_P is updated as we decend the nesting chain. After
1033 <template-args>, it is set to non-zero; after everything else it
1036 DEMANGLE_TRACE ("prefix", dm
);
1043 if (end_of_name_p (dm
))
1044 return "Unexpected end of name in <compound-name>.";
1046 peek
= peek_char (dm
);
1048 if (isdigit ((unsigned char) peek
)
1049 || (peek
>= 'a' && peek
<= 'z')
1050 || peek
== 'C' || peek
== 'D'
1053 /* We have another level of scope qualification. */
1055 result_append (dm
, "::");
1060 /* The substitution determines whether this is a
1062 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
,
1066 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1070 else if (peek
== 'Z')
1071 RETURN_IF_ERROR (demangle_local_name (dm
));
1072 else if (peek
== 'I')
1075 return STATUS_INTERNAL_ERROR
;
1076 /* The template name is a substitution candidate. */
1077 substitution_add (dm
, start
, 0, NOT_TEMPLATE_PARM
);
1078 RETURN_IF_ERROR (demangle_template_args (dm
));
1081 else if (peek
== 'E')
1085 return "Unexpected character in <compound-name>.";
1087 /* Add a new substitution for the prefix thus far. */
1088 substitution_add (dm
, start
, *template_p
, NOT_TEMPLATE_PARM
);
1092 /* Demangles and emits an <unqualified-name>. If the
1093 <unqualified-name> is a function and the first element in the
1094 argument list should be taken to be its return type,
1095 ENCODE_RETURN_TYPE is non-zero.
1097 <unqualified-name> ::= <operator-name>
1099 ::= <source-name> */
1102 demangle_unqualified_name (dm
)
1105 char peek
= peek_char (dm
);
1107 DEMANGLE_TRACE ("unqualified-name", dm
);
1109 if (isdigit ((unsigned char) peek
))
1110 RETURN_IF_ERROR (demangle_source_name (dm
));
1111 else if (peek
>= 'a' && peek
<= 'z')
1114 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1116 else if (peek
== 'C' || peek
== 'D')
1117 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1119 return "Unexpected character in <unqualified-name>.";
1124 /* Demangles and emits <source-name>.
1126 <source-name> ::= <length number> <identifier> */
1129 demangle_source_name (dm
)
1134 DEMANGLE_TRACE ("source-name", dm
);
1136 /* Decode the length of the identifier. */
1137 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1139 return "Zero length in <source-name>.";
1141 /* Now the identifier itself. It's placed into last_source_name,
1142 where it can be used to build a constructor or destructor name. */
1143 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1144 dm
->last_source_name
));
1147 result_append_string (dm
, dm
->last_source_name
);
1152 /* Demangles a number, either a <number> or a <positive-number> at the
1153 current position, consuming all consecutive digit characters. Sets
1154 *VALUE to the resulting numberand returns STATUS_OK. The number is
1155 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1156 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1158 <number> ::= [n] <positive-number>
1160 <positive-number> ::= <decimal integer> */
1163 demangle_number (dm
, value
, base
, is_signed
)
1169 dyn_string_t number
= dyn_string_new (10);
1171 DEMANGLE_TRACE ("number", dm
);
1173 demangle_number_literally (dm
, number
, base
, is_signed
);
1174 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1175 dyn_string_delete (number
);
1180 /* Demangles a number at the current position. The digits (and minus
1181 sign, if present) that make up the number are appended to STR.
1182 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1183 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1184 accepted. Does not consume a trailing underscore or other
1185 terminating character. */
1188 demangle_number_literally (dm
, str
, base
, is_signed
)
1194 DEMANGLE_TRACE ("number*", dm
);
1196 if (base
!= 10 && base
!= 36)
1197 return STATUS_INTERNAL_ERROR
;
1199 /* An `n' denotes a negative number. */
1200 if (is_signed
&& peek_char (dm
) == 'n')
1202 /* Skip past the n. */
1204 /* The normal way to write a negative number is with a minus
1206 dyn_string_append_char (str
, '-');
1209 /* Loop until we hit a non-digit. */
1212 char peek
= peek_char (dm
);
1213 if (isdigit ((unsigned char) peek
)
1214 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1215 /* Accumulate digits. */
1216 dyn_string_append_char (str
, next_char (dm
));
1218 /* Not a digit? All done. */
1225 /* Demangles an identifier at the current position of LENGTH
1226 characters and places it in IDENTIFIER. */
1229 demangle_identifier (dm
, length
, identifier
)
1232 dyn_string_t identifier
;
1234 DEMANGLE_TRACE ("identifier", dm
);
1236 dyn_string_clear (identifier
);
1237 dyn_string_resize (identifier
, length
);
1238 while (length
-- > 0)
1240 if (end_of_name_p (dm
))
1241 return "Unexpected end of name in <identifier>.";
1242 dyn_string_append_char (identifier
, next_char (dm
));
1248 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1249 the short form is emitted; otherwise the full source form
1250 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1251 operands that the operator takes.
1302 ::= cv <type> # cast
1303 ::= vx <source-name> # vendor extended operator */
1306 demangle_operator_name (dm
, short_name
, num_args
)
1311 struct operator_code
1313 /* The mangled code for this operator. */
1315 /* The source name of this operator. */
1317 /* The number of arguments this operator takes. */
1321 static const struct operator_code operators
[] =
1332 { "da", "delete[]" , 1 },
1334 { "dl", "delete" , 1 },
1342 { "lS", "<<=" , 2 },
1351 { "na", "new[]" , 1 },
1355 { "nw", "new" , 1 },
1361 { "pm", "->*" , 2 },
1366 { "rS", ">>=" , 2 },
1369 { "sz", "sizeof" , 1 }
1372 const int num_operators
=
1373 sizeof (operators
) / sizeof (struct operator_code
);
1375 int c0
= next_char (dm
);
1376 int c1
= next_char (dm
);
1377 const struct operator_code
* p1
= operators
;
1378 const struct operator_code
* p2
= operators
+ num_operators
;
1380 DEMANGLE_TRACE ("operator-name", dm
);
1382 /* Is this a vendor extended operator? */
1383 if (c0
== 'v' && c1
== 'x')
1385 result_append (dm
, "operator");
1386 RETURN_IF_ERROR (demangle_source_name (dm
));
1391 /* Is this a conversion operator? */
1392 if (c0
== 'c' && c1
== 'v')
1394 result_append (dm
, "operator ");
1395 /* Demangle the converted-to type. */
1396 RETURN_IF_ERROR (demangle_type (dm
));
1401 /* Perform a binary search for the operator code. */
1404 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1405 char match0
= p
->code
[0];
1406 char match1
= p
->code
[1];
1408 if (c0
== match0
&& c1
== match1
)
1412 result_append (dm
, "operator");
1413 result_append (dm
, p
->name
);
1414 *num_args
= p
->num_args
;
1420 /* Couldn't find it. */
1421 return "Unknown code in <operator-name>.";
1424 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1431 /* Demangles and emits a <special-name>.
1433 <special-name> ::= GV <object name> # Guard variable
1434 ::= Th[n] <offset number> _ <base name> <base encoding>
1435 # non-virtual base override thunk
1436 ::= Tv[n] <offset number> _ <vcall offset number>
1438 # virtual base override thunk
1439 ::= TV <type> # virtual table
1441 ::= TI <type> # typeinfo structure
1442 ::= TS <type> # typeinfo name
1444 Also demangles the special g++ mangling,
1446 <special-name> ::= CT <type> <offset number> _ <base type>
1447 # construction vtable */
1450 demangle_special_name (dm
)
1453 dyn_string_t number
;
1455 char peek
= peek_char (dm
);
1457 DEMANGLE_TRACE ("special-name", dm
);
1461 /* A guard variable name. Consume the G. */
1463 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1464 result_append (dm
, "guard variable for ");
1465 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1467 else if (peek
== 'T')
1469 /* Other C++ implementation miscellania. Consume the T. */
1472 switch (peek_char (dm
))
1475 /* Virtual table. */
1477 result_append (dm
, "vtable for ");
1478 RETURN_IF_ERROR (demangle_type (dm
));
1482 /* VTT structure. */
1484 result_append (dm
, "VTT for ");
1485 RETURN_IF_ERROR (demangle_type (dm
));
1489 /* Typeinfo structure. */
1491 result_append (dm
, "typeinfo for ");
1492 RETURN_IF_ERROR (demangle_type (dm
));
1496 /* Character string containing type name, used in typeinfo. */
1498 result_append (dm
, "typeinfo name for ");
1499 RETURN_IF_ERROR (demangle_type (dm
));
1503 /* Non-virtual thunk. */
1505 result_append (dm
, "non-virtual thunk");
1506 /* Demangle and emit the offset. */
1507 number
= dyn_string_new (4);
1508 demangle_number_literally (dm
, number
, 10, 1);
1509 /* Don't display the offset unless in verbose mode. */
1512 result_append_char (dm
, ' ');
1513 result_append_string (dm
, number
);
1515 dyn_string_delete (number
);
1516 /* Demangle the separator. */
1517 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1518 /* Demangle and emit the target name and function type. */
1519 result_append (dm
, " to ");
1520 RETURN_IF_ERROR (demangle_encoding (dm
));
1524 /* Virtual thunk. */
1526 result_append (dm
, "virtual thunk ");
1527 /* Demangle and emit the offset. */
1528 number
= dyn_string_new (4);
1529 demangle_number_literally (dm
, number
, 10, 1);
1530 /* Don't display the offset unless in verbose mode. */
1533 result_append_string (dm
, number
);
1534 result_append_char (dm
, ' ');
1536 dyn_string_delete (number
);
1537 /* Demangle the separator. */
1538 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1539 /* Demangle and emit the vcall offset. */
1540 number
= dyn_string_new (4);
1541 demangle_number_literally (dm
, number
, 10, 1);
1542 /* Don't display the vcall offset unless in verbose mode. */
1545 result_append_string (dm
, number
);
1546 result_append_char (dm
, ' ');
1548 dyn_string_delete (number
);
1549 /* Demangle the separator. */
1550 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1551 /* Demangle and emit the target function. */
1552 result_append (dm
, "to ");
1553 RETURN_IF_ERROR (demangle_encoding (dm
));
1557 /* TC is a special g++ mangling for a construction vtable. */
1561 result_append (dm
, "construction vtable for ");
1562 RETURN_IF_ERROR (demangle_type (dm
));
1563 /* Demangle the offset. */
1564 number
= dyn_string_new (4);
1565 demangle_number_literally (dm
, number
, 10, 1);
1566 /* Demangle the underscore separator. */
1567 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1568 /* Demangle the base type. */
1569 result_append (dm
, "-in-");
1570 RETURN_IF_ERROR (demangle_type (dm
));
1571 /* Don't display the offset unless in verbose mode. */
1574 result_append_char (dm
, ' ');
1575 result_append_string (dm
, number
);
1577 dyn_string_delete (number
);
1580 /* If flag_strict, fall through. */
1583 return "Unrecognized <special-name>.";
1587 return STATUS_ERROR
;
1592 /* Demangles and emits a <ctor-dtor-name>.
1595 ::= C1 # complete object (in-charge) ctor
1596 ::= C2 # base object (not-in-charge) ctor
1597 ::= C3 # complete object (in-charge) allocating ctor
1598 ::= C4 # base object (not-in-charge) allocating ctor
1599 ::= D0 # deleting (in-charge) dtor
1600 ::= D1 # complete object (in-charge) dtor
1601 ::= D2 # base object (not-in-charge) dtor */
1604 demangle_ctor_dtor_name (dm
)
1607 static const char *const ctor_flavors
[] =
1611 "in-charge allocating",
1612 "not-in-charge allocating"
1614 static const char *const dtor_flavors
[] =
1616 "in-charge deleting",
1622 char peek
= peek_char (dm
);
1624 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
1628 /* A constructor name. Consume the C. */
1630 if (peek_char (dm
) < '1' || peek_char (dm
) > '4')
1631 return "Unrecognized constructor.";
1632 result_append_string (dm
, dm
->last_source_name
);
1633 /* Print the flavor of the constructor if in verbose mode. */
1634 flavor
= next_char (dm
) - '1';
1637 result_append (dm
, "[");
1638 result_append (dm
, ctor_flavors
[flavor
]);
1639 result_append_char (dm
, ']');
1642 else if (peek
== 'D')
1644 /* A destructor name. Consume the D. */
1646 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
1647 return "Unrecognized destructor.";
1648 result_append_char (dm
, '~');
1649 result_append_string (dm
, dm
->last_source_name
);
1650 /* Print the flavor of the destructor if in verbose mode. */
1651 flavor
= next_char (dm
) - '0';
1654 result_append (dm
, " [");
1655 result_append (dm
, dtor_flavors
[flavor
]);
1656 result_append_char (dm
, ']');
1660 return STATUS_ERROR
;
1665 /* Handle pointer, reference, and pointer-to-member cases for
1666 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1667 build a pointer/reference type. We snarf all these, plus the
1668 following <type>, all at once since we need to know whether we have
1669 a pointer to data or pointer to function to construct the right
1670 output syntax. C++'s pointer syntax is hairy.
1674 ::= <pointer-to-member-type>
1676 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1679 demangle_type_ptr (dm
)
1685 /* Collect pointer symbols into this string. */
1686 dyn_string_t symbols
= dyn_string_new (10);
1688 DEMANGLE_TRACE ("type*", dm
);
1690 /* Scan forward, collecting pointers and references into symbols,
1691 until we hit something else. Then emit the type. */
1694 next
= peek_char (dm
);
1697 dyn_string_append_char (symbols
, '*');
1700 else if (next
== 'R')
1702 dyn_string_append_char (symbols
, '&');
1705 else if (next
== 'M')
1707 /* Pointer-to-member. */
1708 dyn_string_t class_type
;
1713 /* Capture the type of which this is a pointer-to-member. */
1715 RETURN_IF_ERROR (demangle_type (dm
));
1716 class_type
= (dyn_string_t
) result_pop (dm
);
1718 /* Build the pointer-to-member notation. It comes before
1719 other pointer and reference qualifiers -- */
1720 dyn_string_prepend_cstr (symbols
, "::*");
1721 dyn_string_prepend (symbols
, class_type
);
1722 dyn_string_delete (class_type
);
1724 if (peek_char (dm
) == 'F')
1727 /* Demangle the type of the pointed-to member. */
1728 status
= demangle_type (dm
);
1729 /* Make it pretty. */
1730 result_append_space (dm
);
1731 /* Add the pointer-to-member syntax, and other pointer and
1732 reference symbols. */
1733 result_append_string (dm
, symbols
);
1735 dyn_string_delete (symbols
);
1737 RETURN_IF_ERROR (status
);
1740 else if (next
== 'F')
1742 /* Ooh, tricky, a pointer-to-function. */
1743 int position
= result_length (dm
);
1744 result_append_char (dm
, '(');
1745 result_append_string (dm
, symbols
);
1746 result_append_char (dm
, ')');
1747 dyn_string_delete (symbols
);
1749 RETURN_IF_ERROR (demangle_function_type (dm
, position
));
1754 /* No more pointe or reference tokens. Finish up. */
1755 status
= demangle_type (dm
);
1757 result_append_string (dm
, symbols
);
1758 dyn_string_delete (symbols
);
1760 RETURN_IF_ERROR (status
);
1766 /* Demangles and emits a <type>.
1768 <type> ::= <builtin-type>
1770 ::= <class-enum-type>
1772 ::= <pointer-to-member-type>
1773 ::= <template-param>
1774 ::= <CV-qualifiers> <type>
1775 ::= P <type> # pointer-to
1776 ::= R <type> # reference-to
1777 ::= C <type> # complex pair (C 2000)
1778 ::= G <type> # imaginary (C 2000)
1779 ::= U <source-name> <type> # vendor extended type qualifier
1780 ::= <substitution> */
1786 int start
= substitution_start (dm
);
1787 char peek
= peek_char (dm
);
1789 int special_std_substitution
;
1790 int is_builtin_type
= 0;
1791 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1792 int template_parm
= NOT_TEMPLATE_PARM
;
1794 DEMANGLE_TRACE ("type", dm
);
1796 /* A <class-enum-type> can start with a digit (a <source-name>), an
1797 N (a <nested-name>), or a Z (a <local-name>). */
1798 if (isdigit ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
1799 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &template_p
));
1800 else if (peek
>= 'a' && peek
<= 'z')
1802 RETURN_IF_ERROR (demangle_builtin_type (dm
));
1803 is_builtin_type
= 1;
1813 dyn_string_t cv_qualifiers
= dyn_string_new (24);
1814 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1816 /* If the qualifiers apply to a pointer or reference, they
1817 need to come after the whole qualified type. */
1818 if (peek_char (dm
) == 'P' || peek_char (dm
) == 'R')
1820 status
= demangle_type (dm
);
1821 result_append_space (dm
);
1822 result_append_string (dm
, cv_qualifiers
);
1824 /* Otherwise, the qualifiers come first. */
1827 result_append_string (dm
, cv_qualifiers
);
1828 result_append_space (dm
);
1829 status
= demangle_type (dm
);
1832 dyn_string_delete (cv_qualifiers
);
1833 RETURN_IF_ERROR (status
);
1838 return "Non-pointer or -reference function type.";
1841 RETURN_IF_ERROR (demangle_array_type (dm
));
1845 RETURN_IF_ERROR (demangle_template_param (dm
, &template_parm
));
1849 RETURN_IF_ERROR (demangle_substitution (dm
, &template_p
,
1850 &special_std_substitution
));
1851 if (special_std_substitution
)
1853 /* This was the magic `std::' substitution. What follows
1854 must be a class name in that namespace. */
1855 result_append (dm
, "::");
1856 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &template_p
));
1863 RETURN_IF_ERROR (demangle_type_ptr (dm
));
1867 /* A C99 complex type. */
1868 result_append (dm
, "complex ");
1870 RETURN_IF_ERROR (demangle_type (dm
));
1874 /* A C99 imaginary type. */
1875 result_append (dm
, "imaginary ");
1877 RETURN_IF_ERROR (demangle_type (dm
));
1881 /* Vendor extended type qualifier. */
1883 RETURN_IF_ERROR (demangle_source_name (dm
));
1884 result_append_char (dm
, ' ');
1885 RETURN_IF_ERROR (demangle_type (dm
));
1889 return "Unexpected character in <type>.";
1892 /* Unqualified builin types are not substitution candidates. */
1893 if (!is_builtin_type
)
1894 /* Add a new substitution for the type. If this type was a
1895 <template-param>, pass its index since from the point of
1896 substitutions, a <template-param> token is a substitution
1897 candidate distinct from the type that is substituted for it. */
1898 substitution_add (dm
, start
, template_p
, template_parm
);
1900 /* Pop off template argument lists added during mangling of this
1902 pop_to_template_arg_list (dm
, old_arg_list
);
1907 /* C++ source names of builtin types, indexed by the mangled code
1908 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
1909 static const char *const builtin_type_names
[26] =
1911 "signed char", /* a */
1915 "long double", /* e */
1917 "__float128", /* g */
1918 "unsigned char", /* h */
1923 "unsigned long", /* m */
1925 "unsigned __int128", /* o */
1930 "unsigned short", /* t */
1934 "long long", /* x */
1935 "unsigned long long", /* y */
1939 /* Demangles and emits a <builtin-type>.
1941 <builtin-type> ::= v # void
1946 ::= h # unsigned char
1948 ::= t # unsigned short
1950 ::= j # unsigned int
1952 ::= m # unsigned long
1953 ::= x # long long, __int64
1954 ::= y # unsigned long long, __int64
1956 ::= o # unsigned __int128
1959 ::= e # long double, __float80
1962 ::= u <source-name> # vendor extended type */
1965 demangle_builtin_type (dm
)
1969 char code
= peek_char (dm
);
1971 DEMANGLE_TRACE ("builtin-type", dm
);
1976 RETURN_IF_ERROR (demangle_source_name (dm
));
1979 else if (code
>= 'a' && code
<= 'z')
1981 const char *type_name
= builtin_type_names
[code
- 'a'];
1982 if (type_name
== NULL
)
1983 return "Unrecognized <builtin-type> code.";
1985 result_append (dm
, type_name
);
1990 return "Non-alphabetic <builtin-type> code.";
1993 /* Demangles all consecutive CV-qualifiers (const, volatile, and
1994 restrict) at the current position. The qualifiers are appended to
1995 QUALIFIERS. Returns STATUS_OK. */
1998 demangle_CV_qualifiers (dm
, qualifiers
)
2000 dyn_string_t qualifiers
;
2002 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2006 switch (peek_char (dm
))
2009 dyn_string_append_space (qualifiers
);
2010 dyn_string_append_cstr (qualifiers
, "restrict");
2014 dyn_string_append_space (qualifiers
);
2015 dyn_string_append_cstr (qualifiers
, "volatile");
2019 dyn_string_append_space (qualifiers
);
2020 dyn_string_append_cstr (qualifiers
, "const");
2031 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2032 position in the result string of the start of the function
2033 identifier, at which the function's return type will be inserted.
2035 <function-type> ::= F [Y] <bare-function-type> E */
2038 demangle_function_type (dm
, function_name_pos
)
2040 int function_name_pos
;
2042 DEMANGLE_TRACE ("function-type", dm
);
2043 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2044 if (peek_char (dm
) == 'Y')
2046 /* Indicate this function has C linkage if in verbose mode. */
2048 result_append (dm
, " [extern \"C\"] ");
2051 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2052 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2056 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2057 position in the result string at which the function return type
2058 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2059 function's return type is assumed not to be encoded.
2061 <bare-function-type> ::= <signature type>+ */
2064 demangle_bare_function_type (dm
, return_type_pos
)
2066 int return_type_pos
;
2068 /* Sequence is the index of the current function parameter, counting
2069 from zero. The value -1 denotes the return type. */
2071 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2073 DEMANGLE_TRACE ("bare-function-type", dm
);
2075 result_append_char (dm
, '(');
2076 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2079 /* We're decoding the function's return type. */
2081 dyn_string_t return_type
;
2083 /* Decode the return type off to the side. */
2085 RETURN_IF_ERROR (demangle_type (dm
));
2086 return_type
= (dyn_string_t
) result_pop (dm
);
2088 /* Add a space to the end of the type. */
2089 dyn_string_append_space (return_type
);
2091 /* Insert the return type where we've been asked to. */
2092 dyn_string_insert (result_string (dm
), return_type_pos
,
2094 dyn_string_delete (return_type
);
2098 /* Skip `void' parameter types. One should only occur as
2099 the only type in a parameter list; in that case, we want
2100 to print `foo ()' instead of `foo (void)'. */
2101 if (peek_char (dm
) == 'v')
2103 /* Consume the v. */
2107 /* Separate parameter types by commas. */
2109 result_append (dm
, ", ");
2110 /* Demangle the type. */
2111 RETURN_IF_ERROR (demangle_type (dm
));
2116 result_append_char (dm
, ')');
2121 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2122 non-zero if the type is a template-id, zero otherwise.
2124 <class-enum-type> ::= <name> */
2127 demangle_class_enum_type (dm
, template_p
)
2131 DEMANGLE_TRACE ("class-enum-type", dm
);
2133 RETURN_IF_ERROR (demangle_name (dm
, template_p
));
2137 /* Demangles and emits an <array-type>.
2139 <array-type> ::= A [<dimension number>] _ <element type> */
2142 demangle_array_type (dm
)
2145 dyn_string_t array_size
= dyn_string_new (10);
2147 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2149 /* Demangle the array size into array_size. */
2150 RETURN_IF_ERROR (demangle_number_literally (dm
, array_size
, 10, 0));
2152 /* Demangle the base type of the array. */
2153 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2154 RETURN_IF_ERROR (demangle_type (dm
));
2156 /* Emit the array dimension syntax. */
2157 result_append_char (dm
, '[');
2158 result_append_string (dm
, array_size
);
2159 result_append_char (dm
, ']');
2160 dyn_string_delete (array_size
);
2165 /* Demangles and emits a <template-param>. The zero-indexed position
2166 in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
2168 <template-param> ::= T_ # first template parameter
2169 ::= T <parameter-2 number> _ */
2172 demangle_template_param (dm
, template_parm_number
)
2174 int *template_parm_number
;
2177 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2180 DEMANGLE_TRACE ("template-param", dm
);
2182 /* Make sure there is a template argmust list in which to look up
2183 this parameter reference. */
2184 if (current_arg_list
== NULL
)
2185 return "Template parameter outside of template.";
2187 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2188 if (peek_char (dm
) == '_')
2192 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2195 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2197 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2199 /* parm_number exceeded the number of arguments in the current
2200 template argument list. */
2201 return "Template parameter number out of bounds.";
2202 result_append_string (dm
, (dyn_string_t
) arg
);
2204 if (peek_char (dm
) == 'I')
2205 RETURN_IF_ERROR (demangle_template_args (dm
));
2207 *template_parm_number
= parm_number
;
2211 /* Demangles and emits a <template-args>.
2213 <template-args> ::= I <template-arg>+ E */
2216 demangle_template_args (dm
)
2220 template_arg_list_t arg_list
= template_arg_list_new ();
2222 /* Preserve the most recently demangled source name. */
2223 dyn_string_t old_last_source_name
= dm
->last_source_name
;
2224 dm
->last_source_name
= dyn_string_new (0);
2226 DEMANGLE_TRACE ("template-args", dm
);
2228 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2229 result_append_char (dm
, '<');
2237 result_append (dm
, ", ");
2239 /* Capture the template arg. */
2241 RETURN_IF_ERROR (demangle_template_arg (dm
));
2242 arg
= result_pop (dm
);
2244 /* Emit it in the demangled name. */
2245 result_append_string (dm
, (dyn_string_t
) arg
);
2247 /* Save it for use in expanding <template-param>s. */
2248 template_arg_list_add_arg (arg_list
, arg
);
2250 while (peek_char (dm
) != 'E');
2251 /* Append the '>'. */
2252 result_close_template_list (dm
);
2254 /* Consume the 'E'. */
2257 /* Restore the most recent demangled source name. */
2258 dyn_string_delete (dm
->last_source_name
);
2259 dm
->last_source_name
= old_last_source_name
;
2261 /* Push the list onto the top of the stack of template argument
2262 lists, so that arguments from it are used from now on when
2263 expanding <template-param>s. */
2264 push_template_arg_list (dm
, arg_list
);
2269 /* This function, which does not correspond to a production in the
2270 mangling spec, handles the `literal' production for both
2271 <template-arg> and <expr-primary>. It does not expect or consume
2272 the initial `L' or final `E'. The demangling is given by:
2274 <literal> ::= <type> </value/ number>
2276 and the emitted output is `(type)number'. */
2279 demangle_literal (dm
)
2282 dyn_string_t value
= dyn_string_new (0);
2283 char peek
= peek_char (dm
);
2285 DEMANGLE_TRACE ("literal", dm
);
2287 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2289 /* If not in verbose mode and this is a builtin type, see if we
2290 can produce simpler numerical output. In particular, for
2291 integer types shorter than `long', just write the number
2292 without type information; for bools, write `true' or `false'.
2293 Other refinements could be made here too. */
2295 /* This constant string is used to map from <builtin-type> codes
2296 (26 letters of the alphabet) to codes that determine how the
2297 value will be displayed. The codes are:
2301 A space means the value will be represented using cast
2303 static const char *const code_map
= "ibi iii ll ii i ";
2305 char code
= code_map
[peek
- 'a'];
2306 /* FIXME: Implement demangling of floats and doubles. */
2308 return STATUS_UNIMPLEMENTED
;
2311 /* It's a boolean. */
2314 /* Consume the b. */
2316 /* Look at the next character. It should be 0 or 1,
2317 corresponding to false or true, respectively. */
2318 value
= peek_char (dm
);
2320 result_append (dm
, "false");
2321 else if (value
== '1')
2322 result_append (dm
, "true");
2324 return "Unrecognized bool constant.";
2325 /* Consume the 0 or 1. */
2329 else if (code
== 'i' || code
== 'l')
2331 /* It's an integer or long. */
2333 /* Consume the type character. */
2335 /* Demangle the number and write it out. */
2336 RETURN_IF_ERROR (demangle_number_literally (dm
, value
, 10, 1));
2337 result_append_string (dm
, value
);
2338 /* For long integers, append an l. */
2340 result_append_char (dm
, code
);
2343 /* ...else code == ' ', so fall through to represent this
2344 literal's type explicitly using cast syntax. */
2347 result_append_char (dm
, '(');
2348 RETURN_IF_ERROR (demangle_type (dm
));
2349 result_append_char (dm
, ')');
2351 RETURN_IF_ERROR (demangle_number_literally (dm
, value
, 10, 1));
2352 result_append_string (dm
, value
);
2353 dyn_string_delete (value
);
2358 /* Demangles and emits a <template-arg>.
2360 <template-arg> ::= <type> # type
2361 ::= L <type> <value number> E # literal
2362 ::= LZ <encoding> E # external name
2363 ::= X <expression> E # expression */
2366 demangle_template_arg (dm
)
2369 DEMANGLE_TRACE ("template-arg", dm
);
2371 switch (peek_char (dm
))
2376 if (peek_char (dm
) == 'Z')
2378 /* External name. */
2380 /* FIXME: Standard is contradictory here. */
2381 RETURN_IF_ERROR (demangle_encoding (dm
));
2384 RETURN_IF_ERROR (demangle_literal (dm
));
2385 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2391 RETURN_IF_ERROR (demangle_expression (dm
));
2395 RETURN_IF_ERROR (demangle_type (dm
));
2402 /* Demangles and emits an <expression>.
2404 <expression> ::= <unary operator-name> <expression>
2405 ::= <binary operator-name> <expression> <expression>
2407 ::= <scope-expression> */
2410 demangle_expression (dm
)
2413 char peek
= peek_char (dm
);
2415 DEMANGLE_TRACE ("expression", dm
);
2417 if (peek
== 'L' || peek
== 'T')
2418 RETURN_IF_ERROR (demangle_expr_primary (dm
));
2419 else if (peek
== 's' && peek_char_next (dm
) == 'r')
2420 RETURN_IF_ERROR (demangle_scope_expression (dm
));
2422 /* An operator expression. */
2425 dyn_string_t operator_name
;
2427 /* We have an operator name. Since we want to output binary
2428 operations in infix notation, capture the operator name
2431 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
2432 operator_name
= (dyn_string_t
) result_pop (dm
);
2434 /* If it's binary, do an operand first. */
2437 result_append_char (dm
, '(');
2438 RETURN_IF_ERROR (demangle_expression (dm
));
2439 result_append_char (dm
, ')');
2442 /* Now emit the operator, followed by its second (if binary) or
2443 only (if unary) operand. */
2444 result_append_string (dm
, operator_name
);
2445 dyn_string_delete (operator_name
);
2446 result_append_char (dm
, '(');
2447 RETURN_IF_ERROR (demangle_expression (dm
));
2448 result_append_char (dm
, ')');
2450 /* The ternary operator takes a third operand. */
2453 result_append (dm
, ":(");
2454 RETURN_IF_ERROR (demangle_expression (dm
));
2455 result_append_char (dm
, ')');
2462 /* Demangles and emits a <scope-expression>.
2464 <scope-expression> ::= sr <qualifying type> <source-name>
2465 ::= sr <qualifying type> <encoding> */
2468 demangle_scope_expression (dm
)
2471 RETURN_IF_ERROR (demangle_char (dm
, 's'));
2472 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
2473 RETURN_IF_ERROR (demangle_type (dm
));
2474 result_append (dm
, "::");
2475 RETURN_IF_ERROR (demangle_encoding (dm
));
2479 /* Demangles and emits an <expr-primary>.
2481 <expr-primary> ::= <template-param>
2482 ::= L <type> <value number> E # literal
2483 ::= L <mangled-name> E # external name */
2486 demangle_expr_primary (dm
)
2489 char peek
= peek_char (dm
);
2492 DEMANGLE_TRACE ("expr-primary", dm
);
2495 RETURN_IF_ERROR (demangle_template_param (dm
, &unused
));
2496 else if (peek
== 'L')
2498 /* Consume the `L'. */
2500 peek
= peek_char (dm
);
2503 RETURN_IF_ERROR (demangle_mangled_name (dm
));
2505 RETURN_IF_ERROR (demangle_literal (dm
));
2507 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2510 return STATUS_ERROR
;
2515 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2516 if the substitution is the name of a template, zero otherwise. If
2517 the substitution token is St, which corresponds to the `::std::'
2518 namespace and can appear in a non-nested name, sets
2519 *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.
2521 <substitution> ::= S <seq-id> _
2525 ::= Sa # ::std::allocator
2526 ::= Sb # ::std::basic_string
2527 ::= Ss # ::std::basic_string<char,
2528 ::std::char_traits<char>,
2529 ::std::allocator<char> >
2530 ::= Si # ::std::basic_istream<char,
2531 std::char_traits<char> >
2532 ::= So # ::std::basic_ostream<char,
2533 std::char_traits<char> >
2534 ::= Sd # ::std::basic_iostream<char,
2535 std::char_traits<char> >
2539 demangle_substitution (dm
, template_p
, special_std_substitution
)
2542 int *special_std_substitution
;
2548 DEMANGLE_TRACE ("substitution", dm
);
2550 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
2551 *special_std_substitution
= 0;
2553 /* Scan the substitution sequence index. A missing number denotes
2555 peek
= peek_char (dm
);
2558 /* If the following character is 0-9 or a capital letter, interpret
2559 the sequence up to the next underscore as a base-36 substitution
2561 else if (isdigit ((unsigned char) peek
)
2562 || (peek
>= 'A' && peek
<= 'Z'))
2563 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
2569 result_append (dm
, "std");
2570 *special_std_substitution
= 1;
2574 result_append (dm
, "std::allocator");
2575 dyn_string_copy_cstr (dm
->last_source_name
, "allocator");
2579 result_append (dm
, "std::basic_string");
2580 dyn_string_copy_cstr (dm
->last_source_name
, "basic_string");
2586 result_append (dm
, "std::string");
2587 dyn_string_copy_cstr (dm
->last_source_name
, "string");
2591 result_append (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >");
2592 dyn_string_copy_cstr (dm
->last_source_name
, "basic_string");
2599 result_append (dm
, "std::istream");
2600 dyn_string_copy_cstr (dm
->last_source_name
, "istream");
2604 result_append (dm
, "std::basic_istream<char, std::char_traints<char> >");
2605 dyn_string_copy_cstr (dm
->last_source_name
, "basic_istream");
2612 result_append (dm
, "std::ostream");
2613 dyn_string_copy_cstr (dm
->last_source_name
, "ostream");
2617 result_append (dm
, "std::basic_ostream<char, std::char_traits<char> >");
2618 dyn_string_copy_cstr (dm
->last_source_name
, "basic_ostream");
2625 result_append (dm
, "std::iostream");
2626 dyn_string_copy_cstr (dm
->last_source_name
, "iostream");
2630 result_append (dm
, "std::basic_iostream<char, std::char_traits<char> >");
2631 dyn_string_copy_cstr (dm
->last_source_name
, "basic_iostream");
2636 return "Unrecognized <substitution>.";
2643 /* Look up the substitution text. Since `S_' is the most recent
2644 substitution, `S0_' is the second-most-recent, etc., shift the
2645 numbering by one. */
2646 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
2648 return "Substitution number out of range.";
2650 /* Emit the substitution text. */
2651 result_append_string (dm
, text
);
2653 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2657 /* Demangles and emits a <local-name>.
2659 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2660 := Z <function encoding> E s [<discriminator>] */
2663 demangle_local_name (dm
)
2666 DEMANGLE_TRACE ("local-name", dm
);
2668 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
2669 RETURN_IF_ERROR (demangle_encoding (dm
));
2670 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2671 result_append (dm
, "'s ");
2673 if (peek_char (dm
) == 's')
2675 /* Local character string literal. */
2676 result_append (dm
, "string literal");
2677 /* Consume the s. */
2679 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
2684 result_append (dm
, "local ");
2685 /* Local name for some other entity. Demangle its name. */
2686 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
2687 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
2693 /* Optimonally demangles and emits a <discriminator>. If there is no
2694 <discriminator> at the current position in the mangled string, the
2695 descriminator is assumed to be zero. Emit the discriminator number
2696 in parentheses, unless SUPPRESS_FIRST is non-zero and the
2697 discriminator is zero.
2699 <discriminator> ::= _ <number> */
2702 demangle_discriminator (dm
, suppress_first
)
2706 /* Output for <discriminator>s to the demangled name is completely
2707 supressed if not in verbose mode. */
2709 if (peek_char (dm
) == '_')
2711 /* Consume the underscore. */
2714 result_append (dm
, " [#");
2715 /* Check if there's a number following the underscore. */
2716 if (isdigit ((unsigned char) peek_char (dm
)))
2719 /* Demangle the number. */
2720 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
2722 /* Write the discriminator. The mangled number is two
2723 less than the discriminator ordinal, counting from
2725 int_to_dyn_string (discriminator
+ 2,
2726 (dyn_string_t
) dm
->result
);
2731 /* A missing digit correspond to one. */
2732 result_append_char (dm
, '1');
2735 result_append_char (dm
, ']');
2737 else if (!suppress_first
)
2740 result_append (dm
, " [#0]");
2746 /* Demangle NAME into RESULT, which must be an initialized
2747 dyn_string_t. On success, returns STATUS_OK. On failure, returns
2748 an error message, and the contents of RESULT are unchanged. */
2751 cp_demangle (name
, result
)
2753 dyn_string_t result
;
2756 int length
= strlen (name
);
2758 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
2760 demangling_t dm
= demangling_new (name
);
2763 status
= demangle_mangled_name (dm
);
2765 if (status
== STATUS_OK
)
2767 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
2768 dyn_string_copy (result
, demangled
);
2769 dyn_string_delete (demangled
);
2772 demangling_delete (dm
);
2776 /* It's evidently not a mangled C++ name. It could be the name
2777 of something with C linkage, though, so just copy NAME into
2779 dyn_string_copy_cstr (result
, name
);
2786 /* Variant entry point for integration with the existing cplus-dem
2787 demangler. Attempts to demangle MANGLED. If the demangling
2788 succeeds, returns a buffer, allocated with malloc, containing the
2789 demangled name. The caller must deallocate the buffer using free.
2790 If the demangling failes, returns NULL. */
2793 cplus_demangle_new_abi (mangled
)
2794 const char* mangled
;
2796 /* Create a dyn_string to hold the demangled name. */
2797 dyn_string_t demangled
= dyn_string_new (0);
2798 /* Attempt the demangling. */
2799 status_t status
= cp_demangle ((char *) mangled
, demangled
);
2800 if (status
== STATUS_OK
)
2801 /* Demangling succeeded. */
2803 /* Grab the demangled result from the dyn_string. It was
2804 allocated with malloc, so we can return it directly. */
2805 char *return_value
= dyn_string_release (demangled
);
2806 /* The dyn_string can go away. */
2807 dyn_string_delete (demangled
);
2808 /* Hand back the demangled name. */
2809 return return_value
;
2812 /* Demangling failed. */
2814 dyn_string_delete (demangled
);
2819 #ifdef STANDALONE_DEMANGLER
2823 static void print_usage
2824 PARAMS ((FILE* fp
, int exit_value
));
2826 /* Non-zero if CHAR is a character than can occur in a mangled name. */
2827 #define is_mangled_char(CHAR) \
2828 (isalnum ((unsigned char) (CHAR)) || (CHAR) == '_')
2830 /* The name of this program, as invoked. */
2831 const char* program_name
;
2833 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
2836 print_usage (fp
, exit_value
)
2840 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
2841 fprintf (fp
, "Options:\n", program_name
);
2842 fprintf (fp
, " -h,--help Display this message.\n");
2843 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
2844 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
2845 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
2850 /* Option specification for getopt_long. */
2851 static struct option long_options
[] =
2853 { "help", no_argument
, NULL
, 'h' },
2854 { "strict", no_argument
, NULL
, 's' },
2855 { "verbose", no_argument
, NULL
, 'v' },
2856 { NULL
, no_argument
, NULL
, 0 },
2859 /* Main entry for a demangling filter executable. It will demangle
2860 its command line arguments, if any. If none are provided, it will
2861 filter stdin to stdout, replacing any recognized mangled C++ names
2862 with their demangled equivalents. */
2873 /* Use the program name of this program, as invoked. */
2874 program_name
= argv
[0];
2876 /* Parse options. */
2879 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
2882 case '?': /* Unrecognized option. */
2883 print_usage (stderr
, 1);
2887 print_usage (stdout
, 0);
2899 while (opt_char
!= -1);
2902 /* No command line arguments were provided. Filter stdin. */
2904 dyn_string_t mangled
= dyn_string_new (3);
2905 dyn_string_t demangled
= dyn_string_new (0);
2908 /* Read all of input. */
2909 while (!feof (stdin
))
2911 char c
= getchar ();
2913 /* The first character of a mangled name is an underscore. */
2918 /* It's not a mangled name. Print the character and go
2925 /* The second character of a mangled name is a capital `Z'. */
2930 /* It's not a mangled name. Print the previous
2931 underscore, the `Z', and go on. */
2937 /* Start keeping track of the candidate mangled name. */
2938 dyn_string_append_char (mangled
, '_');
2939 dyn_string_append_char (mangled
, 'Z');
2941 /* Pile characters into mangled until we hit one that can't
2942 occur in a mangled name. */
2944 while (!feof (stdin
) && is_mangled_char (c
))
2946 dyn_string_append_char (mangled
, c
);
2952 /* Attempt to demangle the name. */
2953 status
= cp_demangle (dyn_string_buf (mangled
), demangled
);
2955 /* If the demangling succeeded, great! Print out the
2956 demangled version. */
2957 if (status
== STATUS_OK
)
2958 fputs (dyn_string_buf (demangled
), stdout
);
2959 /* Otherwise, it might not have been a mangled name. Just
2960 print out the original text. */
2962 fputs (dyn_string_buf (mangled
), stdout
);
2964 /* If we haven't hit EOF yet, we've read one character that
2965 can't occur in a mangled name, so print it out. */
2969 /* Clear the candidate mangled name, to start afresh next
2970 time we hit a `_Z'. */
2971 dyn_string_clear (mangled
);
2974 dyn_string_delete (mangled
);
2975 dyn_string_delete (demangled
);
2978 /* Demangle command line arguments. */
2980 dyn_string_t result
= dyn_string_new (0);
2982 /* Loop over command line arguments. */
2983 for (i
= optind
; i
< argc
; ++i
)
2985 /* Attempt to demangle. */
2986 status
= cp_demangle (argv
[i
], result
);
2988 /* If it worked, print the demangled name. */
2989 if (status
== STATUS_OK
)
2990 printf ("%s\n", dyn_string_buf (result
));
2991 /* If not, print the error message to stderr instead. */
2993 fprintf (stderr
, "%s\n", status
);
2995 dyn_string_delete (result
);
3001 #endif /* STANDALONE_DEMANGLER */