1 /* Demangler for IA64 / g++ standard C++ ABI.
2 Copyright (C) 2000 CodeSourcery LLC.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /* This file implements demangling of C++ names mangled according to
21 the IA64 / g++ standard C++ ABI. Use the cp_demangle function to
22 demangle a mangled name, or compile with the preprocessor macro
23 STANDALONE_DEMANGLER defined to create a demangling filter
24 executable (functionally similar to c++filt, but includes this
31 #include <sys/types.h>
44 #include "libiberty.h"
45 #include "dyn-string.h"
48 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
49 and other debugging output, will be generated. */
50 #ifdef CP_DEMANGLE_DEBUG
51 #define DEMANGLE_TRACE(PRODUCTION, DM) \
52 fprintf (stderr, " -> %-24s at position %3d\n", \
53 (PRODUCTION), current_position (DM));
55 #define DEMANGLE_TRACE(PRODUCTION, DM)
58 /* Don't include <ctype.h>, to prevent additional unresolved symbols
59 from being dragged into the C++ runtime library. */
60 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
61 #define IS_ALPHA(CHAR) \
62 (((CHAR) >= 'a' && (CHAR) <= 'z') \
63 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
65 /* The prefix prepended by GCC to an identifier represnting the
66 anonymous namespace. */
67 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
69 /* If flag_verbose is zero, some simplifications will be made to the
70 output to make it easier to read and supress details that are
71 generally not of interest to the average C++ programmer.
72 Otherwise, the demangled representation will attempt to convey as
73 much information as the mangled form. */
74 static int flag_verbose
;
76 /* If flag_strict is non-zero, demangle strictly according to the
77 specification -- don't demangle special g++ manglings. */
78 static int flag_strict
;
80 /* String_list_t is an extended form of dyn_string_t which provides a link
81 field. A string_list_t may safely be cast to and used as a
84 struct string_list_def
86 struct dyn_string string
;
87 struct string_list_def
*next
;
90 typedef struct string_list_def
*string_list_t
;
92 /* Data structure representing a potential substitution. */
94 struct substitution_def
96 /* The demangled text of the substitution. */
99 /* Whether this substitution represents a template item. */
103 /* Data structure representing a template argument list. */
105 struct template_arg_list_def
107 /* The next (lower) template argument list in the stack of currently
108 active template arguments. */
109 struct template_arg_list_def
*next
;
111 /* The first element in the list of template arguments in
112 left-to-right order. */
113 string_list_t first_argument
;
115 /* The last element in the arguments lists. */
116 string_list_t last_argument
;
119 typedef struct template_arg_list_def
*template_arg_list_t
;
121 /* Data structure to maintain the state of the current demangling. */
123 struct demangling_def
125 /* The full mangled name being mangled. */
128 /* Pointer into name at the current position. */
131 /* Stack for strings containing demangled result generated so far.
132 Text is emitted to the topmost (first) string. */
133 string_list_t result
;
135 /* The number of presently available substitutions. */
136 int num_substitutions
;
138 /* The allocated size of the substitutions array. */
139 int substitutions_allocated
;
141 /* An array of available substitutions. The number of elements in
142 the array is given by num_substitions, and the allocated array
143 size in substitutions_size.
145 The most recent substition is at the end, so
147 - `S_' corresponds to substititutions[num_substitutions - 1]
148 - `S0_' corresponds to substititutions[num_substitutions - 2]
151 struct substitution_def
*substitutions
;
153 /* The stack of template argument lists. */
154 template_arg_list_t template_arg_lists
;
156 /* The most recently demangled source-name. */
157 dyn_string_t last_source_name
;
160 typedef struct demangling_def
*demangling_t
;
162 /* This type is the standard return code from most functions. Values
163 other than STATUS_OK contain descriptive messages. */
164 typedef const char *status_t
;
166 /* Special values that can be used as a status_t. */
167 #define STATUS_OK NULL
168 #define STATUS_ERROR "Error."
169 #define STATUS_UNIMPLEMENTED "Unimplemented."
170 #define STATUS_INTERNAL_ERROR "Internal error."
172 /* This status code indicates a failure in malloc or realloc. */
173 static const char *const status_allocation_failed
= "Allocation failed.";
174 #define STATUS_ALLOCATION_FAILED status_allocation_failed
176 /* Non-zero if STATUS indicates that no error has occurred. */
177 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
179 /* Evaluate EXPR, which must produce a status_t. If the status code
180 indicates an error, return from the current function with that
182 #define RETURN_IF_ERROR(EXPR) \
186 if (!STATUS_NO_ERROR (s)) \
191 static status_t int_to_dyn_string
192 PARAMS ((int, dyn_string_t
));
193 static string_list_t string_list_new
195 static void string_list_delete
196 PARAMS ((string_list_t
));
197 static status_t result_add_separated_char
198 PARAMS ((demangling_t
, int));
199 static status_t result_push
200 PARAMS ((demangling_t
));
201 static string_list_t result_pop
202 PARAMS ((demangling_t
));
203 static int substitution_start
204 PARAMS ((demangling_t
));
205 static status_t substitution_add
206 PARAMS ((demangling_t
, int, int));
207 static dyn_string_t substitution_get
208 PARAMS ((demangling_t
, int, int *));
209 #ifdef CP_DEMANGLE_DEBUG
210 static void substitutions_print
211 PARAMS ((demangling_t
, FILE *));
213 static template_arg_list_t template_arg_list_new
215 static void template_arg_list_delete
216 PARAMS ((template_arg_list_t
));
217 static void template_arg_list_add_arg
218 PARAMS ((template_arg_list_t
, string_list_t
));
219 static string_list_t template_arg_list_get_arg
220 PARAMS ((template_arg_list_t
, int));
221 static void push_template_arg_list
222 PARAMS ((demangling_t
, template_arg_list_t
));
223 static void pop_to_template_arg_list
224 PARAMS ((demangling_t
, template_arg_list_t
));
225 #ifdef CP_DEMANGLE_DEBUG
226 static void template_arg_list_print
227 PARAMS ((template_arg_list_t
, FILE *));
229 static template_arg_list_t current_template_arg_list
230 PARAMS ((demangling_t
));
231 static demangling_t demangling_new
232 PARAMS ((const char *));
233 static void demangling_delete
234 PARAMS ((demangling_t
));
236 /* The last character of DS. Warning: DS is evaluated twice. */
237 #define dyn_string_last_char(DS) \
238 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
240 /* Append a space character (` ') to DS if it does not already end
241 with one. Evaluates to 1 on success, or 0 on allocation failure. */
242 #define dyn_string_append_space(DS) \
243 ((dyn_string_length (DS) > 0 \
244 && dyn_string_last_char (DS) != ' ') \
245 ? dyn_string_append_char ((DS), ' ') \
248 /* Returns the index of the current position in the mangled name. */
249 #define current_position(DM) ((DM)->next - (DM)->name)
251 /* Returns the character at the current position of the mangled name. */
252 #define peek_char(DM) (*((DM)->next))
254 /* Returns the character one past the current position of the mangled
256 #define peek_char_next(DM) \
257 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
259 /* Returns the character at the current position, and advances the
260 current position to the next character. */
261 #define next_char(DM) (*((DM)->next)++)
263 /* Returns non-zero if the current position is the end of the mangled
264 name, i.e. one past the last character. */
265 #define end_of_name_p(DM) (peek_char (DM) == '\0')
267 /* Advances the current position by one character. */
268 #define advance_char(DM) (++(DM)->next)
270 /* Returns the string containing the current demangled result. */
271 #define result_string(DM) (&(DM)->result->string)
273 /* Appends a dyn_string_t to the demangled result. */
274 #define result_append_string(DM, STRING) \
275 (dyn_string_append (&(DM)->result->string, (STRING)) \
276 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
278 /* Appends NUL-terminated string CSTR to the demangled result. */
279 #define result_append(DM, CSTR) \
280 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
281 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
283 /* Appends character CHAR to the demangled result. */
284 #define result_append_char(DM, CHAR) \
285 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \
286 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
288 /* Inserts a dyn_string_t to the demangled result at position POS. */
289 #define result_insert_string(DM, POS, STRING) \
290 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
291 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
293 /* Inserts NUL-terminated string CSTR to the demangled result at
295 #define result_insert(DM, POS, CSTR) \
296 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
297 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
299 /* Inserts character CHAR to the demangled result at position POS. */
300 #define result_insert_char(DM, POS, CHAR) \
301 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
302 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
304 /* The length of the current demangled result. */
305 #define result_length(DM) \
306 dyn_string_length (&(DM)->result->string)
308 /* Appends a space to the demangled result if the last character is
310 #define result_append_space(DM) \
311 (dyn_string_append_space (&(DM)->result->string) \
312 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
314 /* Appends a (less-than, greater-than) character to the result in DM
315 to (open, close) a template argument or parameter list. Appends a
316 space first if necessary to prevent spurious elision of angle
317 brackets with the previous character. */
318 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
319 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
321 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
322 success. On failure, deletes DS and returns an error code. */
325 int_to_dyn_string (value
, ds
)
332 /* Handle zero up front. */
335 if (!dyn_string_append_char (ds
, '0'))
336 return STATUS_ALLOCATION_FAILED
;
340 /* For negative numbers, emit a minus sign. */
343 if (!dyn_string_append_char (ds
, '-'))
344 return STATUS_ALLOCATION_FAILED
;
348 /* Find the power of 10 of the first digit. */
356 /* Write the digits. */
359 int digit
= value
/ mask
;
361 if (!dyn_string_append_char (ds
, '0' + digit
))
362 return STATUS_ALLOCATION_FAILED
;
364 value
-= digit
* mask
;
371 /* Creates a new string list node. The contents of the string are
372 empty, but the initial buffer allocation is LENGTH. The string
373 list node should be deleted with string_list_delete. Returns NULL
374 if allocation fails. */
377 string_list_new (length
)
380 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
383 if (!dyn_string_init ((dyn_string_t
) s
, length
))
388 /* Deletes the entire string list starting at NODE. */
391 string_list_delete (node
)
396 string_list_t next
= node
->next
;
402 /* Appends CHARACTER to the demangled result. If the current trailing
403 character of the result is CHARACTER, a space is inserted first. */
406 result_add_separated_char (dm
, character
)
410 dyn_string_t s
= &dm
->result
->string
;
412 /* Add a space if the last character is already a closing angle
413 bracket, so that a nested template arg list doesn't look like
414 it's closed with a right-shift operator. */
415 if (dyn_string_last_char (s
) == character
)
417 if (!dyn_string_append_char (s
, ' '))
418 return STATUS_ALLOCATION_FAILED
;
421 /* Add closing angle brackets. */
422 if (!dyn_string_append_char (s
, character
))
423 return STATUS_ALLOCATION_FAILED
;
428 /* Allocates and pushes a new string onto the demangled results stack
429 for DM. Subsequent demangling with DM will emit to the new string.
430 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
431 allocation failure. */
437 string_list_t new_string
= string_list_new (0);
438 if (new_string
== NULL
)
439 /* Allocation failed. */
440 return STATUS_ALLOCATION_FAILED
;
442 /* Link the new string to the front of the list of result strings. */
443 new_string
->next
= (string_list_t
) dm
->result
;
444 dm
->result
= new_string
;
448 /* Removes and returns the topmost element on the demangled results
449 stack for DM. The caller assumes ownership for the returned
456 string_list_t top
= dm
->result
;
457 dm
->result
= top
->next
;
461 /* Returns the start position of a fragment of the demangled result
462 that will be a substitution candidate. Should be called at the
463 start of productions that can add substitutions. */
466 substitution_start (dm
)
469 return result_length (dm
);
472 /* Adds the suffix of the current demangled result of DM starting at
473 START_POSITION as a potential substitution. If TEMPLATE_P is
474 non-zero, this potential substitution is a template-id. */
477 substitution_add (dm
, start_position
, template_p
)
482 dyn_string_t result
= result_string (dm
);
483 dyn_string_t substitution
= dyn_string_new (0);
486 if (substitution
== NULL
)
487 return STATUS_ALLOCATION_FAILED
;
489 /* Extract the substring of the current demangling result that
490 represents the subsitution candidate. */
491 if (!dyn_string_substring (substitution
,
492 result
, start_position
, result_length (dm
)))
494 dyn_string_delete (substitution
);
495 return STATUS_ALLOCATION_FAILED
;
498 /* If there's no room for the new entry, grow the array. */
499 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
501 size_t new_array_size
;
502 if (dm
->substitutions_allocated
> 0)
503 dm
->substitutions_allocated
*= 2;
505 dm
->substitutions_allocated
= 2;
507 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
509 dm
->substitutions
= (struct substitution_def
*)
510 realloc (dm
->substitutions
, new_array_size
);
511 if (dm
->substitutions
== NULL
)
512 /* Realloc failed. */
514 dyn_string_delete (substitution
);
515 return STATUS_ALLOCATION_FAILED
;
519 /* Add the substitution to the array. */
520 i
= dm
->num_substitutions
++;
521 dm
->substitutions
[i
].text
= substitution
;
522 dm
->substitutions
[i
].template_p
= template_p
;
524 #ifdef CP_DEMANGLE_DEBUG
525 substitutions_print (dm
, stderr
);
531 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
532 non-zero if the substitution is a template-id, zero otherwise.
533 N is numbered from zero. DM retains ownership of the returned
534 string. If N is negative, or equal to or greater than the current
535 number of substitution candidates, returns NULL. */
538 substitution_get (dm
, n
, template_p
)
543 struct substitution_def
*sub
;
545 /* Make sure N is in the valid range. */
546 if (n
< 0 || n
>= dm
->num_substitutions
)
549 sub
= &(dm
->substitutions
[n
]);
550 *template_p
= sub
->template_p
;
554 #ifdef CP_DEMANGLE_DEBUG
555 /* Debugging routine to print the current substitutions to FP. */
558 substitutions_print (dm
, fp
)
563 int num
= dm
->num_substitutions
;
565 fprintf (fp
, "SUBSTITUTIONS:\n");
566 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
569 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
572 fprintf (fp
, " S_ ");
574 fprintf (fp
, " S%d_", seq_id
);
575 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
579 #endif /* CP_DEMANGLE_DEBUG */
581 /* Creates a new template argument list. Returns NULL if allocation
584 static template_arg_list_t
585 template_arg_list_new ()
587 template_arg_list_t new_list
=
588 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
589 if (new_list
== NULL
)
591 /* Initialize the new list to have no arguments. */
592 new_list
->first_argument
= NULL
;
593 new_list
->last_argument
= NULL
;
594 /* Return the new list. */
598 /* Deletes a template argument list and the template arguments it
602 template_arg_list_delete (list
)
603 template_arg_list_t list
;
605 /* If there are any arguments on LIST, delete them. */
606 if (list
->first_argument
!= NULL
)
607 string_list_delete (list
->first_argument
);
612 /* Adds ARG to the template argument list ARG_LIST. */
615 template_arg_list_add_arg (arg_list
, arg
)
616 template_arg_list_t arg_list
;
619 if (arg_list
->first_argument
== NULL
)
620 /* If there were no arguments before, ARG is the first one. */
621 arg_list
->first_argument
= arg
;
623 /* Make ARG the last argument on the list. */
624 arg_list
->last_argument
->next
= arg
;
625 /* Make ARG the last on the list. */
626 arg_list
->last_argument
= arg
;
630 /* Returns the template arugment at position INDEX in template
631 argument list ARG_LIST. */
634 template_arg_list_get_arg (arg_list
, index
)
635 template_arg_list_t arg_list
;
638 string_list_t arg
= arg_list
->first_argument
;
639 /* Scan down the list of arguments to find the one at position
645 /* Ran out of arguments before INDEX hit zero. That's an
649 /* Return the argument at position INDEX. */
653 /* Pushes ARG_LIST onto the top of the template argument list stack. */
656 push_template_arg_list (dm
, arg_list
)
658 template_arg_list_t arg_list
;
660 arg_list
->next
= dm
->template_arg_lists
;
661 dm
->template_arg_lists
= arg_list
;
662 #ifdef CP_DEMANGLE_DEBUG
663 fprintf (stderr
, " ** pushing template arg list\n");
664 template_arg_list_print (arg_list
, stderr
);
668 /* Pops and deletes elements on the template argument list stack until
669 arg_list is the topmost element. If arg_list is NULL, all elements
670 are popped and deleted. */
673 pop_to_template_arg_list (dm
, arg_list
)
675 template_arg_list_t arg_list
;
677 while (dm
->template_arg_lists
!= arg_list
)
679 template_arg_list_t top
= dm
->template_arg_lists
;
680 /* Disconnect the topmost element from the list. */
681 dm
->template_arg_lists
= top
->next
;
682 /* Delete the popped element. */
683 template_arg_list_delete (top
);
684 #ifdef CP_DEMANGLE_DEBUG
685 fprintf (stderr
, " ** removing template arg list\n");
690 #ifdef CP_DEMANGLE_DEBUG
692 /* Prints the contents of ARG_LIST to FP. */
695 template_arg_list_print (arg_list
, fp
)
696 template_arg_list_t arg_list
;
702 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
703 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
706 fprintf (fp
, " T_ : ");
708 fprintf (fp
, " T%d_ : ", index
);
710 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
714 #endif /* CP_DEMANGLE_DEBUG */
716 /* Returns the topmost element on the stack of template argument
717 lists. If there is no list of template arguments, returns NULL. */
719 static template_arg_list_t
720 current_template_arg_list (dm
)
723 return dm
->template_arg_lists
;
726 /* Allocates a demangling_t object for demangling mangled NAME. A new
727 result must be pushed before the returned object can be used.
728 Returns NULL if allocation fails. */
731 demangling_new (name
)
735 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
742 dm
->num_substitutions
= 0;
743 dm
->substitutions_allocated
= 10;
744 dm
->template_arg_lists
= NULL
;
745 dm
->last_source_name
= dyn_string_new (0);
746 if (dm
->last_source_name
== NULL
)
748 dm
->substitutions
= (struct substitution_def
*)
749 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
750 if (dm
->substitutions
== NULL
)
752 dyn_string_delete (dm
->last_source_name
);
759 /* Deallocates a demangling_t object and all memory associated with
763 demangling_delete (dm
)
767 template_arg_list_t arg_list
= dm
->template_arg_lists
;
769 /* Delete the stack of template argument lists. */
770 while (arg_list
!= NULL
)
772 template_arg_list_t next
= arg_list
->next
;
773 template_arg_list_delete (arg_list
);
776 /* Delete the list of substitutions. */
777 for (i
= dm
->num_substitutions
; --i
>= 0; )
778 dyn_string_delete (dm
->substitutions
[i
].text
);
779 free (dm
->substitutions
);
780 /* Delete the demangled result. */
781 string_list_delete (dm
->result
);
782 /* Delete the stored identifier name. */
783 dyn_string_delete (dm
->last_source_name
);
784 /* Delete the context object itself. */
788 /* These functions demangle an alternative of the corresponding
789 production in the mangling spec. The first argument of each is a
790 demangling context structure for the current demangling
791 operation. Most emit demangled text directly to the topmost result
792 string on the result string stack in the demangling context
795 static status_t demangle_char
796 PARAMS ((demangling_t
, int));
797 static status_t demangle_mangled_name
798 PARAMS ((demangling_t
));
799 static status_t demangle_encoding
800 PARAMS ((demangling_t
));
801 static status_t demangle_name
802 PARAMS ((demangling_t
, int *));
803 static status_t demangle_nested_name
804 PARAMS ((demangling_t
, int *));
805 static status_t demangle_prefix
806 PARAMS ((demangling_t
, int *));
807 static status_t demangle_unqualified_name
808 PARAMS ((demangling_t
, int *));
809 static status_t demangle_source_name
810 PARAMS ((demangling_t
));
811 static status_t demangle_number
812 PARAMS ((demangling_t
, int *, int, int));
813 static status_t demangle_number_literally
814 PARAMS ((demangling_t
, dyn_string_t
, int, int));
815 static status_t demangle_identifier
816 PARAMS ((demangling_t
, int, dyn_string_t
));
817 static status_t demangle_operator_name
818 PARAMS ((demangling_t
, int, int *));
819 static status_t demangle_nv_offset
820 PARAMS ((demangling_t
));
821 static status_t demangle_v_offset
822 PARAMS ((demangling_t
));
823 static status_t demangle_call_offset
824 PARAMS ((demangling_t
));
825 static status_t demangle_special_name
826 PARAMS ((demangling_t
));
827 static status_t demangle_ctor_dtor_name
828 PARAMS ((demangling_t
));
829 static status_t demangle_type_ptr
830 PARAMS ((demangling_t
, int *, int));
831 static status_t demangle_type
832 PARAMS ((demangling_t
));
833 static status_t demangle_CV_qualifiers
834 PARAMS ((demangling_t
, dyn_string_t
));
835 static status_t demangle_builtin_type
836 PARAMS ((demangling_t
));
837 static status_t demangle_function_type
838 PARAMS ((demangling_t
, int *));
839 static status_t demangle_bare_function_type
840 PARAMS ((demangling_t
, int *));
841 static status_t demangle_class_enum_type
842 PARAMS ((demangling_t
, int *));
843 static status_t demangle_array_type
844 PARAMS ((demangling_t
));
845 static status_t demangle_template_param
846 PARAMS ((demangling_t
));
847 static status_t demangle_template_args
848 PARAMS ((demangling_t
));
849 static status_t demangle_literal
850 PARAMS ((demangling_t
));
851 static status_t demangle_template_arg
852 PARAMS ((demangling_t
));
853 static status_t demangle_expression
854 PARAMS ((demangling_t
));
855 static status_t demangle_scope_expression
856 PARAMS ((demangling_t
));
857 static status_t demangle_expr_primary
858 PARAMS ((demangling_t
));
859 static status_t demangle_substitution
860 PARAMS ((demangling_t
, int *));
861 static status_t demangle_local_name
862 PARAMS ((demangling_t
));
863 static status_t demangle_discriminator
864 PARAMS ((demangling_t
, int));
865 static status_t cp_demangle
866 PARAMS ((const char *, dyn_string_t
));
868 static status_t cp_demangle_type
869 PARAMS ((const char*, dyn_string_t
));
872 /* When passed to demangle_bare_function_type, indicates that the
873 function's return type is not encoded before its parameter types. */
874 #define BFT_NO_RETURN_TYPE NULL
876 /* Check that the next character is C. If so, consume it. If not,
880 demangle_char (dm
, c
)
884 static char *error_message
= NULL
;
886 if (peek_char (dm
) == c
)
893 if (error_message
== NULL
)
894 error_message
= strdup ("Expected ?");
895 error_message
[9] = c
;
896 return error_message
;
900 /* Demangles and emits a <mangled-name>.
902 <mangled-name> ::= _Z <encoding> */
905 demangle_mangled_name (dm
)
908 DEMANGLE_TRACE ("mangled-name", dm
);
909 RETURN_IF_ERROR (demangle_char (dm
, '_'));
910 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
911 RETURN_IF_ERROR (demangle_encoding (dm
));
915 /* Demangles and emits an <encoding>.
917 <encoding> ::= <function name> <bare-function-type>
919 ::= <special-name> */
922 demangle_encoding (dm
)
925 int encode_return_type
;
927 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
928 char peek
= peek_char (dm
);
930 DEMANGLE_TRACE ("encoding", dm
);
932 /* Remember where the name starts. If it turns out to be a template
933 function, we'll have to insert the return type here. */
934 start_position
= result_length (dm
);
936 if (peek
== 'G' || peek
== 'T')
937 RETURN_IF_ERROR (demangle_special_name (dm
));
940 /* Now demangle the name. */
941 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
943 /* If there's anything left, the name was a function name, with
944 maybe its return type, and its parameters types, following. */
945 if (!end_of_name_p (dm
)
946 && peek_char (dm
) != 'E')
948 if (encode_return_type
)
949 /* Template functions have their return type encoded. The
950 return type should be inserted at start_position. */
952 (demangle_bare_function_type (dm
, &start_position
));
954 /* Non-template functions don't have their return type
957 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
961 /* Pop off template argument lists that were built during the
962 mangling of this name, to restore the old template context. */
963 pop_to_template_arg_list (dm
, old_arg_list
);
968 /* Demangles and emits a <name>.
970 <name> ::= <unscoped-name>
971 ::= <unscoped-template-name> <template-args>
975 <unscoped-name> ::= <unqualified-name>
976 ::= St <unqualified-name> # ::std::
978 <unscoped-template-name>
980 ::= <substitution> */
983 demangle_name (dm
, encode_return_type
)
985 int *encode_return_type
;
987 int start
= substitution_start (dm
);
988 char peek
= peek_char (dm
);
989 int is_std_substitution
= 0;
991 /* Generally, the return type is encoded if the function is a
992 template-id, and suppressed otherwise. There are a few cases,
993 though, in which the return type is not encoded even for a
994 templated function. In these cases, this flag is set. */
995 int suppress_return_type
= 0;
997 DEMANGLE_TRACE ("name", dm
);
1002 /* This is a <nested-name>. */
1003 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1007 RETURN_IF_ERROR (demangle_local_name (dm
));
1008 *encode_return_type
= 0;
1012 /* The `St' substitution allows a name nested in std:: to appear
1013 without being enclosed in a nested name. */
1014 if (peek_char_next (dm
) == 't')
1016 (void) next_char (dm
);
1017 (void) next_char (dm
);
1018 RETURN_IF_ERROR (result_append (dm
, "std::"));
1020 (demangle_unqualified_name (dm
, &suppress_return_type
));
1021 is_std_substitution
= 1;
1024 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1025 /* Check if a template argument list immediately follows.
1026 If so, then we just demangled an <unqualified-template-name>. */
1027 if (peek_char (dm
) == 'I')
1029 /* A template name of the form std::<unqualified-name> is a
1030 substitution candidate. */
1031 if (is_std_substitution
)
1032 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1033 /* Demangle the <template-args> here. */
1034 RETURN_IF_ERROR (demangle_template_args (dm
));
1035 *encode_return_type
= !suppress_return_type
;
1038 *encode_return_type
= 0;
1043 /* This is an <unscoped-name> or <unscoped-template-name>. */
1044 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1046 /* If the <unqualified-name> is followed by template args, this
1047 is an <unscoped-template-name>. */
1048 if (peek_char (dm
) == 'I')
1050 /* Add a substitution for the unqualified template name. */
1051 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1053 RETURN_IF_ERROR (demangle_template_args (dm
));
1054 *encode_return_type
= !suppress_return_type
;
1057 *encode_return_type
= 0;
1065 /* Demangles and emits a <nested-name>.
1067 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1070 demangle_nested_name (dm
, encode_return_type
)
1072 int *encode_return_type
;
1076 DEMANGLE_TRACE ("nested-name", dm
);
1078 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1080 peek
= peek_char (dm
);
1081 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1085 /* Snarf up and emit CV qualifiers. */
1086 dyn_string_t cv_qualifiers
= dyn_string_new (24);
1087 if (cv_qualifiers
== NULL
)
1088 return STATUS_ALLOCATION_FAILED
;
1090 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1091 status
= result_append_string (dm
, cv_qualifiers
);
1092 dyn_string_delete (cv_qualifiers
);
1093 RETURN_IF_ERROR (status
);
1094 RETURN_IF_ERROR (result_append_space (dm
));
1097 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1098 /* No need to demangle the final <unqualified-name>; demangle_prefix
1100 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1105 /* Demangles and emits a <prefix>.
1107 <prefix> ::= <prefix> <unqualified-name>
1108 ::= <template-prefix> <template-args>
1112 <template-prefix> ::= <prefix>
1113 ::= <substitution> */
1116 demangle_prefix (dm
, encode_return_type
)
1118 int *encode_return_type
;
1120 int start
= substitution_start (dm
);
1123 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1124 After <template-args>, it is set to non-zero; after everything
1125 else it is set to zero. */
1127 /* Generally, the return type is encoded if the function is a
1128 template-id, and suppressed otherwise. There are a few cases,
1129 though, in which the return type is not encoded even for a
1130 templated function. In these cases, this flag is set. */
1131 int suppress_return_type
= 0;
1133 DEMANGLE_TRACE ("prefix", dm
);
1139 if (end_of_name_p (dm
))
1140 return "Unexpected end of name in <compound-name>.";
1142 peek
= peek_char (dm
);
1144 /* We'll initialize suppress_return_type to false, and set it to true
1145 if we end up demangling a constructor name. However, make
1146 sure we're not actually about to demangle template arguments
1147 -- if so, this is the <template-args> following a
1148 <template-prefix>, so we'll want the previous flag value
1151 suppress_return_type
= 0;
1153 if (IS_DIGIT ((unsigned char) peek
)
1154 || (peek
>= 'a' && peek
<= 'z')
1155 || peek
== 'C' || peek
== 'D'
1158 /* We have another level of scope qualification. */
1160 RETURN_IF_ERROR (result_append (dm
, "::"));
1165 /* The substitution determines whether this is a
1167 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1170 /* It's just a name. */
1172 (demangle_unqualified_name (dm
, &suppress_return_type
));
1173 *encode_return_type
= 0;
1176 else if (peek
== 'Z')
1177 RETURN_IF_ERROR (demangle_local_name (dm
));
1178 else if (peek
== 'I')
1180 RETURN_IF_ERROR (demangle_template_args (dm
));
1182 /* Now we want to indicate to the caller that we've
1183 demangled template arguments, thus the prefix was a
1184 <template-prefix>. That's so that the caller knows to
1185 demangle the function's return type, if this turns out to
1186 be a function name. But, if it's a member template
1187 constructor or a templated conversion operator, report it
1188 as untemplated. Those never get encoded return types. */
1189 *encode_return_type
= !suppress_return_type
;
1191 else if (peek
== 'E')
1195 return "Unexpected character in <compound-name>.";
1198 && peek_char (dm
) != 'E')
1199 /* Add a new substitution for the prefix thus far. */
1200 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1204 /* Demangles and emits an <unqualified-name>. If this
1205 <unqualified-name> is for a special function type that should never
1206 have its return type encoded (particularly, a constructor or
1207 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1210 <unqualified-name> ::= <operator-name>
1212 ::= <source-name> */
1215 demangle_unqualified_name (dm
, suppress_return_type
)
1217 int *suppress_return_type
;
1219 char peek
= peek_char (dm
);
1221 DEMANGLE_TRACE ("unqualified-name", dm
);
1223 /* By default, don't force suppression of the return type (though
1224 non-template functions still don't get a return type encoded). */
1225 *suppress_return_type
= 0;
1227 if (IS_DIGIT ((unsigned char) peek
))
1228 RETURN_IF_ERROR (demangle_source_name (dm
));
1229 else if (peek
>= 'a' && peek
<= 'z')
1233 /* Conversion operators never have a return type encoded. */
1234 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1235 *suppress_return_type
= 1;
1237 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1239 else if (peek
== 'C' || peek
== 'D')
1241 /* Constructors never have a return type encoded. */
1243 *suppress_return_type
= 1;
1245 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1248 return "Unexpected character in <unqualified-name>.";
1253 /* Demangles and emits <source-name>.
1255 <source-name> ::= <length number> <identifier> */
1258 demangle_source_name (dm
)
1263 DEMANGLE_TRACE ("source-name", dm
);
1265 /* Decode the length of the identifier. */
1266 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1268 return "Zero length in <source-name>.";
1270 /* Now the identifier itself. It's placed into last_source_name,
1271 where it can be used to build a constructor or destructor name. */
1272 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1273 dm
->last_source_name
));
1276 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1281 /* Demangles a number, either a <number> or a <positive-number> at the
1282 current position, consuming all consecutive digit characters. Sets
1283 *VALUE to the resulting numberand returns STATUS_OK. The number is
1284 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1285 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1287 <number> ::= [n] <positive-number>
1289 <positive-number> ::= <decimal integer> */
1292 demangle_number (dm
, value
, base
, is_signed
)
1298 dyn_string_t number
= dyn_string_new (10);
1300 DEMANGLE_TRACE ("number", dm
);
1303 return STATUS_ALLOCATION_FAILED
;
1305 demangle_number_literally (dm
, number
, base
, is_signed
);
1306 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1307 dyn_string_delete (number
);
1312 /* Demangles a number at the current position. The digits (and minus
1313 sign, if present) that make up the number are appended to STR.
1314 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1315 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1316 accepted. Does not consume a trailing underscore or other
1317 terminating character. */
1320 demangle_number_literally (dm
, str
, base
, is_signed
)
1326 DEMANGLE_TRACE ("number*", dm
);
1328 if (base
!= 10 && base
!= 36)
1329 return STATUS_INTERNAL_ERROR
;
1331 /* An `n' denotes a negative number. */
1332 if (is_signed
&& peek_char (dm
) == 'n')
1334 /* Skip past the n. */
1336 /* The normal way to write a negative number is with a minus
1338 if (!dyn_string_append_char (str
, '-'))
1339 return STATUS_ALLOCATION_FAILED
;
1342 /* Loop until we hit a non-digit. */
1345 char peek
= peek_char (dm
);
1346 if (IS_DIGIT ((unsigned char) peek
)
1347 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1349 /* Accumulate digits. */
1350 if (!dyn_string_append_char (str
, next_char (dm
)))
1351 return STATUS_ALLOCATION_FAILED
;
1354 /* Not a digit? All done. */
1361 /* Demangles an identifier at the current position of LENGTH
1362 characters and places it in IDENTIFIER. */
1365 demangle_identifier (dm
, length
, identifier
)
1368 dyn_string_t identifier
;
1370 DEMANGLE_TRACE ("identifier", dm
);
1372 dyn_string_clear (identifier
);
1373 if (!dyn_string_resize (identifier
, length
))
1374 return STATUS_ALLOCATION_FAILED
;
1376 while (length
-- > 0)
1378 if (end_of_name_p (dm
))
1379 return "Unexpected end of name in <identifier>.";
1380 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1381 return STATUS_ALLOCATION_FAILED
;
1384 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1385 followed by the source file name and some random characters.
1386 Unless we're in strict mode, decipher these names appropriately. */
1389 char *name
= dyn_string_buf (identifier
);
1390 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1392 /* Compare the first, fixed part. */
1393 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1395 name
+= prefix_length
;
1396 /* The next character might be a period, an underscore, or
1397 dollar sign, depending on the target architecture's
1398 assembler's capabilities. After that comes an `N'. */
1399 if ((*name
== '.' || *name
== '_' || *name
== '$')
1400 && *(name
+ 1) == 'N')
1401 /* This looks like the anonymous namespace identifier.
1402 Replace it with something comprehensible. */
1403 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1410 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1411 the short form is emitted; otherwise the full source form
1412 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1413 operands that the operator takes.
1464 ::= cv <type> # cast
1465 ::= v [0-9] <source-name> # vendor extended operator */
1468 demangle_operator_name (dm
, short_name
, num_args
)
1473 struct operator_code
1475 /* The mangled code for this operator. */
1477 /* The source name of this operator. */
1479 /* The number of arguments this operator takes. */
1483 static const struct operator_code operators
[] =
1494 { "da", " delete[]", 1 },
1496 { "dl", " delete" , 1 },
1504 { "lS", "<<=" , 2 },
1513 { "na", " new[]" , 1 },
1517 { "nw", " new" , 1 },
1523 { "pm", "->*" , 2 },
1529 { "rS", ">>=" , 2 },
1532 { "sz", " sizeof" , 1 }
1535 const int num_operators
=
1536 sizeof (operators
) / sizeof (struct operator_code
);
1538 int c0
= next_char (dm
);
1539 int c1
= next_char (dm
);
1540 const struct operator_code
* p1
= operators
;
1541 const struct operator_code
* p2
= operators
+ num_operators
;
1543 DEMANGLE_TRACE ("operator-name", dm
);
1545 /* Is this a vendor-extended operator? */
1546 if (c0
== 'v' && IS_DIGIT (c1
))
1548 RETURN_IF_ERROR (result_append (dm
, "operator "));
1549 RETURN_IF_ERROR (demangle_source_name (dm
));
1554 /* Is this a conversion operator? */
1555 if (c0
== 'c' && c1
== 'v')
1557 RETURN_IF_ERROR (result_append (dm
, "operator "));
1558 /* Demangle the converted-to type. */
1559 RETURN_IF_ERROR (demangle_type (dm
));
1564 /* Perform a binary search for the operator code. */
1567 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1568 char match0
= p
->code
[0];
1569 char match1
= p
->code
[1];
1571 if (c0
== match0
&& c1
== match1
)
1575 RETURN_IF_ERROR (result_append (dm
, "operator"));
1576 RETURN_IF_ERROR (result_append (dm
, p
->name
));
1577 *num_args
= p
->num_args
;
1583 /* Couldn't find it. */
1584 return "Unknown code in <operator-name>.";
1587 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1594 /* Demangles and omits an <nv-offset>.
1596 <nv-offset> ::= <offset number> # non-virtual base override */
1599 demangle_nv_offset (dm
)
1602 dyn_string_t number
;
1603 status_t status
= STATUS_OK
;
1605 DEMANGLE_TRACE ("h-offset", dm
);
1607 /* Demangle the offset. */
1608 number
= dyn_string_new (4);
1610 return STATUS_ALLOCATION_FAILED
;
1611 demangle_number_literally (dm
, number
, 10, 1);
1613 /* Don't display the offset unless in verbose mode. */
1616 status
= result_append (dm
, " [nv:");
1617 if (STATUS_NO_ERROR (status
))
1618 status
= result_append_string (dm
, number
);
1619 if (STATUS_NO_ERROR (status
))
1620 status
= result_append_char (dm
, ']');
1624 dyn_string_delete (number
);
1625 RETURN_IF_ERROR (status
);
1629 /* Demangles and emits a <v-offset>.
1631 <v-offset> ::= <offset number> _ <virtual offset number>
1632 # virtual base override, with vcall offset */
1635 demangle_v_offset (dm
)
1638 dyn_string_t number
;
1639 status_t status
= STATUS_OK
;
1641 DEMANGLE_TRACE ("v-offset", dm
);
1643 /* Demangle the offset. */
1644 number
= dyn_string_new (4);
1646 return STATUS_ALLOCATION_FAILED
;
1647 demangle_number_literally (dm
, number
, 10, 1);
1649 /* Don't display the offset unless in verbose mode. */
1652 status
= result_append (dm
, " [v:");
1653 if (STATUS_NO_ERROR (status
))
1654 status
= result_append_string (dm
, number
);
1655 if (STATUS_NO_ERROR (status
))
1656 result_append_char (dm
, ',');
1658 dyn_string_delete (number
);
1659 RETURN_IF_ERROR (status
);
1661 /* Demangle the separator. */
1662 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1664 /* Demangle the vcall offset. */
1665 number
= dyn_string_new (4);
1667 return STATUS_ALLOCATION_FAILED
;
1668 demangle_number_literally (dm
, number
, 10, 1);
1670 /* Don't display the vcall offset unless in verbose mode. */
1673 status
= result_append_string (dm
, number
);
1674 if (STATUS_NO_ERROR (status
))
1675 status
= result_append_char (dm
, ']');
1677 dyn_string_delete (number
);
1678 RETURN_IF_ERROR (status
);
1683 /* Demangles and emits a <call-offset>.
1685 <call-offset> ::= h <nv-offset> _
1686 ::= v <v-offset> _ */
1689 demangle_call_offset (dm
)
1692 DEMANGLE_TRACE ("call-offset", dm
);
1694 switch (peek_char (dm
))
1698 /* Demangle the offset. */
1699 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1700 /* Demangle the separator. */
1701 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1706 /* Demangle the offset. */
1707 RETURN_IF_ERROR (demangle_v_offset (dm
));
1708 /* Demangle the separator. */
1709 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1713 return "Unrecognized <call-offset>.";
1719 /* Demangles and emits a <special-name>.
1721 <special-name> ::= GV <object name> # Guard variable
1722 ::= TV <type> # virtual table
1724 ::= TI <type> # typeinfo structure
1725 ::= TS <type> # typeinfo name
1727 Other relevant productions include thunks:
1729 <special-name> ::= T <call-offset> <base encoding>
1730 # base is the nominal target function of thunk
1732 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1733 # base is the nominal target function of thunk
1734 # first call-offset is 'this' adjustment
1735 # second call-offset is result adjustment
1739 <call-offset> ::= h <nv-offset> _
1742 Also demangles the special g++ manglings,
1744 <special-name> ::= TC <type> <offset number> _ <base type>
1745 # construction vtable
1746 ::= TF <type> # typeinfo function (old ABI only)
1747 ::= TJ <type> # java Class structure */
1750 demangle_special_name (dm
)
1753 dyn_string_t number
;
1755 char peek
= peek_char (dm
);
1757 DEMANGLE_TRACE ("special-name", dm
);
1761 /* A guard variable name. Consume the G. */
1763 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1764 RETURN_IF_ERROR (result_append (dm
, "guard variable for "));
1765 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1767 else if (peek
== 'T')
1769 status_t status
= STATUS_OK
;
1771 /* Other C++ implementation miscellania. Consume the T. */
1774 switch (peek_char (dm
))
1777 /* Virtual table. */
1779 RETURN_IF_ERROR (result_append (dm
, "vtable for "));
1780 RETURN_IF_ERROR (demangle_type (dm
));
1784 /* VTT structure. */
1786 RETURN_IF_ERROR (result_append (dm
, "VTT for "));
1787 RETURN_IF_ERROR (demangle_type (dm
));
1791 /* Typeinfo structure. */
1793 RETURN_IF_ERROR (result_append (dm
, "typeinfo for "));
1794 RETURN_IF_ERROR (demangle_type (dm
));
1798 /* Typeinfo function. Used only in old ABI with new mangling. */
1800 RETURN_IF_ERROR (result_append (dm
, "typeinfo fn for "));
1801 RETURN_IF_ERROR (demangle_type (dm
));
1805 /* Character string containing type name, used in typeinfo. */
1807 RETURN_IF_ERROR (result_append (dm
, "typeinfo name for "));
1808 RETURN_IF_ERROR (demangle_type (dm
));
1812 /* The java Class variable corresponding to a C++ class. */
1814 RETURN_IF_ERROR (result_append (dm
, "java Class for "));
1815 RETURN_IF_ERROR (demangle_type (dm
));
1819 /* Non-virtual thunk. */
1821 RETURN_IF_ERROR (result_append (dm
, "non-virtual thunk"));
1822 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1823 /* Demangle the separator. */
1824 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1825 /* Demangle and emit the target name and function type. */
1826 RETURN_IF_ERROR (result_append (dm
, " to "));
1827 RETURN_IF_ERROR (demangle_encoding (dm
));
1831 /* Virtual thunk. */
1833 RETURN_IF_ERROR (result_append (dm
, "virtual thunk"));
1834 RETURN_IF_ERROR (demangle_v_offset (dm
));
1835 /* Demangle the separator. */
1836 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1837 /* Demangle and emit the target function. */
1838 RETURN_IF_ERROR (result_append (dm
, " to "));
1839 RETURN_IF_ERROR (demangle_encoding (dm
));
1843 /* Covariant return thunk. */
1845 RETURN_IF_ERROR (result_append (dm
, "covariant return thunk"));
1846 RETURN_IF_ERROR (demangle_call_offset (dm
));
1847 RETURN_IF_ERROR (demangle_call_offset (dm
));
1848 /* Demangle and emit the target function. */
1849 RETURN_IF_ERROR (result_append (dm
, " to "));
1850 RETURN_IF_ERROR (demangle_encoding (dm
));
1854 /* TC is a special g++ mangling for a construction vtable. */
1857 dyn_string_t derived_type
;
1860 RETURN_IF_ERROR (result_append (dm
, "construction vtable for "));
1862 /* Demangle the derived type off to the side. */
1863 RETURN_IF_ERROR (result_push (dm
));
1864 RETURN_IF_ERROR (demangle_type (dm
));
1865 derived_type
= (dyn_string_t
) result_pop (dm
);
1867 /* Demangle the offset. */
1868 number
= dyn_string_new (4);
1871 dyn_string_delete (derived_type
);
1872 return STATUS_ALLOCATION_FAILED
;
1874 demangle_number_literally (dm
, number
, 10, 1);
1875 /* Demangle the underscore separator. */
1876 status
= demangle_char (dm
, '_');
1878 /* Demangle the base type. */
1879 if (STATUS_NO_ERROR (status
))
1880 status
= demangle_type (dm
);
1882 /* Emit the derived type. */
1883 if (STATUS_NO_ERROR (status
))
1884 status
= result_append (dm
, "-in-");
1885 if (STATUS_NO_ERROR (status
))
1886 status
= result_append_string (dm
, derived_type
);
1887 dyn_string_delete (derived_type
);
1889 /* Don't display the offset unless in verbose mode. */
1892 status
= result_append_char (dm
, ' ');
1893 if (STATUS_NO_ERROR (status
))
1894 result_append_string (dm
, number
);
1896 dyn_string_delete (number
);
1897 RETURN_IF_ERROR (status
);
1900 /* If flag_strict, fall through. */
1903 return "Unrecognized <special-name>.";
1907 return STATUS_ERROR
;
1912 /* Demangles and emits a <ctor-dtor-name>.
1915 ::= C1 # complete object (in-charge) ctor
1916 ::= C2 # base object (not-in-charge) ctor
1917 ::= C3 # complete object (in-charge) allocating ctor
1918 ::= D0 # deleting (in-charge) dtor
1919 ::= D1 # complete object (in-charge) dtor
1920 ::= D2 # base object (not-in-charge) dtor */
1923 demangle_ctor_dtor_name (dm
)
1926 static const char *const ctor_flavors
[] =
1932 static const char *const dtor_flavors
[] =
1934 "in-charge deleting",
1940 char peek
= peek_char (dm
);
1942 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
1946 /* A constructor name. Consume the C. */
1948 if (peek_char (dm
) < '1' || peek_char (dm
) > '3')
1949 return "Unrecognized constructor.";
1950 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1951 /* Print the flavor of the constructor if in verbose mode. */
1952 flavor
= next_char (dm
) - '1';
1955 RETURN_IF_ERROR (result_append (dm
, "["));
1956 RETURN_IF_ERROR (result_append (dm
, ctor_flavors
[flavor
]));
1957 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1960 else if (peek
== 'D')
1962 /* A destructor name. Consume the D. */
1964 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
1965 return "Unrecognized destructor.";
1966 RETURN_IF_ERROR (result_append_char (dm
, '~'));
1967 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1968 /* Print the flavor of the destructor if in verbose mode. */
1969 flavor
= next_char (dm
) - '0';
1972 RETURN_IF_ERROR (result_append (dm
, " ["));
1973 RETURN_IF_ERROR (result_append (dm
, dtor_flavors
[flavor
]));
1974 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1978 return STATUS_ERROR
;
1983 /* Handle pointer, reference, and pointer-to-member cases for
1984 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1985 build a pointer/reference type. We snarf all these, plus the
1986 following <type>, all at once since we need to know whether we have
1987 a pointer to data or pointer to function to construct the right
1988 output syntax. C++'s pointer syntax is hairy.
1990 This function adds substitution candidates for every nested
1991 pointer/reference type it processes, including the outermost, final
1992 type, assuming the substitution starts at SUBSTITUTION_START in the
1993 demangling result. For example, if this function demangles
1994 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
1995 `Foo**', in that order.
1997 *INSERT_POS is a quantity used internally, when this function calls
1998 itself recursively, to figure out where to insert pointer
1999 punctuation on the way up. On entry to this function, INSERT_POS
2000 should point to a temporary value, but that value need not be
2005 ::= <pointer-to-member-type>
2007 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2010 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2013 int substitution_start
;
2017 int is_substitution_candidate
= 1;
2019 DEMANGLE_TRACE ("type*", dm
);
2021 /* Scan forward, collecting pointers and references into symbols,
2022 until we hit something else. Then emit the type. */
2023 next
= peek_char (dm
);
2026 /* A pointer. Snarf the `P'. */
2028 /* Demangle the underlying type. */
2029 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2030 substitution_start
));
2031 /* Insert an asterisk where we're told to; it doesn't
2032 necessarily go at the end. */
2033 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2034 /* The next (outermost) pointer or reference character should go
2038 else if (next
== 'R')
2040 /* A reference. Snarf the `R'. */
2042 /* Demangle the underlying type. */
2043 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2044 substitution_start
));
2045 /* Insert an ampersand where we're told to; it doesn't
2046 necessarily go at the end. */
2047 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2048 /* The next (outermost) pointer or reference character should go
2052 else if (next
== 'M')
2054 /* A pointer-to-member. */
2055 dyn_string_t class_type
;
2060 /* Capture the type of which this is a pointer-to-member. */
2061 RETURN_IF_ERROR (result_push (dm
));
2062 RETURN_IF_ERROR (demangle_type (dm
));
2063 class_type
= (dyn_string_t
) result_pop (dm
);
2065 if (peek_char (dm
) == 'F')
2066 /* A pointer-to-member function. We want output along the
2067 lines of `void (C::*) (int, int)'. Demangle the function
2068 type, which would in this case give `void () (int, int)'
2069 and set *insert_pos to the spot between the first
2071 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2074 /* A pointer-to-member variable. Demangle the type of the
2075 pointed-to member. */
2076 status
= demangle_type (dm
);
2077 /* Make it pretty. */
2078 if (STATUS_NO_ERROR (status
))
2079 status
= result_append_space (dm
);
2080 /* The pointer-to-member notation (e.g. `C::*') follows the
2082 *insert_pos
= result_length (dm
);
2085 /* Build the pointer-to-member notation. */
2086 if (STATUS_NO_ERROR (status
))
2087 status
= result_insert (dm
, *insert_pos
, "::*");
2088 if (STATUS_NO_ERROR (status
))
2089 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2090 /* There may be additional levels of (pointer or reference)
2091 indirection in this type. If so, the `*' and `&' should be
2092 added after the pointer-to-member notation (e.g. `C::*&' for
2093 a reference to a pointer-to-member of class C). */
2094 *insert_pos
+= dyn_string_length (class_type
) + 3;
2097 dyn_string_delete (class_type
);
2099 RETURN_IF_ERROR (status
);
2101 else if (next
== 'F')
2103 /* Ooh, tricky, a pointer-to-function. When we demangle the
2104 function type, the return type should go at the very
2106 *insert_pos
= result_length (dm
);
2107 /* The parentheses indicate this is a function pointer or
2109 RETURN_IF_ERROR (result_append (dm
, "()"));
2110 /* Now demangle the function type. The return type will be
2111 inserted before the `()', and the argument list will go after
2113 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2114 /* We should now have something along the lines of
2115 `void () (int, int)'. The pointer or reference characters
2116 have to inside the first set of parentheses. *insert_pos has
2117 already been updated to point past the end of the return
2118 type. Move it one character over so it points inside the
2124 /* No more pointer or reference tokens; this is therefore a
2125 pointer to data. Finish up by demangling the underlying
2127 RETURN_IF_ERROR (demangle_type (dm
));
2128 /* The pointer or reference characters follow the underlying
2129 type, as in `int*&'. */
2130 *insert_pos
= result_length (dm
);
2131 /* Because of the production <type> ::= <substitution>,
2132 demangle_type will already have added the underlying type as
2133 a substitution candidate. Don't do it again. */
2134 is_substitution_candidate
= 0;
2137 if (is_substitution_candidate
)
2138 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2143 /* Demangles and emits a <type>.
2145 <type> ::= <builtin-type>
2147 ::= <class-enum-type>
2149 ::= <pointer-to-member-type>
2150 ::= <template-param>
2151 ::= <template-template-param> <template-args>
2152 ::= <CV-qualifiers> <type>
2153 ::= P <type> # pointer-to
2154 ::= R <type> # reference-to
2155 ::= C <type> # complex pair (C 2000)
2156 ::= G <type> # imaginary (C 2000)
2157 ::= U <source-name> <type> # vendor extended type qualifier
2158 ::= <substitution> */
2164 int start
= substitution_start (dm
);
2165 char peek
= peek_char (dm
);
2167 int encode_return_type
= 0;
2168 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2171 /* A <type> can be a <substitution>; therefore, this <type> is a
2172 substitution candidate unless a special condition holds (see
2174 int is_substitution_candidate
= 1;
2176 DEMANGLE_TRACE ("type", dm
);
2178 /* A <class-enum-type> can start with a digit (a <source-name>), an
2179 N (a <nested-name>), or a Z (a <local-name>). */
2180 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2181 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2182 /* Lower-case letters begin <builtin-type>s, except for `r', which
2183 denotes restrict. */
2184 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2186 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2187 /* Built-in types are not substitution candidates. */
2188 is_substitution_candidate
= 0;
2196 /* CV-qualifiers (including restrict). We have to demangle
2197 them off to the side, since C++ syntax puts them in a funny
2198 place for qualified pointer and reference types. */
2201 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2203 if (cv_qualifiers
== NULL
)
2204 return STATUS_ALLOCATION_FAILED
;
2206 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2208 /* If the qualifiers apply to a pointer or reference, they
2209 need to come after the whole qualified type. */
2210 if (peek_char (dm
) == 'P' || peek_char (dm
) == 'R')
2212 status
= demangle_type (dm
);
2213 if (STATUS_NO_ERROR (status
))
2214 status
= result_append_space (dm
);
2215 if (STATUS_NO_ERROR (status
))
2216 status
= result_append_string (dm
, cv_qualifiers
);
2218 /* Otherwise, the qualifiers come first. */
2221 status
= result_append_string (dm
, cv_qualifiers
);
2222 if (STATUS_NO_ERROR (status
))
2223 status
= result_append_space (dm
);
2224 if (STATUS_NO_ERROR (status
))
2225 status
= demangle_type (dm
);
2228 dyn_string_delete (cv_qualifiers
);
2229 RETURN_IF_ERROR (status
);
2234 return "Non-pointer or -reference function type.";
2237 RETURN_IF_ERROR (demangle_array_type (dm
));
2241 /* It's either a <template-param> or a
2242 <template-template-param>. In either case, demangle the
2244 RETURN_IF_ERROR (demangle_template_param (dm
));
2246 /* Check for a template argument list; if one is found, it's a
2247 <template-template-param> ::= <template-param>
2248 ::= <substitution> */
2249 if (peek_char (dm
) == 'I')
2251 /* Add a substitution candidate. The template parameter
2252 `T' token is a substitution candidate by itself,
2253 without the template argument list. */
2254 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2256 /* Now demangle the template argument list. */
2257 RETURN_IF_ERROR (demangle_template_args (dm
));
2258 /* The entire type, including the template template
2259 parameter and its argument list, will be added as a
2260 substitution candidate below. */
2266 /* First check if this is a special substitution. If it is,
2267 this is a <class-enum-type>. Special substitutions have a
2268 letter following the `S'; other substitutions have a digit
2270 peek_next
= peek_char_next (dm
);
2271 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2273 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2275 /* The substituted name may have been a template name.
2276 Check if template arguments follow, and if so, demangle
2278 if (peek_char (dm
) == 'I')
2279 RETURN_IF_ERROR (demangle_template_args (dm
));
2281 /* A substitution token is not itself a substitution
2282 candidate. (However, if the substituted template is
2283 instantiated, the resulting type is.) */
2284 is_substitution_candidate
= 0;
2288 /* Now some trickiness. We have a special substitution
2289 here. Often, the special substitution provides the
2290 name of a template that's subsequently instantiated,
2291 for instance `SaIcE' => std::allocator<char>. In these
2292 cases we need to add a substitution candidate for the
2293 entire <class-enum-type> and thus don't want to clear
2294 the is_substitution_candidate flag.
2296 However, it's possible that what we have here is a
2297 substitution token representing an entire type, such as
2298 `Ss' => std::string. In this case, we mustn't add a
2299 new substitution candidate for this substitution token.
2300 To detect this case, remember where the start of the
2301 substitution token is. */
2302 const char *next
= dm
->next
;
2303 /* Now demangle the <class-enum-type>. */
2305 (demangle_class_enum_type (dm
, &encode_return_type
));
2306 /* If all that was just demangled is the two-character
2307 special substitution token, supress the addition of a
2308 new candidate for it. */
2309 if (dm
->next
== next
+ 2)
2310 is_substitution_candidate
= 0;
2318 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2319 /* demangle_type_ptr adds all applicable substitution
2321 is_substitution_candidate
= 0;
2325 /* A C99 complex type. */
2326 RETURN_IF_ERROR (result_append (dm
, "complex "));
2328 RETURN_IF_ERROR (demangle_type (dm
));
2332 /* A C99 imaginary type. */
2333 RETURN_IF_ERROR (result_append (dm
, "imaginary "));
2335 RETURN_IF_ERROR (demangle_type (dm
));
2339 /* Vendor-extended type qualifier. */
2341 RETURN_IF_ERROR (demangle_source_name (dm
));
2342 RETURN_IF_ERROR (result_append_char (dm
, ' '));
2343 RETURN_IF_ERROR (demangle_type (dm
));
2347 return "Unexpected character in <type>.";
2350 if (is_substitution_candidate
)
2351 /* Add a new substitution for the type. If this type was a
2352 <template-param>, pass its index since from the point of
2353 substitutions; a <template-param> token is a substitution
2354 candidate distinct from the type that is substituted for it. */
2355 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2357 /* Pop off template argument lists added during mangling of this
2359 pop_to_template_arg_list (dm
, old_arg_list
);
2364 /* C++ source names of builtin types, indexed by the mangled code
2365 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2366 static const char *const builtin_type_names
[26] =
2368 "signed char", /* a */
2372 "long double", /* e */
2374 "__float128", /* g */
2375 "unsigned char", /* h */
2380 "unsigned long", /* m */
2382 "unsigned __int128", /* o */
2387 "unsigned short", /* t */
2391 "long long", /* x */
2392 "unsigned long long", /* y */
2396 /* Demangles and emits a <builtin-type>.
2398 <builtin-type> ::= v # void
2403 ::= h # unsigned char
2405 ::= t # unsigned short
2407 ::= j # unsigned int
2409 ::= m # unsigned long
2410 ::= x # long long, __int64
2411 ::= y # unsigned long long, __int64
2413 ::= o # unsigned __int128
2416 ::= e # long double, __float80
2419 ::= u <source-name> # vendor extended type */
2422 demangle_builtin_type (dm
)
2426 char code
= peek_char (dm
);
2428 DEMANGLE_TRACE ("builtin-type", dm
);
2433 RETURN_IF_ERROR (demangle_source_name (dm
));
2436 else if (code
>= 'a' && code
<= 'z')
2438 const char *type_name
= builtin_type_names
[code
- 'a'];
2439 if (type_name
== NULL
)
2440 return "Unrecognized <builtin-type> code.";
2442 RETURN_IF_ERROR (result_append (dm
, type_name
));
2447 return "Non-alphabetic <builtin-type> code.";
2450 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2451 restrict) at the current position. The qualifiers are appended to
2452 QUALIFIERS. Returns STATUS_OK. */
2455 demangle_CV_qualifiers (dm
, qualifiers
)
2457 dyn_string_t qualifiers
;
2459 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2463 switch (peek_char (dm
))
2466 if (!dyn_string_append_space (qualifiers
))
2467 return STATUS_ALLOCATION_FAILED
;
2468 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2469 return STATUS_ALLOCATION_FAILED
;
2473 if (!dyn_string_append_space (qualifiers
))
2474 return STATUS_ALLOCATION_FAILED
;
2475 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2476 return STATUS_ALLOCATION_FAILED
;
2480 if (!dyn_string_append_space (qualifiers
))
2481 return STATUS_ALLOCATION_FAILED
;
2482 if (!dyn_string_append_cstr (qualifiers
, "const"))
2483 return STATUS_ALLOCATION_FAILED
;
2494 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2495 position in the result string of the start of the function
2496 identifier, at which the function's return type will be inserted;
2497 *FUNCTION_NAME_POS is updated to position past the end of the
2498 function's return type.
2500 <function-type> ::= F [Y] <bare-function-type> E */
2503 demangle_function_type (dm
, function_name_pos
)
2505 int *function_name_pos
;
2507 DEMANGLE_TRACE ("function-type", dm
);
2508 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2509 if (peek_char (dm
) == 'Y')
2511 /* Indicate this function has C linkage if in verbose mode. */
2513 RETURN_IF_ERROR (result_append (dm
, " [extern \"C\"] "));
2516 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2517 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2521 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2522 position in the result string at which the function return type
2523 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2524 function's return type is assumed not to be encoded.
2526 <bare-function-type> ::= <signature type>+ */
2529 demangle_bare_function_type (dm
, return_type_pos
)
2531 int *return_type_pos
;
2533 /* Sequence is the index of the current function parameter, counting
2534 from zero. The value -1 denotes the return type. */
2536 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2538 DEMANGLE_TRACE ("bare-function-type", dm
);
2540 RETURN_IF_ERROR (result_append_char (dm
, '('));
2541 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2544 /* We're decoding the function's return type. */
2546 dyn_string_t return_type
;
2547 status_t status
= STATUS_OK
;
2549 /* Decode the return type off to the side. */
2550 RETURN_IF_ERROR (result_push (dm
));
2551 RETURN_IF_ERROR (demangle_type (dm
));
2552 return_type
= (dyn_string_t
) result_pop (dm
);
2554 /* Add a space to the end of the type. Insert the return
2555 type where we've been asked to. */
2556 if (!dyn_string_append_space (return_type
))
2557 status
= STATUS_ALLOCATION_FAILED
;
2558 if (STATUS_NO_ERROR (status
))
2560 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2562 status
= STATUS_ALLOCATION_FAILED
;
2564 *return_type_pos
+= dyn_string_length (return_type
);
2567 dyn_string_delete (return_type
);
2568 RETURN_IF_ERROR (status
);
2572 /* Skip `void' parameter types. One should only occur as
2573 the only type in a parameter list; in that case, we want
2574 to print `foo ()' instead of `foo (void)'. */
2575 if (peek_char (dm
) == 'v')
2576 /* Consume the v. */
2580 /* Separate parameter types by commas. */
2582 RETURN_IF_ERROR (result_append (dm
, ", "));
2583 /* Demangle the type. */
2584 RETURN_IF_ERROR (demangle_type (dm
));
2590 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2592 /* We should have demangled at least one parameter type (which would
2593 be void, for a function that takes no parameters), plus the
2594 return type, if we were supposed to demangle that. */
2596 return "Missing function return type.";
2597 else if (sequence
== 0)
2598 return "Missing function parameter.";
2603 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2604 non-zero if the type is a template-id, zero otherwise.
2606 <class-enum-type> ::= <name> */
2609 demangle_class_enum_type (dm
, encode_return_type
)
2611 int *encode_return_type
;
2613 DEMANGLE_TRACE ("class-enum-type", dm
);
2615 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2619 /* Demangles and emits an <array-type>.
2621 <array-type> ::= A [<dimension number>] _ <element type>
2622 ::= A <dimension expression> _ <element type> */
2625 demangle_array_type (dm
)
2628 status_t status
= STATUS_OK
;
2629 dyn_string_t array_size
= NULL
;
2632 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2634 /* Demangle the array size into array_size. */
2635 peek
= peek_char (dm
);
2637 /* Array bound is omitted. This is a C99-style VLA. */
2639 else if (IS_DIGIT (peek_char (dm
)))
2641 /* It looks like a constant array bound. */
2642 array_size
= dyn_string_new (10);
2643 if (array_size
== NULL
)
2644 return STATUS_ALLOCATION_FAILED
;
2645 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2649 /* Anything is must be an expression for a nont-constant array
2650 bound. This happens if the array type occurs in a template
2651 and the array bound references a template parameter. */
2652 RETURN_IF_ERROR (result_push (dm
));
2653 RETURN_IF_ERROR (demangle_expression (dm
));
2654 array_size
= (dyn_string_t
) result_pop (dm
);
2656 /* array_size may have been allocated by now, so we can't use
2657 RETURN_IF_ERROR until it's been deallocated. */
2659 /* Demangle the base type of the array. */
2660 if (STATUS_NO_ERROR (status
))
2661 status
= demangle_char (dm
, '_');
2662 if (STATUS_NO_ERROR (status
))
2663 status
= demangle_type (dm
);
2665 /* Emit the array dimension syntax. */
2666 if (STATUS_NO_ERROR (status
))
2667 status
= result_append_char (dm
, '[');
2668 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2669 status
= result_append_string (dm
, array_size
);
2670 if (STATUS_NO_ERROR (status
))
2671 status
= result_append_char (dm
, ']');
2672 if (array_size
!= NULL
)
2673 dyn_string_delete (array_size
);
2675 RETURN_IF_ERROR (status
);
2680 /* Demangles and emits a <template-param>.
2682 <template-param> ::= T_ # first template parameter
2683 ::= T <parameter-2 number> _ */
2686 demangle_template_param (dm
)
2690 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2693 DEMANGLE_TRACE ("template-param", dm
);
2695 /* Make sure there is a template argmust list in which to look up
2696 this parameter reference. */
2697 if (current_arg_list
== NULL
)
2698 return "Template parameter outside of template.";
2700 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2701 if (peek_char (dm
) == '_')
2705 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2708 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2710 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2712 /* parm_number exceeded the number of arguments in the current
2713 template argument list. */
2714 return "Template parameter number out of bounds.";
2715 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2720 /* Demangles and emits a <template-args>.
2722 <template-args> ::= I <template-arg>+ E */
2725 demangle_template_args (dm
)
2729 dyn_string_t old_last_source_name
;
2730 template_arg_list_t arg_list
= template_arg_list_new ();
2732 if (arg_list
== NULL
)
2733 return STATUS_ALLOCATION_FAILED
;
2735 /* Preserve the most recently demangled source name. */
2736 old_last_source_name
= dm
->last_source_name
;
2737 dm
->last_source_name
= dyn_string_new (0);
2739 DEMANGLE_TRACE ("template-args", dm
);
2741 if (dm
->last_source_name
== NULL
)
2742 return STATUS_ALLOCATION_FAILED
;
2744 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2745 RETURN_IF_ERROR (result_open_template_list (dm
));
2753 RETURN_IF_ERROR (result_append (dm
, ", "));
2755 /* Capture the template arg. */
2756 RETURN_IF_ERROR (result_push (dm
));
2757 RETURN_IF_ERROR (demangle_template_arg (dm
));
2758 arg
= result_pop (dm
);
2760 /* Emit it in the demangled name. */
2761 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2763 /* Save it for use in expanding <template-param>s. */
2764 template_arg_list_add_arg (arg_list
, arg
);
2766 while (peek_char (dm
) != 'E');
2767 /* Append the '>'. */
2768 RETURN_IF_ERROR (result_close_template_list (dm
));
2770 /* Consume the 'E'. */
2773 /* Restore the most recent demangled source name. */
2774 dyn_string_delete (dm
->last_source_name
);
2775 dm
->last_source_name
= old_last_source_name
;
2777 /* Push the list onto the top of the stack of template argument
2778 lists, so that arguments from it are used from now on when
2779 expanding <template-param>s. */
2780 push_template_arg_list (dm
, arg_list
);
2785 /* This function, which does not correspond to a production in the
2786 mangling spec, handles the `literal' production for both
2787 <template-arg> and <expr-primary>. It does not expect or consume
2788 the initial `L' or final `E'. The demangling is given by:
2790 <literal> ::= <type> </value/ number>
2792 and the emitted output is `(type)number'. */
2795 demangle_literal (dm
)
2798 char peek
= peek_char (dm
);
2799 dyn_string_t value_string
;
2802 DEMANGLE_TRACE ("literal", dm
);
2804 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2806 /* If not in verbose mode and this is a builtin type, see if we
2807 can produce simpler numerical output. In particular, for
2808 integer types shorter than `long', just write the number
2809 without type information; for bools, write `true' or `false'.
2810 Other refinements could be made here too. */
2812 /* This constant string is used to map from <builtin-type> codes
2813 (26 letters of the alphabet) to codes that determine how the
2814 value will be displayed. The codes are:
2818 A space means the value will be represented using cast
2820 static const char *const code_map
= "ibi iii ll ii i ";
2822 char code
= code_map
[peek
- 'a'];
2823 /* FIXME: Implement demangling of floats and doubles. */
2825 return STATUS_UNIMPLEMENTED
;
2828 /* It's a boolean. */
2831 /* Consume the b. */
2833 /* Look at the next character. It should be 0 or 1,
2834 corresponding to false or true, respectively. */
2835 value
= peek_char (dm
);
2837 RETURN_IF_ERROR (result_append (dm
, "false"));
2838 else if (value
== '1')
2839 RETURN_IF_ERROR (result_append (dm
, "true"));
2841 return "Unrecognized bool constant.";
2842 /* Consume the 0 or 1. */
2846 else if (code
== 'i' || code
== 'l')
2848 /* It's an integer or long. */
2850 /* Consume the type character. */
2853 /* Demangle the number and write it out. */
2854 value_string
= dyn_string_new (0);
2855 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2856 if (STATUS_NO_ERROR (status
))
2857 status
= result_append_string (dm
, value_string
);
2858 /* For long integers, append an l. */
2859 if (code
== 'l' && STATUS_NO_ERROR (status
))
2860 status
= result_append_char (dm
, code
);
2861 dyn_string_delete (value_string
);
2863 RETURN_IF_ERROR (status
);
2866 /* ...else code == ' ', so fall through to represent this
2867 literal's type explicitly using cast syntax. */
2870 RETURN_IF_ERROR (result_append_char (dm
, '('));
2871 RETURN_IF_ERROR (demangle_type (dm
));
2872 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2874 value_string
= dyn_string_new (0);
2875 if (value_string
== NULL
)
2876 return STATUS_ALLOCATION_FAILED
;
2878 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2879 if (STATUS_NO_ERROR (status
))
2880 status
= result_append_string (dm
, value_string
);
2881 dyn_string_delete (value_string
);
2882 RETURN_IF_ERROR (status
);
2887 /* Demangles and emits a <template-arg>.
2889 <template-arg> ::= <type> # type
2890 ::= L <type> <value number> E # literal
2891 ::= LZ <encoding> E # external name
2892 ::= X <expression> E # expression */
2895 demangle_template_arg (dm
)
2898 DEMANGLE_TRACE ("template-arg", dm
);
2900 switch (peek_char (dm
))
2905 if (peek_char (dm
) == 'Z')
2907 /* External name. */
2909 /* FIXME: Standard is contradictory here. */
2910 RETURN_IF_ERROR (demangle_encoding (dm
));
2913 RETURN_IF_ERROR (demangle_literal (dm
));
2914 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2920 RETURN_IF_ERROR (demangle_expression (dm
));
2921 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2925 RETURN_IF_ERROR (demangle_type (dm
));
2932 /* Demangles and emits an <expression>.
2934 <expression> ::= <unary operator-name> <expression>
2935 ::= <binary operator-name> <expression> <expression>
2937 ::= <scope-expression> */
2940 demangle_expression (dm
)
2943 char peek
= peek_char (dm
);
2945 DEMANGLE_TRACE ("expression", dm
);
2947 if (peek
== 'L' || peek
== 'T')
2948 RETURN_IF_ERROR (demangle_expr_primary (dm
));
2949 else if (peek
== 's' && peek_char_next (dm
) == 'r')
2950 RETURN_IF_ERROR (demangle_scope_expression (dm
));
2952 /* An operator expression. */
2955 status_t status
= STATUS_OK
;
2956 dyn_string_t operator_name
;
2958 /* We have an operator name. Since we want to output binary
2959 operations in infix notation, capture the operator name
2961 RETURN_IF_ERROR (result_push (dm
));
2962 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
2963 operator_name
= (dyn_string_t
) result_pop (dm
);
2965 /* If it's binary, do an operand first. */
2968 status
= result_append_char (dm
, '(');
2969 if (STATUS_NO_ERROR (status
))
2970 status
= demangle_expression (dm
);
2971 if (STATUS_NO_ERROR (status
))
2972 status
= result_append_char (dm
, ')');
2975 /* Emit the operator. */
2976 if (STATUS_NO_ERROR (status
))
2977 status
= result_append_string (dm
, operator_name
);
2978 dyn_string_delete (operator_name
);
2979 RETURN_IF_ERROR (status
);
2981 /* Emit its second (if binary) or only (if unary) operand. */
2982 RETURN_IF_ERROR (result_append_char (dm
, '('));
2983 RETURN_IF_ERROR (demangle_expression (dm
));
2984 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2986 /* The ternary operator takes a third operand. */
2989 RETURN_IF_ERROR (result_append (dm
, ":("));
2990 RETURN_IF_ERROR (demangle_expression (dm
));
2991 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2998 /* Demangles and emits a <scope-expression>.
3000 <scope-expression> ::= sr <qualifying type> <source-name>
3001 ::= sr <qualifying type> <encoding> */
3004 demangle_scope_expression (dm
)
3007 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3008 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3009 RETURN_IF_ERROR (demangle_type (dm
));
3010 RETURN_IF_ERROR (result_append (dm
, "::"));
3011 RETURN_IF_ERROR (demangle_encoding (dm
));
3015 /* Demangles and emits an <expr-primary>.
3017 <expr-primary> ::= <template-param>
3018 ::= L <type> <value number> E # literal
3019 ::= L <mangled-name> E # external name */
3022 demangle_expr_primary (dm
)
3025 char peek
= peek_char (dm
);
3027 DEMANGLE_TRACE ("expr-primary", dm
);
3030 RETURN_IF_ERROR (demangle_template_param (dm
));
3031 else if (peek
== 'L')
3033 /* Consume the `L'. */
3035 peek
= peek_char (dm
);
3038 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3040 RETURN_IF_ERROR (demangle_literal (dm
));
3042 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3045 return STATUS_ERROR
;
3050 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3051 if the substitution is the name of a template, zero otherwise.
3053 <substitution> ::= S <seq-id> _
3057 ::= Sa # ::std::allocator
3058 ::= Sb # ::std::basic_string
3059 ::= Ss # ::std::basic_string<char,
3060 ::std::char_traits<char>,
3061 ::std::allocator<char> >
3062 ::= Si # ::std::basic_istream<char,
3063 std::char_traits<char> >
3064 ::= So # ::std::basic_ostream<char,
3065 std::char_traits<char> >
3066 ::= Sd # ::std::basic_iostream<char,
3067 std::char_traits<char> >
3071 demangle_substitution (dm
, template_p
)
3079 DEMANGLE_TRACE ("substitution", dm
);
3081 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3083 /* Scan the substitution sequence index. A missing number denotes
3085 peek
= peek_char (dm
);
3088 /* If the following character is 0-9 or a capital letter, interpret
3089 the sequence up to the next underscore as a base-36 substitution
3091 else if (IS_DIGIT ((unsigned char) peek
)
3092 || (peek
>= 'A' && peek
<= 'Z'))
3093 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3096 const char *new_last_source_name
= NULL
;
3101 RETURN_IF_ERROR (result_append (dm
, "std"));
3105 RETURN_IF_ERROR (result_append (dm
, "std::allocator"));
3106 new_last_source_name
= "allocator";
3111 RETURN_IF_ERROR (result_append (dm
, "std::basic_string"));
3112 new_last_source_name
= "basic_string";
3119 RETURN_IF_ERROR (result_append (dm
, "std::string"));
3120 new_last_source_name
= "string";
3124 RETURN_IF_ERROR (result_append (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3125 new_last_source_name
= "basic_string";
3133 RETURN_IF_ERROR (result_append (dm
, "std::istream"));
3134 new_last_source_name
= "istream";
3138 RETURN_IF_ERROR (result_append (dm
, "std::basic_istream<char, std::char_traints<char> >"));
3139 new_last_source_name
= "basic_istream";
3147 RETURN_IF_ERROR (result_append (dm
, "std::ostream"));
3148 new_last_source_name
= "ostream";
3152 RETURN_IF_ERROR (result_append (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3153 new_last_source_name
= "basic_ostream";
3161 RETURN_IF_ERROR (result_append (dm
, "std::iostream"));
3162 new_last_source_name
= "iostream";
3166 RETURN_IF_ERROR (result_append (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3167 new_last_source_name
= "basic_iostream";
3173 return "Unrecognized <substitution>.";
3176 /* Consume the character we just processed. */
3179 if (new_last_source_name
!= NULL
)
3181 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3182 new_last_source_name
))
3183 return STATUS_ALLOCATION_FAILED
;
3189 /* Look up the substitution text. Since `S_' is the most recent
3190 substitution, `S0_' is the second-most-recent, etc., shift the
3191 numbering by one. */
3192 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3194 return "Substitution number out of range.";
3196 /* Emit the substitution text. */
3197 RETURN_IF_ERROR (result_append_string (dm
, text
));
3199 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3203 /* Demangles and emits a <local-name>.
3205 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3206 := Z <function encoding> E s [<discriminator>] */
3209 demangle_local_name (dm
)
3212 DEMANGLE_TRACE ("local-name", dm
);
3214 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3215 RETURN_IF_ERROR (demangle_encoding (dm
));
3216 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3217 RETURN_IF_ERROR (result_append (dm
, "::"));
3219 if (peek_char (dm
) == 's')
3221 /* Local character string literal. */
3222 RETURN_IF_ERROR (result_append (dm
, "string literal"));
3223 /* Consume the s. */
3225 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3230 /* Local name for some other entity. Demangle its name. */
3231 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3232 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3238 /* Optimonally demangles and emits a <discriminator>. If there is no
3239 <discriminator> at the current position in the mangled string, the
3240 descriminator is assumed to be zero. Emit the discriminator number
3241 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3242 discriminator is zero.
3244 <discriminator> ::= _ <number> */
3247 demangle_discriminator (dm
, suppress_first
)
3251 /* Output for <discriminator>s to the demangled name is completely
3252 suppressed if not in verbose mode. */
3254 if (peek_char (dm
) == '_')
3256 /* Consume the underscore. */
3259 RETURN_IF_ERROR (result_append (dm
, " [#"));
3260 /* Check if there's a number following the underscore. */
3261 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3264 /* Demangle the number. */
3265 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3267 /* Write the discriminator. The mangled number is two
3268 less than the discriminator ordinal, counting from
3270 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 2,
3271 (dyn_string_t
) dm
->result
));
3276 /* A missing digit correspond to one. */
3277 RETURN_IF_ERROR (result_append_char (dm
, '1'));
3280 RETURN_IF_ERROR (result_append_char (dm
, ']'));
3282 else if (!suppress_first
)
3285 RETURN_IF_ERROR (result_append (dm
, " [#0]"));
3291 /* Demangle NAME into RESULT, which must be an initialized
3292 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3293 an error message, and the contents of RESULT are unchanged. */
3296 cp_demangle (name
, result
)
3298 dyn_string_t result
;
3301 int length
= strlen (name
);
3303 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3305 demangling_t dm
= demangling_new (name
);
3307 return STATUS_ALLOCATION_FAILED
;
3309 status
= result_push (dm
);
3310 if (status
!= STATUS_OK
)
3312 demangling_delete (dm
);
3316 status
= demangle_mangled_name (dm
);
3317 if (STATUS_NO_ERROR (status
))
3319 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3320 if (!dyn_string_copy (result
, demangled
))
3321 return STATUS_ALLOCATION_FAILED
;
3322 dyn_string_delete (demangled
);
3325 demangling_delete (dm
);
3329 /* It's evidently not a mangled C++ name. It could be the name
3330 of something with C linkage, though, so just copy NAME into
3332 if (!dyn_string_copy_cstr (result
, name
))
3333 return STATUS_ALLOCATION_FAILED
;
3340 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3341 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3342 an error message, and the contents of RESULT are unchanged. */
3346 cp_demangle_type (type_name
, result
)
3347 const char* type_name
;
3348 dyn_string_t result
;
3351 demangling_t dm
= demangling_new (type_name
);
3354 return STATUS_ALLOCATION_FAILED
;
3356 /* Demangle the type name. The demangled name is stored in dm. */
3357 status
= result_push (dm
);
3358 if (status
!= STATUS_OK
)
3360 demangling_delete (dm
);
3364 status
= demangle_type (dm
);
3366 if (STATUS_NO_ERROR (status
))
3368 /* The demangling succeeded. Pop the result out of dm and copy
3370 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3371 if (!dyn_string_copy (result
, demangled
))
3372 return STATUS_ALLOCATION_FAILED
;
3373 dyn_string_delete (demangled
);
3377 demangling_delete (dm
);
3382 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3384 /* ABI-mandated entry point in the C++ runtime library for performing
3385 demangling. MANGLED_NAME is a NUL-terminated character string
3386 containing the name to be demangled.
3388 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3389 *LENGTH bytes, into which the demangled name is stored. If
3390 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3391 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3392 is placed in a region of memory allocated with malloc.
3394 If LENGTH is non-NULL, the length of the buffer conaining the
3395 demangled name, is placed in *LENGTH.
3397 The return value is a pointer to the start of the NUL-terminated
3398 demangled name, or NULL if the demangling fails. The caller is
3399 responsible for deallocating this memory using free.
3401 *STATUS is set to one of the following values:
3402 0: The demangling operation succeeded.
3403 -1: A memory allocation failiure occurred.
3404 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3405 -3: One of the arguments is invalid.
3407 The demagling is performed using the C++ ABI mangling rules, with
3411 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3412 const char *mangled_name
;
3413 char *output_buffer
;
3417 struct dyn_string demangled_name
;
3423 if (mangled_name
== NULL
) {
3428 /* Did the caller provide a buffer for the demangled name? */
3429 if (output_buffer
== NULL
) {
3430 /* No; dyn_string will malloc a buffer for us. */
3431 if (!dyn_string_init (&demangled_name
, 0))
3438 /* Yes. Check that the length was provided. */
3439 if (length
== NULL
) {
3443 /* Install the buffer into a dyn_string. */
3444 demangled_name
.allocated
= *length
;
3445 demangled_name
.length
= 0;
3446 demangled_name
.s
= output_buffer
;
3449 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3450 /* MANGLED_NAME apprears to be a function or variable name.
3451 Demangle it accordingly. */
3452 result
= cp_demangle (mangled_name
, &demangled_name
);
3454 /* Try to demangled MANGLED_NAME as the name of a type. */
3455 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3457 if (result
== STATUS_OK
)
3458 /* The demangling succeeded. */
3460 /* If LENGTH isn't NULL, store the allocated buffer length
3461 there; the buffer may have been realloced by dyn_string
3464 *length
= demangled_name
.allocated
;
3465 /* The operation was a success. */
3467 return dyn_string_buf (&demangled_name
);
3469 else if (result
== STATUS_ALLOCATION_FAILED
)
3470 /* A call to malloc or realloc failed during the demangling
3477 /* The demangling failed for another reason, most probably because
3478 MANGLED_NAME isn't a valid mangled name. */
3480 /* If the buffer containing the demangled name wasn't provided
3481 by the caller, free it. */
3482 if (output_buffer
== NULL
)
3483 free (dyn_string_buf (&demangled_name
));
3489 #else /* !IN_LIBGCC2 */
3491 /* Variant entry point for integration with the existing cplus-dem
3492 demangler. Attempts to demangle MANGLED. If the demangling
3493 succeeds, returns a buffer, allocated with malloc, containing the
3494 demangled name. The caller must deallocate the buffer using free.
3495 If the demangling failes, returns NULL. */
3498 cplus_demangle_new_abi (mangled
)
3499 const char* mangled
;
3501 /* Create a dyn_string to hold the demangled name. */
3502 dyn_string_t demangled
= dyn_string_new (0);
3503 /* Attempt the demangling. */
3504 status_t status
= cp_demangle ((char *) mangled
, demangled
);
3505 if (STATUS_NO_ERROR (status
))
3506 /* Demangling succeeded. */
3508 /* Grab the demangled result from the dyn_string. It was
3509 allocated with malloc, so we can return it directly. */
3510 char *return_value
= dyn_string_release (demangled
);
3511 /* Hand back the demangled name. */
3512 return return_value
;
3514 else if (status
== STATUS_ALLOCATION_FAILED
)
3516 fprintf (stderr
, "Memory allocation failed.\n");
3520 /* Demangling failed. */
3522 dyn_string_delete (demangled
);
3527 #endif /* IN_LIBGCC2 */
3529 #ifdef STANDALONE_DEMANGLER
3533 static void print_usage
3534 PARAMS ((FILE* fp
, int exit_value
));
3536 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3537 #define is_mangled_char(CHAR) \
3538 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3539 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3541 /* The name of this program, as invoked. */
3542 const char* program_name
;
3544 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3547 print_usage (fp
, exit_value
)
3551 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3552 fprintf (fp
, "Options:\n");
3553 fprintf (fp
, " -h,--help Display this message.\n");
3554 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3555 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3556 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3561 /* Option specification for getopt_long. */
3562 static struct option long_options
[] =
3564 { "help", no_argument
, NULL
, 'h' },
3565 { "strict", no_argument
, NULL
, 's' },
3566 { "verbose", no_argument
, NULL
, 'v' },
3567 { NULL
, no_argument
, NULL
, 0 },
3570 /* Main entry for a demangling filter executable. It will demangle
3571 its command line arguments, if any. If none are provided, it will
3572 filter stdin to stdout, replacing any recognized mangled C++ names
3573 with their demangled equivalents. */
3584 /* Use the program name of this program, as invoked. */
3585 program_name
= argv
[0];
3587 /* Parse options. */
3590 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3593 case '?': /* Unrecognized option. */
3594 print_usage (stderr
, 1);
3598 print_usage (stdout
, 0);
3610 while (opt_char
!= -1);
3613 /* No command line arguments were provided. Filter stdin. */
3615 dyn_string_t mangled
= dyn_string_new (3);
3616 dyn_string_t demangled
= dyn_string_new (0);
3619 /* Read all of input. */
3620 while (!feof (stdin
))
3622 char c
= getchar ();
3624 /* The first character of a mangled name is an underscore. */
3629 /* It's not a mangled name. Print the character and go
3636 /* The second character of a mangled name is a capital `Z'. */
3641 /* It's not a mangled name. Print the previous
3642 underscore, the `Z', and go on. */
3648 /* Start keeping track of the candidate mangled name. */
3649 dyn_string_append_char (mangled
, '_');
3650 dyn_string_append_char (mangled
, 'Z');
3652 /* Pile characters into mangled until we hit one that can't
3653 occur in a mangled name. */
3655 while (!feof (stdin
) && is_mangled_char (c
))
3657 dyn_string_append_char (mangled
, c
);
3663 /* Attempt to demangle the name. */
3664 status
= cp_demangle (dyn_string_buf (mangled
), demangled
);
3666 /* If the demangling succeeded, great! Print out the
3667 demangled version. */
3668 if (STATUS_NO_ERROR (status
))
3669 fputs (dyn_string_buf (demangled
), stdout
);
3670 /* Abort on allocation failures. */
3671 else if (status
== STATUS_ALLOCATION_FAILED
)
3673 fprintf (stderr
, "Memory allocation failed.\n");
3676 /* Otherwise, it might not have been a mangled name. Just
3677 print out the original text. */
3679 fputs (dyn_string_buf (mangled
), stdout
);
3681 /* If we haven't hit EOF yet, we've read one character that
3682 can't occur in a mangled name, so print it out. */
3686 /* Clear the candidate mangled name, to start afresh next
3687 time we hit a `_Z'. */
3688 dyn_string_clear (mangled
);
3691 dyn_string_delete (mangled
);
3692 dyn_string_delete (demangled
);
3695 /* Demangle command line arguments. */
3697 dyn_string_t result
= dyn_string_new (0);
3699 /* Loop over command line arguments. */
3700 for (i
= optind
; i
< argc
; ++i
)
3702 /* Attempt to demangle. */
3703 status
= cp_demangle (argv
[i
], result
);
3705 /* If it worked, print the demangled name. */
3706 if (STATUS_NO_ERROR (status
))
3707 printf ("%s\n", dyn_string_buf (result
));
3708 /* Abort on allocaiton failures. */
3709 else if (status
== STATUS_ALLOCATION_FAILED
)
3711 fprintf (stderr
, "Memory allocaiton failed.\n");
3714 /* If not, print the error message to stderr instead. */
3716 fprintf (stderr
, "%s\n", status
);
3718 dyn_string_delete (result
);
3724 #endif /* STANDALONE_DEMANGLER */