1 /* Demangler for IA64 / g++ V3 ABI.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This file is part of GNU CC.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 /* This file implements demangling of C++ names mangled according to
23 the IA64 / g++ V3 ABI. Use the cp_demangle function to
24 demangle a mangled name, or compile with the preprocessor macro
25 STANDALONE_DEMANGLER defined to create a demangling filter
26 executable (functionally similar to c++filt, but includes this
33 #include <sys/types.h>
46 #include "libiberty.h"
47 #include "dyn-string.h"
50 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
51 and other debugging output, will be generated. */
52 #ifdef CP_DEMANGLE_DEBUG
53 #define DEMANGLE_TRACE(PRODUCTION, DM) \
54 fprintf (stderr, " -> %-24s at position %3d\n", \
55 (PRODUCTION), current_position (DM));
57 #define DEMANGLE_TRACE(PRODUCTION, DM)
60 /* Don't include <ctype.h>, to prevent additional unresolved symbols
61 from being dragged into the C++ runtime library. */
62 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
63 #define IS_ALPHA(CHAR) \
64 (((CHAR) >= 'a' && (CHAR) <= 'z') \
65 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
67 /* The prefix prepended by GCC to an identifier represnting the
68 anonymous namespace. */
69 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
71 /* If flag_verbose is zero, some simplifications will be made to the
72 output to make it easier to read and supress details that are
73 generally not of interest to the average C++ programmer.
74 Otherwise, the demangled representation will attempt to convey as
75 much information as the mangled form. */
76 static int flag_verbose
;
78 /* If flag_strict is non-zero, demangle strictly according to the
79 specification -- don't demangle special g++ manglings. */
80 static int flag_strict
;
82 /* String_list_t is an extended form of dyn_string_t which provides a
83 link field and a caret position for additions to the string. A
84 string_list_t may safely be cast to and used as a dyn_string_t. */
86 struct string_list_def
88 /* The dyn_string; must be first. */
89 struct dyn_string string
;
91 /* The position at which additional text is added to this string
92 (using the result_add* macros). This value is an offset from the
93 end of the string, not the beginning (and should be
97 /* The next string in the list. */
98 struct string_list_def
*next
;
101 typedef struct string_list_def
*string_list_t
;
103 /* Data structure representing a potential substitution. */
105 struct substitution_def
107 /* The demangled text of the substitution. */
110 /* Whether this substitution represents a template item. */
114 /* Data structure representing a template argument list. */
116 struct template_arg_list_def
118 /* The next (lower) template argument list in the stack of currently
119 active template arguments. */
120 struct template_arg_list_def
*next
;
122 /* The first element in the list of template arguments in
123 left-to-right order. */
124 string_list_t first_argument
;
126 /* The last element in the arguments lists. */
127 string_list_t last_argument
;
130 typedef struct template_arg_list_def
*template_arg_list_t
;
132 /* Data structure to maintain the state of the current demangling. */
134 struct demangling_def
136 /* The full mangled name being mangled. */
139 /* Pointer into name at the current position. */
142 /* Stack for strings containing demangled result generated so far.
143 Text is emitted to the topmost (first) string. */
144 string_list_t result
;
146 /* The number of presently available substitutions. */
147 int num_substitutions
;
149 /* The allocated size of the substitutions array. */
150 int substitutions_allocated
;
152 /* An array of available substitutions. The number of elements in
153 the array is given by num_substitions, and the allocated array
154 size in substitutions_size.
156 The most recent substition is at the end, so
158 - `S_' corresponds to substititutions[num_substitutions - 1]
159 - `S0_' corresponds to substititutions[num_substitutions - 2]
162 struct substitution_def
*substitutions
;
164 /* The stack of template argument lists. */
165 template_arg_list_t template_arg_lists
;
167 /* The most recently demangled source-name. */
168 dyn_string_t last_source_name
;
171 typedef struct demangling_def
*demangling_t
;
173 /* This type is the standard return code from most functions. Values
174 other than STATUS_OK contain descriptive messages. */
175 typedef const char *status_t
;
177 /* Special values that can be used as a status_t. */
178 #define STATUS_OK NULL
179 #define STATUS_ERROR "Error."
180 #define STATUS_UNIMPLEMENTED "Unimplemented."
181 #define STATUS_INTERNAL_ERROR "Internal error."
183 /* This status code indicates a failure in malloc or realloc. */
184 static const char *const status_allocation_failed
= "Allocation failed.";
185 #define STATUS_ALLOCATION_FAILED status_allocation_failed
187 /* Non-zero if STATUS indicates that no error has occurred. */
188 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
190 /* Evaluate EXPR, which must produce a status_t. If the status code
191 indicates an error, return from the current function with that
193 #define RETURN_IF_ERROR(EXPR) \
197 if (!STATUS_NO_ERROR (s)) \
202 static status_t int_to_dyn_string
203 PARAMS ((int, dyn_string_t
));
204 static string_list_t string_list_new
206 static void string_list_delete
207 PARAMS ((string_list_t
));
208 static status_t result_add_separated_char
209 PARAMS ((demangling_t
, int));
210 static status_t result_push
211 PARAMS ((demangling_t
));
212 static string_list_t result_pop
213 PARAMS ((demangling_t
));
214 static int substitution_start
215 PARAMS ((demangling_t
));
216 static status_t substitution_add
217 PARAMS ((demangling_t
, int, int));
218 static dyn_string_t substitution_get
219 PARAMS ((demangling_t
, int, int *));
220 #ifdef CP_DEMANGLE_DEBUG
221 static void substitutions_print
222 PARAMS ((demangling_t
, FILE *));
224 static template_arg_list_t template_arg_list_new
226 static void template_arg_list_delete
227 PARAMS ((template_arg_list_t
));
228 static void template_arg_list_add_arg
229 PARAMS ((template_arg_list_t
, string_list_t
));
230 static string_list_t template_arg_list_get_arg
231 PARAMS ((template_arg_list_t
, int));
232 static void push_template_arg_list
233 PARAMS ((demangling_t
, template_arg_list_t
));
234 static void pop_to_template_arg_list
235 PARAMS ((demangling_t
, template_arg_list_t
));
236 #ifdef CP_DEMANGLE_DEBUG
237 static void template_arg_list_print
238 PARAMS ((template_arg_list_t
, FILE *));
240 static template_arg_list_t current_template_arg_list
241 PARAMS ((demangling_t
));
242 static demangling_t demangling_new
243 PARAMS ((const char *));
244 static void demangling_delete
245 PARAMS ((demangling_t
));
247 /* The last character of DS. Warning: DS is evaluated twice. */
248 #define dyn_string_last_char(DS) \
249 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
251 /* Append a space character (` ') to DS if it does not already end
252 with one. Evaluates to 1 on success, or 0 on allocation failure. */
253 #define dyn_string_append_space(DS) \
254 ((dyn_string_length (DS) > 0 \
255 && dyn_string_last_char (DS) != ' ') \
256 ? dyn_string_append_char ((DS), ' ') \
259 /* Returns the index of the current position in the mangled name. */
260 #define current_position(DM) ((DM)->next - (DM)->name)
262 /* Returns the character at the current position of the mangled name. */
263 #define peek_char(DM) (*((DM)->next))
265 /* Returns the character one past the current position of the mangled
267 #define peek_char_next(DM) \
268 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
270 /* Returns the character at the current position, and advances the
271 current position to the next character. */
272 #define next_char(DM) (*((DM)->next)++)
274 /* Returns non-zero if the current position is the end of the mangled
275 name, i.e. one past the last character. */
276 #define end_of_name_p(DM) (peek_char (DM) == '\0')
278 /* Advances the current position by one character. */
279 #define advance_char(DM) (++(DM)->next)
281 /* Returns the string containing the current demangled result. */
282 #define result_string(DM) (&(DM)->result->string)
284 /* Returns the position at which new text is inserted into the
286 #define result_caret_pos(DM) \
287 (result_length (DM) + \
288 ((string_list_t) result_string (DM))->caret_position)
290 /* Adds a dyn_string_t to the demangled result. */
291 #define result_add_string(DM, STRING) \
292 (dyn_string_insert (&(DM)->result->string, \
293 result_caret_pos (DM), (STRING)) \
294 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
296 /* Adds NUL-terminated string CSTR to the demangled result. */
297 #define result_add(DM, CSTR) \
298 (dyn_string_insert_cstr (&(DM)->result->string, \
299 result_caret_pos (DM), (CSTR)) \
300 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
302 /* Adds character CHAR to the demangled result. */
303 #define result_add_char(DM, CHAR) \
304 (dyn_string_insert_char (&(DM)->result->string, \
305 result_caret_pos (DM), (CHAR)) \
306 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
308 /* Inserts a dyn_string_t to the demangled result at position POS. */
309 #define result_insert_string(DM, POS, STRING) \
310 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
311 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
313 /* Inserts NUL-terminated string CSTR to the demangled result at
315 #define result_insert(DM, POS, CSTR) \
316 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
317 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
319 /* Inserts character CHAR to the demangled result at position POS. */
320 #define result_insert_char(DM, POS, CHAR) \
321 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
322 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
324 /* The length of the current demangled result. */
325 #define result_length(DM) \
326 dyn_string_length (&(DM)->result->string)
328 /* Appends a (less-than, greater-than) character to the result in DM
329 to (open, close) a template argument or parameter list. Appends a
330 space first if necessary to prevent spurious elision of angle
331 brackets with the previous character. */
332 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
333 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
335 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
336 success. On failure, deletes DS and returns an error code. */
339 int_to_dyn_string (value
, ds
)
346 /* Handle zero up front. */
349 if (!dyn_string_append_char (ds
, '0'))
350 return STATUS_ALLOCATION_FAILED
;
354 /* For negative numbers, emit a minus sign. */
357 if (!dyn_string_append_char (ds
, '-'))
358 return STATUS_ALLOCATION_FAILED
;
362 /* Find the power of 10 of the first digit. */
370 /* Write the digits. */
373 int digit
= value
/ mask
;
375 if (!dyn_string_append_char (ds
, '0' + digit
))
376 return STATUS_ALLOCATION_FAILED
;
378 value
-= digit
* mask
;
385 /* Creates a new string list node. The contents of the string are
386 empty, but the initial buffer allocation is LENGTH. The string
387 list node should be deleted with string_list_delete. Returns NULL
388 if allocation fails. */
391 string_list_new (length
)
394 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
395 s
->caret_position
= 0;
398 if (!dyn_string_init ((dyn_string_t
) s
, length
))
403 /* Deletes the entire string list starting at NODE. */
406 string_list_delete (node
)
411 string_list_t next
= node
->next
;
417 /* Appends CHARACTER to the demangled result. If the current trailing
418 character of the result is CHARACTER, a space is inserted first. */
421 result_add_separated_char (dm
, character
)
425 char *result
= dyn_string_buf (result_string (dm
));
426 int caret_pos
= result_caret_pos (dm
);
428 /* Add a space if the last character is already the character we
430 if (caret_pos
> 0 && result
[caret_pos
- 1] == character
)
431 RETURN_IF_ERROR (result_add_char (dm
, ' '));
432 /* Add the character. */
433 RETURN_IF_ERROR (result_add_char (dm
, character
));
438 /* Allocates and pushes a new string onto the demangled results stack
439 for DM. Subsequent demangling with DM will emit to the new string.
440 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
441 allocation failure. */
447 string_list_t new_string
= string_list_new (0);
448 if (new_string
== NULL
)
449 /* Allocation failed. */
450 return STATUS_ALLOCATION_FAILED
;
452 /* Link the new string to the front of the list of result strings. */
453 new_string
->next
= (string_list_t
) dm
->result
;
454 dm
->result
= new_string
;
458 /* Removes and returns the topmost element on the demangled results
459 stack for DM. The caller assumes ownership for the returned
466 string_list_t top
= dm
->result
;
467 dm
->result
= top
->next
;
471 /* Returns the current value of the caret for the result string. The
472 value is an offet from the end of the result string. */
475 result_get_caret (dm
)
478 return ((string_list_t
) result_string (dm
))->caret_position
;
481 /* Sets the value of the caret for the result string, counted as an
482 offet from the end of the result string. */
485 result_set_caret (dm
, position
)
489 ((string_list_t
) result_string (dm
))->caret_position
= position
;
492 /* Shifts the position of the next addition to the result by
493 POSITION_OFFSET. A negative value shifts the caret to the left. */
496 result_shift_caret (dm
, position_offset
)
500 ((string_list_t
) result_string (dm
))->caret_position
+= position_offset
;
503 /* Returns non-zero if the character that comes right before the place
504 where text will be added to the result is a space. In this case,
505 the caller should supress adding another space. */
508 result_previous_char_is_space (dm
)
511 char *result
= dyn_string_buf (result_string (dm
));
512 int pos
= result_caret_pos (dm
);
513 return pos
> 0 && result
[pos
- 1] == ' ';
516 /* Returns the start position of a fragment of the demangled result
517 that will be a substitution candidate. Should be called at the
518 start of productions that can add substitutions. */
521 substitution_start (dm
)
524 return result_caret_pos (dm
);
527 /* Adds the suffix of the current demangled result of DM starting at
528 START_POSITION as a potential substitution. If TEMPLATE_P is
529 non-zero, this potential substitution is a template-id. */
532 substitution_add (dm
, start_position
, template_p
)
537 dyn_string_t result
= result_string (dm
);
538 dyn_string_t substitution
= dyn_string_new (0);
541 if (substitution
== NULL
)
542 return STATUS_ALLOCATION_FAILED
;
544 /* Extract the substring of the current demangling result that
545 represents the subsitution candidate. */
546 if (!dyn_string_substring (substitution
,
547 result
, start_position
, result_caret_pos (dm
)))
549 dyn_string_delete (substitution
);
550 return STATUS_ALLOCATION_FAILED
;
553 /* If there's no room for the new entry, grow the array. */
554 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
556 size_t new_array_size
;
557 if (dm
->substitutions_allocated
> 0)
558 dm
->substitutions_allocated
*= 2;
560 dm
->substitutions_allocated
= 2;
562 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
564 dm
->substitutions
= (struct substitution_def
*)
565 realloc (dm
->substitutions
, new_array_size
);
566 if (dm
->substitutions
== NULL
)
567 /* Realloc failed. */
569 dyn_string_delete (substitution
);
570 return STATUS_ALLOCATION_FAILED
;
574 /* Add the substitution to the array. */
575 i
= dm
->num_substitutions
++;
576 dm
->substitutions
[i
].text
= substitution
;
577 dm
->substitutions
[i
].template_p
= template_p
;
579 #ifdef CP_DEMANGLE_DEBUG
580 substitutions_print (dm
, stderr
);
586 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
587 non-zero if the substitution is a template-id, zero otherwise.
588 N is numbered from zero. DM retains ownership of the returned
589 string. If N is negative, or equal to or greater than the current
590 number of substitution candidates, returns NULL. */
593 substitution_get (dm
, n
, template_p
)
598 struct substitution_def
*sub
;
600 /* Make sure N is in the valid range. */
601 if (n
< 0 || n
>= dm
->num_substitutions
)
604 sub
= &(dm
->substitutions
[n
]);
605 *template_p
= sub
->template_p
;
609 #ifdef CP_DEMANGLE_DEBUG
610 /* Debugging routine to print the current substitutions to FP. */
613 substitutions_print (dm
, fp
)
618 int num
= dm
->num_substitutions
;
620 fprintf (fp
, "SUBSTITUTIONS:\n");
621 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
624 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
627 fprintf (fp
, " S_ ");
629 fprintf (fp
, " S%d_", seq_id
);
630 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
634 #endif /* CP_DEMANGLE_DEBUG */
636 /* Creates a new template argument list. Returns NULL if allocation
639 static template_arg_list_t
640 template_arg_list_new ()
642 template_arg_list_t new_list
=
643 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
644 if (new_list
== NULL
)
646 /* Initialize the new list to have no arguments. */
647 new_list
->first_argument
= NULL
;
648 new_list
->last_argument
= NULL
;
649 /* Return the new list. */
653 /* Deletes a template argument list and the template arguments it
657 template_arg_list_delete (list
)
658 template_arg_list_t list
;
660 /* If there are any arguments on LIST, delete them. */
661 if (list
->first_argument
!= NULL
)
662 string_list_delete (list
->first_argument
);
667 /* Adds ARG to the template argument list ARG_LIST. */
670 template_arg_list_add_arg (arg_list
, arg
)
671 template_arg_list_t arg_list
;
674 if (arg_list
->first_argument
== NULL
)
675 /* If there were no arguments before, ARG is the first one. */
676 arg_list
->first_argument
= arg
;
678 /* Make ARG the last argument on the list. */
679 arg_list
->last_argument
->next
= arg
;
680 /* Make ARG the last on the list. */
681 arg_list
->last_argument
= arg
;
685 /* Returns the template arugment at position INDEX in template
686 argument list ARG_LIST. */
689 template_arg_list_get_arg (arg_list
, index
)
690 template_arg_list_t arg_list
;
693 string_list_t arg
= arg_list
->first_argument
;
694 /* Scan down the list of arguments to find the one at position
700 /* Ran out of arguments before INDEX hit zero. That's an
704 /* Return the argument at position INDEX. */
708 /* Pushes ARG_LIST onto the top of the template argument list stack. */
711 push_template_arg_list (dm
, arg_list
)
713 template_arg_list_t arg_list
;
715 arg_list
->next
= dm
->template_arg_lists
;
716 dm
->template_arg_lists
= arg_list
;
717 #ifdef CP_DEMANGLE_DEBUG
718 fprintf (stderr
, " ** pushing template arg list\n");
719 template_arg_list_print (arg_list
, stderr
);
723 /* Pops and deletes elements on the template argument list stack until
724 arg_list is the topmost element. If arg_list is NULL, all elements
725 are popped and deleted. */
728 pop_to_template_arg_list (dm
, arg_list
)
730 template_arg_list_t arg_list
;
732 while (dm
->template_arg_lists
!= arg_list
)
734 template_arg_list_t top
= dm
->template_arg_lists
;
735 /* Disconnect the topmost element from the list. */
736 dm
->template_arg_lists
= top
->next
;
737 /* Delete the popped element. */
738 template_arg_list_delete (top
);
739 #ifdef CP_DEMANGLE_DEBUG
740 fprintf (stderr
, " ** removing template arg list\n");
745 #ifdef CP_DEMANGLE_DEBUG
747 /* Prints the contents of ARG_LIST to FP. */
750 template_arg_list_print (arg_list
, fp
)
751 template_arg_list_t arg_list
;
757 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
758 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
761 fprintf (fp
, " T_ : ");
763 fprintf (fp
, " T%d_ : ", index
);
765 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
769 #endif /* CP_DEMANGLE_DEBUG */
771 /* Returns the topmost element on the stack of template argument
772 lists. If there is no list of template arguments, returns NULL. */
774 static template_arg_list_t
775 current_template_arg_list (dm
)
778 return dm
->template_arg_lists
;
781 /* Allocates a demangling_t object for demangling mangled NAME. A new
782 result must be pushed before the returned object can be used.
783 Returns NULL if allocation fails. */
786 demangling_new (name
)
790 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
797 dm
->num_substitutions
= 0;
798 dm
->substitutions_allocated
= 10;
799 dm
->template_arg_lists
= NULL
;
800 dm
->last_source_name
= dyn_string_new (0);
801 if (dm
->last_source_name
== NULL
)
803 dm
->substitutions
= (struct substitution_def
*)
804 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
805 if (dm
->substitutions
== NULL
)
807 dyn_string_delete (dm
->last_source_name
);
814 /* Deallocates a demangling_t object and all memory associated with
818 demangling_delete (dm
)
822 template_arg_list_t arg_list
= dm
->template_arg_lists
;
824 /* Delete the stack of template argument lists. */
825 while (arg_list
!= NULL
)
827 template_arg_list_t next
= arg_list
->next
;
828 template_arg_list_delete (arg_list
);
831 /* Delete the list of substitutions. */
832 for (i
= dm
->num_substitutions
; --i
>= 0; )
833 dyn_string_delete (dm
->substitutions
[i
].text
);
834 free (dm
->substitutions
);
835 /* Delete the demangled result. */
836 string_list_delete (dm
->result
);
837 /* Delete the stored identifier name. */
838 dyn_string_delete (dm
->last_source_name
);
839 /* Delete the context object itself. */
843 /* These functions demangle an alternative of the corresponding
844 production in the mangling spec. The first argument of each is a
845 demangling context structure for the current demangling
846 operation. Most emit demangled text directly to the topmost result
847 string on the result string stack in the demangling context
850 static status_t demangle_char
851 PARAMS ((demangling_t
, int));
852 static status_t demangle_mangled_name
853 PARAMS ((demangling_t
));
854 static status_t demangle_encoding
855 PARAMS ((demangling_t
));
856 static status_t demangle_name
857 PARAMS ((demangling_t
, int *));
858 static status_t demangle_nested_name
859 PARAMS ((demangling_t
, int *));
860 static status_t demangle_prefix
861 PARAMS ((demangling_t
, int *));
862 static status_t demangle_unqualified_name
863 PARAMS ((demangling_t
, int *));
864 static status_t demangle_source_name
865 PARAMS ((demangling_t
));
866 static status_t demangle_number
867 PARAMS ((demangling_t
, int *, int, int));
868 static status_t demangle_number_literally
869 PARAMS ((demangling_t
, dyn_string_t
, int, int));
870 static status_t demangle_identifier
871 PARAMS ((demangling_t
, int, dyn_string_t
));
872 static status_t demangle_operator_name
873 PARAMS ((demangling_t
, int, int *));
874 static status_t demangle_nv_offset
875 PARAMS ((demangling_t
));
876 static status_t demangle_v_offset
877 PARAMS ((demangling_t
));
878 static status_t demangle_call_offset
879 PARAMS ((demangling_t
));
880 static status_t demangle_special_name
881 PARAMS ((demangling_t
));
882 static status_t demangle_ctor_dtor_name
883 PARAMS ((demangling_t
));
884 static status_t demangle_type_ptr
885 PARAMS ((demangling_t
, int *, int));
886 static status_t demangle_type
887 PARAMS ((demangling_t
));
888 static status_t demangle_CV_qualifiers
889 PARAMS ((demangling_t
, dyn_string_t
));
890 static status_t demangle_builtin_type
891 PARAMS ((demangling_t
));
892 static status_t demangle_function_type
893 PARAMS ((demangling_t
, int *));
894 static status_t demangle_bare_function_type
895 PARAMS ((demangling_t
, int *));
896 static status_t demangle_class_enum_type
897 PARAMS ((demangling_t
, int *));
898 static status_t demangle_array_type
899 PARAMS ((demangling_t
, int *));
900 static status_t demangle_template_param
901 PARAMS ((demangling_t
));
902 static status_t demangle_template_args
903 PARAMS ((demangling_t
));
904 static status_t demangle_literal
905 PARAMS ((demangling_t
));
906 static status_t demangle_template_arg
907 PARAMS ((demangling_t
));
908 static status_t demangle_expression
909 PARAMS ((demangling_t
));
910 static status_t demangle_scope_expression
911 PARAMS ((demangling_t
));
912 static status_t demangle_expr_primary
913 PARAMS ((demangling_t
));
914 static status_t demangle_substitution
915 PARAMS ((demangling_t
, int *));
916 static status_t demangle_local_name
917 PARAMS ((demangling_t
));
918 static status_t demangle_discriminator
919 PARAMS ((demangling_t
, int));
920 static status_t cp_demangle
921 PARAMS ((const char *, dyn_string_t
));
923 static status_t cp_demangle_type
924 PARAMS ((const char*, dyn_string_t
));
927 /* When passed to demangle_bare_function_type, indicates that the
928 function's return type is not encoded before its parameter types. */
929 #define BFT_NO_RETURN_TYPE NULL
931 /* Check that the next character is C. If so, consume it. If not,
935 demangle_char (dm
, c
)
939 static char *error_message
= NULL
;
941 if (peek_char (dm
) == c
)
948 if (error_message
== NULL
)
949 error_message
= strdup ("Expected ?");
950 error_message
[9] = c
;
951 return error_message
;
955 /* Demangles and emits a <mangled-name>.
957 <mangled-name> ::= _Z <encoding> */
960 demangle_mangled_name (dm
)
963 DEMANGLE_TRACE ("mangled-name", dm
);
964 RETURN_IF_ERROR (demangle_char (dm
, '_'));
965 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
966 RETURN_IF_ERROR (demangle_encoding (dm
));
970 /* Demangles and emits an <encoding>.
972 <encoding> ::= <function name> <bare-function-type>
974 ::= <special-name> */
977 demangle_encoding (dm
)
980 int encode_return_type
;
982 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
983 char peek
= peek_char (dm
);
985 DEMANGLE_TRACE ("encoding", dm
);
987 /* Remember where the name starts. If it turns out to be a template
988 function, we'll have to insert the return type here. */
989 start_position
= result_caret_pos (dm
);
991 if (peek
== 'G' || peek
== 'T')
992 RETURN_IF_ERROR (demangle_special_name (dm
));
995 /* Now demangle the name. */
996 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
998 /* If there's anything left, the name was a function name, with
999 maybe its return type, and its parameter types, following. */
1000 if (!end_of_name_p (dm
)
1001 && peek_char (dm
) != 'E')
1003 if (encode_return_type
)
1004 /* Template functions have their return type encoded. The
1005 return type should be inserted at start_position. */
1007 (demangle_bare_function_type (dm
, &start_position
));
1009 /* Non-template functions don't have their return type
1012 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
1016 /* Pop off template argument lists that were built during the
1017 mangling of this name, to restore the old template context. */
1018 pop_to_template_arg_list (dm
, old_arg_list
);
1023 /* Demangles and emits a <name>.
1025 <name> ::= <unscoped-name>
1026 ::= <unscoped-template-name> <template-args>
1030 <unscoped-name> ::= <unqualified-name>
1031 ::= St <unqualified-name> # ::std::
1033 <unscoped-template-name>
1035 ::= <substitution> */
1038 demangle_name (dm
, encode_return_type
)
1040 int *encode_return_type
;
1042 int start
= substitution_start (dm
);
1043 char peek
= peek_char (dm
);
1044 int is_std_substitution
= 0;
1046 /* Generally, the return type is encoded if the function is a
1047 template-id, and suppressed otherwise. There are a few cases,
1048 though, in which the return type is not encoded even for a
1049 templated function. In these cases, this flag is set. */
1050 int suppress_return_type
= 0;
1052 DEMANGLE_TRACE ("name", dm
);
1057 /* This is a <nested-name>. */
1058 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1062 RETURN_IF_ERROR (demangle_local_name (dm
));
1063 *encode_return_type
= 0;
1067 /* The `St' substitution allows a name nested in std:: to appear
1068 without being enclosed in a nested name. */
1069 if (peek_char_next (dm
) == 't')
1071 (void) next_char (dm
);
1072 (void) next_char (dm
);
1073 RETURN_IF_ERROR (result_add (dm
, "std::"));
1075 (demangle_unqualified_name (dm
, &suppress_return_type
));
1076 is_std_substitution
= 1;
1079 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1080 /* Check if a template argument list immediately follows.
1081 If so, then we just demangled an <unqualified-template-name>. */
1082 if (peek_char (dm
) == 'I')
1084 /* A template name of the form std::<unqualified-name> is a
1085 substitution candidate. */
1086 if (is_std_substitution
)
1087 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1088 /* Demangle the <template-args> here. */
1089 RETURN_IF_ERROR (demangle_template_args (dm
));
1090 *encode_return_type
= !suppress_return_type
;
1093 *encode_return_type
= 0;
1098 /* This is an <unscoped-name> or <unscoped-template-name>. */
1099 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1101 /* If the <unqualified-name> is followed by template args, this
1102 is an <unscoped-template-name>. */
1103 if (peek_char (dm
) == 'I')
1105 /* Add a substitution for the unqualified template name. */
1106 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1108 RETURN_IF_ERROR (demangle_template_args (dm
));
1109 *encode_return_type
= !suppress_return_type
;
1112 *encode_return_type
= 0;
1120 /* Demangles and emits a <nested-name>.
1122 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1125 demangle_nested_name (dm
, encode_return_type
)
1127 int *encode_return_type
;
1131 DEMANGLE_TRACE ("nested-name", dm
);
1133 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1135 peek
= peek_char (dm
);
1136 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1138 dyn_string_t cv_qualifiers
;
1141 /* Snarf up CV qualifiers. */
1142 cv_qualifiers
= dyn_string_new (24);
1143 if (cv_qualifiers
== NULL
)
1144 return STATUS_ALLOCATION_FAILED
;
1145 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1147 /* Emit them, preceded by a space. */
1148 status
= result_add_char (dm
, ' ');
1149 if (STATUS_NO_ERROR (status
))
1150 status
= result_add_string (dm
, cv_qualifiers
);
1151 /* The CV qualifiers that occur in a <nested-name> will be
1152 qualifiers for member functions. These are placed at the end
1153 of the function. Therefore, shift the caret to the left by
1154 the length of the qualifiers, so other text is inserted
1155 before them and they stay at the end. */
1156 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
) - 1);
1158 dyn_string_delete (cv_qualifiers
);
1159 RETURN_IF_ERROR (status
);
1162 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1163 /* No need to demangle the final <unqualified-name>; demangle_prefix
1165 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1170 /* Demangles and emits a <prefix>.
1172 <prefix> ::= <prefix> <unqualified-name>
1173 ::= <template-prefix> <template-args>
1177 <template-prefix> ::= <prefix>
1178 ::= <substitution> */
1181 demangle_prefix (dm
, encode_return_type
)
1183 int *encode_return_type
;
1185 int start
= substitution_start (dm
);
1188 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1189 After <template-args>, it is set to non-zero; after everything
1190 else it is set to zero. */
1192 /* Generally, the return type is encoded if the function is a
1193 template-id, and suppressed otherwise. There are a few cases,
1194 though, in which the return type is not encoded even for a
1195 templated function. In these cases, this flag is set. */
1196 int suppress_return_type
= 0;
1198 DEMANGLE_TRACE ("prefix", dm
);
1204 if (end_of_name_p (dm
))
1205 return "Unexpected end of name in <compound-name>.";
1207 peek
= peek_char (dm
);
1209 /* We'll initialize suppress_return_type to false, and set it to true
1210 if we end up demangling a constructor name. However, make
1211 sure we're not actually about to demangle template arguments
1212 -- if so, this is the <template-args> following a
1213 <template-prefix>, so we'll want the previous flag value
1216 suppress_return_type
= 0;
1218 if (IS_DIGIT ((unsigned char) peek
)
1219 || (peek
>= 'a' && peek
<= 'z')
1220 || peek
== 'C' || peek
== 'D'
1223 /* We have another level of scope qualification. */
1225 RETURN_IF_ERROR (result_add (dm
, "::"));
1230 /* The substitution determines whether this is a
1232 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1235 /* It's just a name. */
1237 (demangle_unqualified_name (dm
, &suppress_return_type
));
1238 *encode_return_type
= 0;
1241 else if (peek
== 'Z')
1242 RETURN_IF_ERROR (demangle_local_name (dm
));
1243 else if (peek
== 'I')
1245 RETURN_IF_ERROR (demangle_template_args (dm
));
1247 /* Now we want to indicate to the caller that we've
1248 demangled template arguments, thus the prefix was a
1249 <template-prefix>. That's so that the caller knows to
1250 demangle the function's return type, if this turns out to
1251 be a function name. But, if it's a member template
1252 constructor or a templated conversion operator, report it
1253 as untemplated. Those never get encoded return types. */
1254 *encode_return_type
= !suppress_return_type
;
1256 else if (peek
== 'E')
1260 return "Unexpected character in <compound-name>.";
1263 && peek_char (dm
) != 'E')
1264 /* Add a new substitution for the prefix thus far. */
1265 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1269 /* Demangles and emits an <unqualified-name>. If this
1270 <unqualified-name> is for a special function type that should never
1271 have its return type encoded (particularly, a constructor or
1272 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1275 <unqualified-name> ::= <operator-name>
1277 ::= <source-name> */
1280 demangle_unqualified_name (dm
, suppress_return_type
)
1282 int *suppress_return_type
;
1284 char peek
= peek_char (dm
);
1286 DEMANGLE_TRACE ("unqualified-name", dm
);
1288 /* By default, don't force suppression of the return type (though
1289 non-template functions still don't get a return type encoded). */
1290 *suppress_return_type
= 0;
1292 if (IS_DIGIT ((unsigned char) peek
))
1293 RETURN_IF_ERROR (demangle_source_name (dm
));
1294 else if (peek
>= 'a' && peek
<= 'z')
1298 /* Conversion operators never have a return type encoded. */
1299 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1300 *suppress_return_type
= 1;
1302 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1304 else if (peek
== 'C' || peek
== 'D')
1306 /* Constructors never have a return type encoded. */
1308 *suppress_return_type
= 1;
1310 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1313 return "Unexpected character in <unqualified-name>.";
1318 /* Demangles and emits <source-name>.
1320 <source-name> ::= <length number> <identifier> */
1323 demangle_source_name (dm
)
1328 DEMANGLE_TRACE ("source-name", dm
);
1330 /* Decode the length of the identifier. */
1331 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1333 return "Zero length in <source-name>.";
1335 /* Now the identifier itself. It's placed into last_source_name,
1336 where it can be used to build a constructor or destructor name. */
1337 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1338 dm
->last_source_name
));
1341 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
1346 /* Demangles a number, either a <number> or a <positive-number> at the
1347 current position, consuming all consecutive digit characters. Sets
1348 *VALUE to the resulting numberand returns STATUS_OK. The number is
1349 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1350 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1352 <number> ::= [n] <positive-number>
1354 <positive-number> ::= <decimal integer> */
1357 demangle_number (dm
, value
, base
, is_signed
)
1363 dyn_string_t number
= dyn_string_new (10);
1365 DEMANGLE_TRACE ("number", dm
);
1368 return STATUS_ALLOCATION_FAILED
;
1370 demangle_number_literally (dm
, number
, base
, is_signed
);
1371 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1372 dyn_string_delete (number
);
1377 /* Demangles a number at the current position. The digits (and minus
1378 sign, if present) that make up the number are appended to STR.
1379 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1380 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1381 accepted. Does not consume a trailing underscore or other
1382 terminating character. */
1385 demangle_number_literally (dm
, str
, base
, is_signed
)
1391 DEMANGLE_TRACE ("number*", dm
);
1393 if (base
!= 10 && base
!= 36)
1394 return STATUS_INTERNAL_ERROR
;
1396 /* An `n' denotes a negative number. */
1397 if (is_signed
&& peek_char (dm
) == 'n')
1399 /* Skip past the n. */
1401 /* The normal way to write a negative number is with a minus
1403 if (!dyn_string_append_char (str
, '-'))
1404 return STATUS_ALLOCATION_FAILED
;
1407 /* Loop until we hit a non-digit. */
1410 char peek
= peek_char (dm
);
1411 if (IS_DIGIT ((unsigned char) peek
)
1412 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1414 /* Accumulate digits. */
1415 if (!dyn_string_append_char (str
, next_char (dm
)))
1416 return STATUS_ALLOCATION_FAILED
;
1419 /* Not a digit? All done. */
1426 /* Demangles an identifier at the current position of LENGTH
1427 characters and places it in IDENTIFIER. */
1430 demangle_identifier (dm
, length
, identifier
)
1433 dyn_string_t identifier
;
1435 DEMANGLE_TRACE ("identifier", dm
);
1437 dyn_string_clear (identifier
);
1438 if (!dyn_string_resize (identifier
, length
))
1439 return STATUS_ALLOCATION_FAILED
;
1441 while (length
-- > 0)
1443 if (end_of_name_p (dm
))
1444 return "Unexpected end of name in <identifier>.";
1445 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1446 return STATUS_ALLOCATION_FAILED
;
1449 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1450 followed by the source file name and some random characters.
1451 Unless we're in strict mode, decipher these names appropriately. */
1454 char *name
= dyn_string_buf (identifier
);
1455 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1457 /* Compare the first, fixed part. */
1458 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1460 name
+= prefix_length
;
1461 /* The next character might be a period, an underscore, or
1462 dollar sign, depending on the target architecture's
1463 assembler's capabilities. After that comes an `N'. */
1464 if ((*name
== '.' || *name
== '_' || *name
== '$')
1465 && *(name
+ 1) == 'N')
1466 /* This looks like the anonymous namespace identifier.
1467 Replace it with something comprehensible. */
1468 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1475 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1476 the short form is emitted; otherwise the full source form
1477 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1478 operands that the operator takes.
1529 ::= cv <type> # cast
1530 ::= v [0-9] <source-name> # vendor extended operator */
1533 demangle_operator_name (dm
, short_name
, num_args
)
1538 struct operator_code
1540 /* The mangled code for this operator. */
1542 /* The source name of this operator. */
1544 /* The number of arguments this operator takes. */
1548 static const struct operator_code operators
[] =
1559 { "da", " delete[]", 1 },
1561 { "dl", " delete" , 1 },
1569 { "lS", "<<=" , 2 },
1578 { "na", " new[]" , 1 },
1582 { "nw", " new" , 1 },
1588 { "pm", "->*" , 2 },
1594 { "rS", ">>=" , 2 },
1597 { "sz", " sizeof" , 1 }
1600 const int num_operators
=
1601 sizeof (operators
) / sizeof (struct operator_code
);
1603 int c0
= next_char (dm
);
1604 int c1
= next_char (dm
);
1605 const struct operator_code
* p1
= operators
;
1606 const struct operator_code
* p2
= operators
+ num_operators
;
1608 DEMANGLE_TRACE ("operator-name", dm
);
1610 /* Is this a vendor-extended operator? */
1611 if (c0
== 'v' && IS_DIGIT (c1
))
1613 RETURN_IF_ERROR (result_add (dm
, "operator "));
1614 RETURN_IF_ERROR (demangle_source_name (dm
));
1619 /* Is this a conversion operator? */
1620 if (c0
== 'c' && c1
== 'v')
1622 RETURN_IF_ERROR (result_add (dm
, "operator "));
1623 /* Demangle the converted-to type. */
1624 RETURN_IF_ERROR (demangle_type (dm
));
1629 /* Perform a binary search for the operator code. */
1632 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1633 char match0
= p
->code
[0];
1634 char match1
= p
->code
[1];
1636 if (c0
== match0
&& c1
== match1
)
1640 RETURN_IF_ERROR (result_add (dm
, "operator"));
1641 RETURN_IF_ERROR (result_add (dm
, p
->name
));
1642 *num_args
= p
->num_args
;
1648 /* Couldn't find it. */
1649 return "Unknown code in <operator-name>.";
1652 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1659 /* Demangles and omits an <nv-offset>.
1661 <nv-offset> ::= <offset number> # non-virtual base override */
1664 demangle_nv_offset (dm
)
1667 dyn_string_t number
;
1668 status_t status
= STATUS_OK
;
1670 DEMANGLE_TRACE ("h-offset", dm
);
1672 /* Demangle the offset. */
1673 number
= dyn_string_new (4);
1675 return STATUS_ALLOCATION_FAILED
;
1676 demangle_number_literally (dm
, number
, 10, 1);
1678 /* Don't display the offset unless in verbose mode. */
1681 status
= result_add (dm
, " [nv:");
1682 if (STATUS_NO_ERROR (status
))
1683 status
= result_add_string (dm
, number
);
1684 if (STATUS_NO_ERROR (status
))
1685 status
= result_add_char (dm
, ']');
1689 dyn_string_delete (number
);
1690 RETURN_IF_ERROR (status
);
1694 /* Demangles and emits a <v-offset>.
1696 <v-offset> ::= <offset number> _ <virtual offset number>
1697 # virtual base override, with vcall offset */
1700 demangle_v_offset (dm
)
1703 dyn_string_t number
;
1704 status_t status
= STATUS_OK
;
1706 DEMANGLE_TRACE ("v-offset", dm
);
1708 /* Demangle the offset. */
1709 number
= dyn_string_new (4);
1711 return STATUS_ALLOCATION_FAILED
;
1712 demangle_number_literally (dm
, number
, 10, 1);
1714 /* Don't display the offset unless in verbose mode. */
1717 status
= result_add (dm
, " [v:");
1718 if (STATUS_NO_ERROR (status
))
1719 status
= result_add_string (dm
, number
);
1720 if (STATUS_NO_ERROR (status
))
1721 result_add_char (dm
, ',');
1723 dyn_string_delete (number
);
1724 RETURN_IF_ERROR (status
);
1726 /* Demangle the separator. */
1727 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1729 /* Demangle the vcall offset. */
1730 number
= dyn_string_new (4);
1732 return STATUS_ALLOCATION_FAILED
;
1733 demangle_number_literally (dm
, number
, 10, 1);
1735 /* Don't display the vcall offset unless in verbose mode. */
1738 status
= result_add_string (dm
, number
);
1739 if (STATUS_NO_ERROR (status
))
1740 status
= result_add_char (dm
, ']');
1742 dyn_string_delete (number
);
1743 RETURN_IF_ERROR (status
);
1748 /* Demangles and emits a <call-offset>.
1750 <call-offset> ::= h <nv-offset> _
1751 ::= v <v-offset> _ */
1754 demangle_call_offset (dm
)
1757 DEMANGLE_TRACE ("call-offset", dm
);
1759 switch (peek_char (dm
))
1763 /* Demangle the offset. */
1764 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1765 /* Demangle the separator. */
1766 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1771 /* Demangle the offset. */
1772 RETURN_IF_ERROR (demangle_v_offset (dm
));
1773 /* Demangle the separator. */
1774 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1778 return "Unrecognized <call-offset>.";
1784 /* Demangles and emits a <special-name>.
1786 <special-name> ::= GV <object name> # Guard variable
1787 ::= TV <type> # virtual table
1789 ::= TI <type> # typeinfo structure
1790 ::= TS <type> # typeinfo name
1792 Other relevant productions include thunks:
1794 <special-name> ::= T <call-offset> <base encoding>
1795 # base is the nominal target function of thunk
1797 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1798 # base is the nominal target function of thunk
1799 # first call-offset is 'this' adjustment
1800 # second call-offset is result adjustment
1804 <call-offset> ::= h <nv-offset> _
1807 Also demangles the special g++ manglings,
1809 <special-name> ::= TC <type> <offset number> _ <base type>
1810 # construction vtable
1811 ::= TF <type> # typeinfo function (old ABI only)
1812 ::= TJ <type> # java Class structure */
1815 demangle_special_name (dm
)
1818 dyn_string_t number
;
1820 char peek
= peek_char (dm
);
1822 DEMANGLE_TRACE ("special-name", dm
);
1826 /* A guard variable name. Consume the G. */
1828 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1829 RETURN_IF_ERROR (result_add (dm
, "guard variable for "));
1830 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1832 else if (peek
== 'T')
1834 status_t status
= STATUS_OK
;
1836 /* Other C++ implementation miscellania. Consume the T. */
1839 switch (peek_char (dm
))
1842 /* Virtual table. */
1844 RETURN_IF_ERROR (result_add (dm
, "vtable for "));
1845 RETURN_IF_ERROR (demangle_type (dm
));
1849 /* VTT structure. */
1851 RETURN_IF_ERROR (result_add (dm
, "VTT for "));
1852 RETURN_IF_ERROR (demangle_type (dm
));
1856 /* Typeinfo structure. */
1858 RETURN_IF_ERROR (result_add (dm
, "typeinfo for "));
1859 RETURN_IF_ERROR (demangle_type (dm
));
1863 /* Typeinfo function. Used only in old ABI with new mangling. */
1865 RETURN_IF_ERROR (result_add (dm
, "typeinfo fn for "));
1866 RETURN_IF_ERROR (demangle_type (dm
));
1870 /* Character string containing type name, used in typeinfo. */
1872 RETURN_IF_ERROR (result_add (dm
, "typeinfo name for "));
1873 RETURN_IF_ERROR (demangle_type (dm
));
1877 /* The java Class variable corresponding to a C++ class. */
1879 RETURN_IF_ERROR (result_add (dm
, "java Class for "));
1880 RETURN_IF_ERROR (demangle_type (dm
));
1884 /* Non-virtual thunk. */
1886 RETURN_IF_ERROR (result_add (dm
, "non-virtual thunk"));
1887 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1888 /* Demangle the separator. */
1889 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1890 /* Demangle and emit the target name and function type. */
1891 RETURN_IF_ERROR (result_add (dm
, " to "));
1892 RETURN_IF_ERROR (demangle_encoding (dm
));
1896 /* Virtual thunk. */
1898 RETURN_IF_ERROR (result_add (dm
, "virtual thunk"));
1899 RETURN_IF_ERROR (demangle_v_offset (dm
));
1900 /* Demangle the separator. */
1901 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1902 /* Demangle and emit the target function. */
1903 RETURN_IF_ERROR (result_add (dm
, " to "));
1904 RETURN_IF_ERROR (demangle_encoding (dm
));
1908 /* Covariant return thunk. */
1910 RETURN_IF_ERROR (result_add (dm
, "covariant return thunk"));
1911 RETURN_IF_ERROR (demangle_call_offset (dm
));
1912 RETURN_IF_ERROR (demangle_call_offset (dm
));
1913 /* Demangle and emit the target function. */
1914 RETURN_IF_ERROR (result_add (dm
, " to "));
1915 RETURN_IF_ERROR (demangle_encoding (dm
));
1919 /* TC is a special g++ mangling for a construction vtable. */
1922 dyn_string_t derived_type
;
1925 RETURN_IF_ERROR (result_add (dm
, "construction vtable for "));
1927 /* Demangle the derived type off to the side. */
1928 RETURN_IF_ERROR (result_push (dm
));
1929 RETURN_IF_ERROR (demangle_type (dm
));
1930 derived_type
= (dyn_string_t
) result_pop (dm
);
1932 /* Demangle the offset. */
1933 number
= dyn_string_new (4);
1936 dyn_string_delete (derived_type
);
1937 return STATUS_ALLOCATION_FAILED
;
1939 demangle_number_literally (dm
, number
, 10, 1);
1940 /* Demangle the underscore separator. */
1941 status
= demangle_char (dm
, '_');
1943 /* Demangle the base type. */
1944 if (STATUS_NO_ERROR (status
))
1945 status
= demangle_type (dm
);
1947 /* Emit the derived type. */
1948 if (STATUS_NO_ERROR (status
))
1949 status
= result_add (dm
, "-in-");
1950 if (STATUS_NO_ERROR (status
))
1951 status
= result_add_string (dm
, derived_type
);
1952 dyn_string_delete (derived_type
);
1954 /* Don't display the offset unless in verbose mode. */
1957 status
= result_add_char (dm
, ' ');
1958 if (STATUS_NO_ERROR (status
))
1959 result_add_string (dm
, number
);
1961 dyn_string_delete (number
);
1962 RETURN_IF_ERROR (status
);
1965 /* If flag_strict, fall through. */
1968 return "Unrecognized <special-name>.";
1972 return STATUS_ERROR
;
1977 /* Demangles and emits a <ctor-dtor-name>.
1980 ::= C1 # complete object (in-charge) ctor
1981 ::= C2 # base object (not-in-charge) ctor
1982 ::= C3 # complete object (in-charge) allocating ctor
1983 ::= D0 # deleting (in-charge) dtor
1984 ::= D1 # complete object (in-charge) dtor
1985 ::= D2 # base object (not-in-charge) dtor */
1988 demangle_ctor_dtor_name (dm
)
1991 static const char *const ctor_flavors
[] =
1997 static const char *const dtor_flavors
[] =
1999 "in-charge deleting",
2005 char peek
= peek_char (dm
);
2007 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
2011 /* A constructor name. Consume the C. */
2013 if (peek_char (dm
) < '1' || peek_char (dm
) > '3')
2014 return "Unrecognized constructor.";
2015 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2016 /* Print the flavor of the constructor if in verbose mode. */
2017 flavor
= next_char (dm
) - '1';
2020 RETURN_IF_ERROR (result_add (dm
, "["));
2021 RETURN_IF_ERROR (result_add (dm
, ctor_flavors
[flavor
]));
2022 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2025 else if (peek
== 'D')
2027 /* A destructor name. Consume the D. */
2029 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
2030 return "Unrecognized destructor.";
2031 RETURN_IF_ERROR (result_add_char (dm
, '~'));
2032 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2033 /* Print the flavor of the destructor if in verbose mode. */
2034 flavor
= next_char (dm
) - '0';
2037 RETURN_IF_ERROR (result_add (dm
, " ["));
2038 RETURN_IF_ERROR (result_add (dm
, dtor_flavors
[flavor
]));
2039 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2043 return STATUS_ERROR
;
2048 /* Handle pointer, reference, and pointer-to-member cases for
2049 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2050 build a pointer/reference type. We snarf all these, plus the
2051 following <type>, all at once since we need to know whether we have
2052 a pointer to data or pointer to function to construct the right
2053 output syntax. C++'s pointer syntax is hairy.
2055 This function adds substitution candidates for every nested
2056 pointer/reference type it processes, including the outermost, final
2057 type, assuming the substitution starts at SUBSTITUTION_START in the
2058 demangling result. For example, if this function demangles
2059 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2060 `Foo**', in that order.
2062 *INSERT_POS is a quantity used internally, when this function calls
2063 itself recursively, to figure out where to insert pointer
2064 punctuation on the way up. On entry to this function, INSERT_POS
2065 should point to a temporary value, but that value need not be
2070 ::= <pointer-to-member-type>
2072 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2075 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2078 int substitution_start
;
2081 int is_substitution_candidate
= 1;
2083 DEMANGLE_TRACE ("type*", dm
);
2085 /* Scan forward, collecting pointers and references into symbols,
2086 until we hit something else. Then emit the type. */
2087 switch (peek_char (dm
))
2090 /* A pointer. Snarf the `P'. */
2092 /* Demangle the underlying type. */
2093 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2094 substitution_start
));
2095 /* Insert an asterisk where we're told to; it doesn't
2096 necessarily go at the end. */
2097 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2098 /* The next (outermost) pointer or reference character should go
2104 /* A reference. Snarf the `R'. */
2106 /* Demangle the underlying type. */
2107 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2108 substitution_start
));
2109 /* Insert an ampersand where we're told to; it doesn't
2110 necessarily go at the end. */
2111 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2112 /* The next (outermost) pointer or reference character should go
2119 /* A pointer-to-member. */
2120 dyn_string_t class_type
;
2125 /* Capture the type of which this is a pointer-to-member. */
2126 RETURN_IF_ERROR (result_push (dm
));
2127 RETURN_IF_ERROR (demangle_type (dm
));
2128 class_type
= (dyn_string_t
) result_pop (dm
);
2130 if (peek_char (dm
) == 'F')
2131 /* A pointer-to-member function. We want output along the
2132 lines of `void (C::*) (int, int)'. Demangle the function
2133 type, which would in this case give `void () (int, int)'
2134 and set *insert_pos to the spot between the first
2136 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2137 else if (peek_char (dm
) == 'A')
2138 /* A pointer-to-member array variable. We want output that
2139 looks like `int (Klass::*) [10]'. Demangle the array type
2140 as `int () [10]', and set *insert_pos to the spot between
2142 status
= demangle_array_type (dm
, insert_pos
);
2145 /* A pointer-to-member variable. Demangle the type of the
2146 pointed-to member. */
2147 status
= demangle_type (dm
);
2148 /* Make it pretty. */
2149 if (STATUS_NO_ERROR (status
)
2150 && !result_previous_char_is_space (dm
))
2151 status
= result_add_char (dm
, ' ');
2152 /* The pointer-to-member notation (e.g. `C::*') follows the
2154 *insert_pos
= result_caret_pos (dm
);
2157 /* Build the pointer-to-member notation. */
2158 if (STATUS_NO_ERROR (status
))
2159 status
= result_insert (dm
, *insert_pos
, "::*");
2160 if (STATUS_NO_ERROR (status
))
2161 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2162 /* There may be additional levels of (pointer or reference)
2163 indirection in this type. If so, the `*' and `&' should be
2164 added after the pointer-to-member notation (e.g. `C::*&' for
2165 a reference to a pointer-to-member of class C). */
2166 *insert_pos
+= dyn_string_length (class_type
) + 3;
2169 dyn_string_delete (class_type
);
2171 RETURN_IF_ERROR (status
);
2176 /* Ooh, tricky, a pointer-to-function. When we demangle the
2177 function type, the return type should go at the very
2179 *insert_pos
= result_caret_pos (dm
);
2180 /* The parentheses indicate this is a function pointer or
2182 RETURN_IF_ERROR (result_add (dm
, "()"));
2183 /* Now demangle the function type. The return type will be
2184 inserted before the `()', and the argument list will go after
2186 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2187 /* We should now have something along the lines of
2188 `void () (int, int)'. The pointer or reference characters
2189 have to inside the first set of parentheses. *insert_pos has
2190 already been updated to point past the end of the return
2191 type. Move it one character over so it points inside the
2197 /* An array pointer or reference. demangle_array_type will figure
2198 out where the asterisks and ampersands go. */
2199 RETURN_IF_ERROR (demangle_array_type (dm
, insert_pos
));
2203 /* No more pointer or reference tokens; this is therefore a
2204 pointer to data. Finish up by demangling the underlying
2206 RETURN_IF_ERROR (demangle_type (dm
));
2207 /* The pointer or reference characters follow the underlying
2208 type, as in `int*&'. */
2209 *insert_pos
= result_caret_pos (dm
);
2210 /* Because of the production <type> ::= <substitution>,
2211 demangle_type will already have added the underlying type as
2212 a substitution candidate. Don't do it again. */
2213 is_substitution_candidate
= 0;
2217 if (is_substitution_candidate
)
2218 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2223 /* Demangles and emits a <type>.
2225 <type> ::= <builtin-type>
2227 ::= <class-enum-type>
2229 ::= <pointer-to-member-type>
2230 ::= <template-param>
2231 ::= <template-template-param> <template-args>
2232 ::= <CV-qualifiers> <type>
2233 ::= P <type> # pointer-to
2234 ::= R <type> # reference-to
2235 ::= C <type> # complex pair (C 2000)
2236 ::= G <type> # imaginary (C 2000)
2237 ::= U <source-name> <type> # vendor extended type qualifier
2238 ::= <substitution> */
2244 int start
= substitution_start (dm
);
2245 char peek
= peek_char (dm
);
2247 int encode_return_type
= 0;
2248 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2251 /* A <type> can be a <substitution>; therefore, this <type> is a
2252 substitution candidate unless a special condition holds (see
2254 int is_substitution_candidate
= 1;
2256 DEMANGLE_TRACE ("type", dm
);
2258 /* A <class-enum-type> can start with a digit (a <source-name>), an
2259 N (a <nested-name>), or a Z (a <local-name>). */
2260 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2261 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2262 /* Lower-case letters begin <builtin-type>s, except for `r', which
2263 denotes restrict. */
2264 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2266 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2267 /* Built-in types are not substitution candidates. */
2268 is_substitution_candidate
= 0;
2276 /* CV-qualifiers (including restrict). We have to demangle
2277 them off to the side, since C++ syntax puts them in a funny
2278 place for qualified pointer and reference types. */
2281 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2282 int old_caret_position
= result_get_caret (dm
);
2284 if (cv_qualifiers
== NULL
)
2285 return STATUS_ALLOCATION_FAILED
;
2287 /* Decode all adjacent CV qualifiers. */
2288 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2289 /* Emit them, and shift the caret left so that the
2290 underlying type will be emitted before the qualifiers. */
2291 status
= result_add_string (dm
, cv_qualifiers
);
2292 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2294 dyn_string_delete (cv_qualifiers
);
2295 RETURN_IF_ERROR (status
);
2296 /* Also prepend a blank, if needed. */
2297 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2298 result_shift_caret (dm
, -1);
2300 /* Demangle the underlying type. It will be emitted before
2301 the CV qualifiers, since we moved the caret. */
2302 RETURN_IF_ERROR (demangle_type (dm
));
2304 /* Put the caret back where it was previously. */
2305 result_set_caret (dm
, old_caret_position
);
2310 return "Non-pointer or -reference function type.";
2313 RETURN_IF_ERROR (demangle_array_type (dm
, NULL
));
2317 /* It's either a <template-param> or a
2318 <template-template-param>. In either case, demangle the
2320 RETURN_IF_ERROR (demangle_template_param (dm
));
2322 /* Check for a template argument list; if one is found, it's a
2323 <template-template-param> ::= <template-param>
2324 ::= <substitution> */
2325 if (peek_char (dm
) == 'I')
2327 /* Add a substitution candidate. The template parameter
2328 `T' token is a substitution candidate by itself,
2329 without the template argument list. */
2330 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2332 /* Now demangle the template argument list. */
2333 RETURN_IF_ERROR (demangle_template_args (dm
));
2334 /* The entire type, including the template template
2335 parameter and its argument list, will be added as a
2336 substitution candidate below. */
2342 /* First check if this is a special substitution. If it is,
2343 this is a <class-enum-type>. Special substitutions have a
2344 letter following the `S'; other substitutions have a digit
2346 peek_next
= peek_char_next (dm
);
2347 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2349 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2351 /* The substituted name may have been a template name.
2352 Check if template arguments follow, and if so, demangle
2354 if (peek_char (dm
) == 'I')
2355 RETURN_IF_ERROR (demangle_template_args (dm
));
2357 /* A substitution token is not itself a substitution
2358 candidate. (However, if the substituted template is
2359 instantiated, the resulting type is.) */
2360 is_substitution_candidate
= 0;
2364 /* Now some trickiness. We have a special substitution
2365 here. Often, the special substitution provides the
2366 name of a template that's subsequently instantiated,
2367 for instance `SaIcE' => std::allocator<char>. In these
2368 cases we need to add a substitution candidate for the
2369 entire <class-enum-type> and thus don't want to clear
2370 the is_substitution_candidate flag.
2372 However, it's possible that what we have here is a
2373 substitution token representing an entire type, such as
2374 `Ss' => std::string. In this case, we mustn't add a
2375 new substitution candidate for this substitution token.
2376 To detect this case, remember where the start of the
2377 substitution token is. */
2378 const char *next
= dm
->next
;
2379 /* Now demangle the <class-enum-type>. */
2381 (demangle_class_enum_type (dm
, &encode_return_type
));
2382 /* If all that was just demangled is the two-character
2383 special substitution token, supress the addition of a
2384 new candidate for it. */
2385 if (dm
->next
== next
+ 2)
2386 is_substitution_candidate
= 0;
2394 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2395 /* demangle_type_ptr adds all applicable substitution
2397 is_substitution_candidate
= 0;
2401 /* A C99 complex type. */
2402 RETURN_IF_ERROR (result_add (dm
, "complex "));
2404 RETURN_IF_ERROR (demangle_type (dm
));
2408 /* A C99 imaginary type. */
2409 RETURN_IF_ERROR (result_add (dm
, "imaginary "));
2411 RETURN_IF_ERROR (demangle_type (dm
));
2415 /* Vendor-extended type qualifier. */
2417 RETURN_IF_ERROR (demangle_source_name (dm
));
2418 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2419 RETURN_IF_ERROR (demangle_type (dm
));
2423 return "Unexpected character in <type>.";
2426 if (is_substitution_candidate
)
2427 /* Add a new substitution for the type. If this type was a
2428 <template-param>, pass its index since from the point of
2429 substitutions; a <template-param> token is a substitution
2430 candidate distinct from the type that is substituted for it. */
2431 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2433 /* Pop off template argument lists added during mangling of this
2435 pop_to_template_arg_list (dm
, old_arg_list
);
2440 /* C++ source names of builtin types, indexed by the mangled code
2441 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2442 static const char *const builtin_type_names
[26] =
2444 "signed char", /* a */
2448 "long double", /* e */
2450 "__float128", /* g */
2451 "unsigned char", /* h */
2456 "unsigned long", /* m */
2458 "unsigned __int128", /* o */
2463 "unsigned short", /* t */
2467 "long long", /* x */
2468 "unsigned long long", /* y */
2472 /* Demangles and emits a <builtin-type>.
2474 <builtin-type> ::= v # void
2479 ::= h # unsigned char
2481 ::= t # unsigned short
2483 ::= j # unsigned int
2485 ::= m # unsigned long
2486 ::= x # long long, __int64
2487 ::= y # unsigned long long, __int64
2489 ::= o # unsigned __int128
2492 ::= e # long double, __float80
2495 ::= u <source-name> # vendor extended type */
2498 demangle_builtin_type (dm
)
2502 char code
= peek_char (dm
);
2504 DEMANGLE_TRACE ("builtin-type", dm
);
2509 RETURN_IF_ERROR (demangle_source_name (dm
));
2512 else if (code
>= 'a' && code
<= 'z')
2514 const char *type_name
= builtin_type_names
[code
- 'a'];
2515 if (type_name
== NULL
)
2516 return "Unrecognized <builtin-type> code.";
2518 RETURN_IF_ERROR (result_add (dm
, type_name
));
2523 return "Non-alphabetic <builtin-type> code.";
2526 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2527 restrict) at the current position. The qualifiers are appended to
2528 QUALIFIERS. Returns STATUS_OK. */
2531 demangle_CV_qualifiers (dm
, qualifiers
)
2533 dyn_string_t qualifiers
;
2535 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2539 switch (peek_char (dm
))
2542 if (!dyn_string_append_space (qualifiers
))
2543 return STATUS_ALLOCATION_FAILED
;
2544 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2545 return STATUS_ALLOCATION_FAILED
;
2549 if (!dyn_string_append_space (qualifiers
))
2550 return STATUS_ALLOCATION_FAILED
;
2551 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2552 return STATUS_ALLOCATION_FAILED
;
2556 if (!dyn_string_append_space (qualifiers
))
2557 return STATUS_ALLOCATION_FAILED
;
2558 if (!dyn_string_append_cstr (qualifiers
, "const"))
2559 return STATUS_ALLOCATION_FAILED
;
2570 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2571 position in the result string of the start of the function
2572 identifier, at which the function's return type will be inserted;
2573 *FUNCTION_NAME_POS is updated to position past the end of the
2574 function's return type.
2576 <function-type> ::= F [Y] <bare-function-type> E */
2579 demangle_function_type (dm
, function_name_pos
)
2581 int *function_name_pos
;
2583 DEMANGLE_TRACE ("function-type", dm
);
2584 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2585 if (peek_char (dm
) == 'Y')
2587 /* Indicate this function has C linkage if in verbose mode. */
2589 RETURN_IF_ERROR (result_add (dm
, " [extern \"C\"] "));
2592 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2593 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2597 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2598 position in the result string at which the function return type
2599 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2600 function's return type is assumed not to be encoded.
2602 <bare-function-type> ::= <signature type>+ */
2605 demangle_bare_function_type (dm
, return_type_pos
)
2607 int *return_type_pos
;
2609 /* Sequence is the index of the current function parameter, counting
2610 from zero. The value -1 denotes the return type. */
2612 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2614 DEMANGLE_TRACE ("bare-function-type", dm
);
2616 RETURN_IF_ERROR (result_add_char (dm
, '('));
2617 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2620 /* We're decoding the function's return type. */
2622 dyn_string_t return_type
;
2623 status_t status
= STATUS_OK
;
2625 /* Decode the return type off to the side. */
2626 RETURN_IF_ERROR (result_push (dm
));
2627 RETURN_IF_ERROR (demangle_type (dm
));
2628 return_type
= (dyn_string_t
) result_pop (dm
);
2630 /* Add a space to the end of the type. Insert the return
2631 type where we've been asked to. */
2632 if (!dyn_string_append_space (return_type
))
2633 status
= STATUS_ALLOCATION_FAILED
;
2634 if (STATUS_NO_ERROR (status
))
2636 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2638 status
= STATUS_ALLOCATION_FAILED
;
2640 *return_type_pos
+= dyn_string_length (return_type
);
2643 dyn_string_delete (return_type
);
2644 RETURN_IF_ERROR (status
);
2648 /* Skip `void' parameter types. One should only occur as
2649 the only type in a parameter list; in that case, we want
2650 to print `foo ()' instead of `foo (void)'. */
2651 if (peek_char (dm
) == 'v')
2652 /* Consume the v. */
2656 /* Separate parameter types by commas. */
2658 RETURN_IF_ERROR (result_add (dm
, ", "));
2659 /* Demangle the type. */
2660 RETURN_IF_ERROR (demangle_type (dm
));
2666 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2668 /* We should have demangled at least one parameter type (which would
2669 be void, for a function that takes no parameters), plus the
2670 return type, if we were supposed to demangle that. */
2672 return "Missing function return type.";
2673 else if (sequence
== 0)
2674 return "Missing function parameter.";
2679 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2680 non-zero if the type is a template-id, zero otherwise.
2682 <class-enum-type> ::= <name> */
2685 demangle_class_enum_type (dm
, encode_return_type
)
2687 int *encode_return_type
;
2689 DEMANGLE_TRACE ("class-enum-type", dm
);
2691 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2695 /* Demangles and emits an <array-type>.
2697 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2698 pointer or reference to an array, except that asterisk and
2699 ampersand punctuation is omitted (since it's not know at this
2700 point). *PTR_INSERT_POS is set to the position in the demangled
2701 name at which this punctuation should be inserted. For example,
2702 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2703 between the parentheses.
2705 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2706 pointer- or reference-qualified. Then, for example, `A10_i' is
2707 demangled simply as `int[10]'.
2709 <array-type> ::= A [<dimension number>] _ <element type>
2710 ::= A <dimension expression> _ <element type> */
2713 demangle_array_type (dm
, ptr_insert_pos
)
2715 int *ptr_insert_pos
;
2717 status_t status
= STATUS_OK
;
2718 dyn_string_t array_size
= NULL
;
2721 DEMANGLE_TRACE ("array-type", dm
);
2723 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2725 /* Demangle the array size into array_size. */
2726 peek
= peek_char (dm
);
2728 /* Array bound is omitted. This is a C99-style VLA. */
2730 else if (IS_DIGIT (peek_char (dm
)))
2732 /* It looks like a constant array bound. */
2733 array_size
= dyn_string_new (10);
2734 if (array_size
== NULL
)
2735 return STATUS_ALLOCATION_FAILED
;
2736 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2740 /* Anything is must be an expression for a nont-constant array
2741 bound. This happens if the array type occurs in a template
2742 and the array bound references a template parameter. */
2743 RETURN_IF_ERROR (result_push (dm
));
2744 RETURN_IF_ERROR (demangle_expression (dm
));
2745 array_size
= (dyn_string_t
) result_pop (dm
);
2747 /* array_size may have been allocated by now, so we can't use
2748 RETURN_IF_ERROR until it's been deallocated. */
2750 /* Demangle the base type of the array. */
2751 if (STATUS_NO_ERROR (status
))
2752 status
= demangle_char (dm
, '_');
2753 if (STATUS_NO_ERROR (status
))
2754 status
= demangle_type (dm
);
2756 if (ptr_insert_pos
!= NULL
)
2758 /* This array is actually part of an pointer- or
2759 reference-to-array type. Format appropriately, except we
2760 don't know which and how much punctuation to use. */
2761 if (STATUS_NO_ERROR (status
))
2762 status
= result_add (dm
, " () ");
2763 /* Let the caller know where to insert the punctuation. */
2764 *ptr_insert_pos
= result_caret_pos (dm
) - 2;
2767 /* Emit the array dimension syntax. */
2768 if (STATUS_NO_ERROR (status
))
2769 status
= result_add_char (dm
, '[');
2770 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2771 status
= result_add_string (dm
, array_size
);
2772 if (STATUS_NO_ERROR (status
))
2773 status
= result_add_char (dm
, ']');
2774 if (array_size
!= NULL
)
2775 dyn_string_delete (array_size
);
2777 RETURN_IF_ERROR (status
);
2782 /* Demangles and emits a <template-param>.
2784 <template-param> ::= T_ # first template parameter
2785 ::= T <parameter-2 number> _ */
2788 demangle_template_param (dm
)
2792 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2795 DEMANGLE_TRACE ("template-param", dm
);
2797 /* Make sure there is a template argmust list in which to look up
2798 this parameter reference. */
2799 if (current_arg_list
== NULL
)
2800 return "Template parameter outside of template.";
2802 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2803 if (peek_char (dm
) == '_')
2807 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2810 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2812 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2814 /* parm_number exceeded the number of arguments in the current
2815 template argument list. */
2816 return "Template parameter number out of bounds.";
2817 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2822 /* Demangles and emits a <template-args>.
2824 <template-args> ::= I <template-arg>+ E */
2827 demangle_template_args (dm
)
2831 dyn_string_t old_last_source_name
;
2832 template_arg_list_t arg_list
= template_arg_list_new ();
2834 if (arg_list
== NULL
)
2835 return STATUS_ALLOCATION_FAILED
;
2837 /* Preserve the most recently demangled source name. */
2838 old_last_source_name
= dm
->last_source_name
;
2839 dm
->last_source_name
= dyn_string_new (0);
2841 DEMANGLE_TRACE ("template-args", dm
);
2843 if (dm
->last_source_name
== NULL
)
2844 return STATUS_ALLOCATION_FAILED
;
2846 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2847 RETURN_IF_ERROR (result_open_template_list (dm
));
2855 RETURN_IF_ERROR (result_add (dm
, ", "));
2857 /* Capture the template arg. */
2858 RETURN_IF_ERROR (result_push (dm
));
2859 RETURN_IF_ERROR (demangle_template_arg (dm
));
2860 arg
= result_pop (dm
);
2862 /* Emit it in the demangled name. */
2863 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2865 /* Save it for use in expanding <template-param>s. */
2866 template_arg_list_add_arg (arg_list
, arg
);
2868 while (peek_char (dm
) != 'E');
2869 /* Append the '>'. */
2870 RETURN_IF_ERROR (result_close_template_list (dm
));
2872 /* Consume the 'E'. */
2875 /* Restore the most recent demangled source name. */
2876 dyn_string_delete (dm
->last_source_name
);
2877 dm
->last_source_name
= old_last_source_name
;
2879 /* Push the list onto the top of the stack of template argument
2880 lists, so that arguments from it are used from now on when
2881 expanding <template-param>s. */
2882 push_template_arg_list (dm
, arg_list
);
2887 /* This function, which does not correspond to a production in the
2888 mangling spec, handles the `literal' production for both
2889 <template-arg> and <expr-primary>. It does not expect or consume
2890 the initial `L' or final `E'. The demangling is given by:
2892 <literal> ::= <type> </value/ number>
2894 and the emitted output is `(type)number'. */
2897 demangle_literal (dm
)
2900 char peek
= peek_char (dm
);
2901 dyn_string_t value_string
;
2904 DEMANGLE_TRACE ("literal", dm
);
2906 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2908 /* If not in verbose mode and this is a builtin type, see if we
2909 can produce simpler numerical output. In particular, for
2910 integer types shorter than `long', just write the number
2911 without type information; for bools, write `true' or `false'.
2912 Other refinements could be made here too. */
2914 /* This constant string is used to map from <builtin-type> codes
2915 (26 letters of the alphabet) to codes that determine how the
2916 value will be displayed. The codes are:
2920 A space means the value will be represented using cast
2922 static const char *const code_map
= "ibi iii ll ii i ";
2924 char code
= code_map
[peek
- 'a'];
2925 /* FIXME: Implement demangling of floats and doubles. */
2927 return STATUS_UNIMPLEMENTED
;
2930 /* It's a boolean. */
2933 /* Consume the b. */
2935 /* Look at the next character. It should be 0 or 1,
2936 corresponding to false or true, respectively. */
2937 value
= peek_char (dm
);
2939 RETURN_IF_ERROR (result_add (dm
, "false"));
2940 else if (value
== '1')
2941 RETURN_IF_ERROR (result_add (dm
, "true"));
2943 return "Unrecognized bool constant.";
2944 /* Consume the 0 or 1. */
2948 else if (code
== 'i' || code
== 'l')
2950 /* It's an integer or long. */
2952 /* Consume the type character. */
2955 /* Demangle the number and write it out. */
2956 value_string
= dyn_string_new (0);
2957 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2958 if (STATUS_NO_ERROR (status
))
2959 status
= result_add_string (dm
, value_string
);
2960 /* For long integers, append an l. */
2961 if (code
== 'l' && STATUS_NO_ERROR (status
))
2962 status
= result_add_char (dm
, code
);
2963 dyn_string_delete (value_string
);
2965 RETURN_IF_ERROR (status
);
2968 /* ...else code == ' ', so fall through to represent this
2969 literal's type explicitly using cast syntax. */
2972 RETURN_IF_ERROR (result_add_char (dm
, '('));
2973 RETURN_IF_ERROR (demangle_type (dm
));
2974 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2976 value_string
= dyn_string_new (0);
2977 if (value_string
== NULL
)
2978 return STATUS_ALLOCATION_FAILED
;
2980 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2981 if (STATUS_NO_ERROR (status
))
2982 status
= result_add_string (dm
, value_string
);
2983 dyn_string_delete (value_string
);
2984 RETURN_IF_ERROR (status
);
2989 /* Demangles and emits a <template-arg>.
2991 <template-arg> ::= <type> # type
2992 ::= L <type> <value number> E # literal
2993 ::= LZ <encoding> E # external name
2994 ::= X <expression> E # expression */
2997 demangle_template_arg (dm
)
3000 DEMANGLE_TRACE ("template-arg", dm
);
3002 switch (peek_char (dm
))
3007 if (peek_char (dm
) == 'Z')
3009 /* External name. */
3011 /* FIXME: Standard is contradictory here. */
3012 RETURN_IF_ERROR (demangle_encoding (dm
));
3015 RETURN_IF_ERROR (demangle_literal (dm
));
3016 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3022 RETURN_IF_ERROR (demangle_expression (dm
));
3023 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3027 RETURN_IF_ERROR (demangle_type (dm
));
3034 /* Demangles and emits an <expression>.
3036 <expression> ::= <unary operator-name> <expression>
3037 ::= <binary operator-name> <expression> <expression>
3039 ::= <scope-expression> */
3042 demangle_expression (dm
)
3045 char peek
= peek_char (dm
);
3047 DEMANGLE_TRACE ("expression", dm
);
3049 if (peek
== 'L' || peek
== 'T')
3050 RETURN_IF_ERROR (demangle_expr_primary (dm
));
3051 else if (peek
== 's' && peek_char_next (dm
) == 'r')
3052 RETURN_IF_ERROR (demangle_scope_expression (dm
));
3054 /* An operator expression. */
3057 status_t status
= STATUS_OK
;
3058 dyn_string_t operator_name
;
3060 /* We have an operator name. Since we want to output binary
3061 operations in infix notation, capture the operator name
3063 RETURN_IF_ERROR (result_push (dm
));
3064 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
3065 operator_name
= (dyn_string_t
) result_pop (dm
);
3067 /* If it's binary, do an operand first. */
3070 status
= result_add_char (dm
, '(');
3071 if (STATUS_NO_ERROR (status
))
3072 status
= demangle_expression (dm
);
3073 if (STATUS_NO_ERROR (status
))
3074 status
= result_add_char (dm
, ')');
3077 /* Emit the operator. */
3078 if (STATUS_NO_ERROR (status
))
3079 status
= result_add_string (dm
, operator_name
);
3080 dyn_string_delete (operator_name
);
3081 RETURN_IF_ERROR (status
);
3083 /* Emit its second (if binary) or only (if unary) operand. */
3084 RETURN_IF_ERROR (result_add_char (dm
, '('));
3085 RETURN_IF_ERROR (demangle_expression (dm
));
3086 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3088 /* The ternary operator takes a third operand. */
3091 RETURN_IF_ERROR (result_add (dm
, ":("));
3092 RETURN_IF_ERROR (demangle_expression (dm
));
3093 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3100 /* Demangles and emits a <scope-expression>.
3102 <scope-expression> ::= sr <qualifying type> <source-name>
3103 ::= sr <qualifying type> <encoding> */
3106 demangle_scope_expression (dm
)
3109 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3110 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3111 RETURN_IF_ERROR (demangle_type (dm
));
3112 RETURN_IF_ERROR (result_add (dm
, "::"));
3113 RETURN_IF_ERROR (demangle_encoding (dm
));
3117 /* Demangles and emits an <expr-primary>.
3119 <expr-primary> ::= <template-param>
3120 ::= L <type> <value number> E # literal
3121 ::= L <mangled-name> E # external name */
3124 demangle_expr_primary (dm
)
3127 char peek
= peek_char (dm
);
3129 DEMANGLE_TRACE ("expr-primary", dm
);
3132 RETURN_IF_ERROR (demangle_template_param (dm
));
3133 else if (peek
== 'L')
3135 /* Consume the `L'. */
3137 peek
= peek_char (dm
);
3140 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3142 RETURN_IF_ERROR (demangle_literal (dm
));
3144 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3147 return STATUS_ERROR
;
3152 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3153 if the substitution is the name of a template, zero otherwise.
3155 <substitution> ::= S <seq-id> _
3159 ::= Sa # ::std::allocator
3160 ::= Sb # ::std::basic_string
3161 ::= Ss # ::std::basic_string<char,
3162 ::std::char_traits<char>,
3163 ::std::allocator<char> >
3164 ::= Si # ::std::basic_istream<char,
3165 std::char_traits<char> >
3166 ::= So # ::std::basic_ostream<char,
3167 std::char_traits<char> >
3168 ::= Sd # ::std::basic_iostream<char,
3169 std::char_traits<char> >
3173 demangle_substitution (dm
, template_p
)
3181 DEMANGLE_TRACE ("substitution", dm
);
3183 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3185 /* Scan the substitution sequence index. A missing number denotes
3187 peek
= peek_char (dm
);
3190 /* If the following character is 0-9 or a capital letter, interpret
3191 the sequence up to the next underscore as a base-36 substitution
3193 else if (IS_DIGIT ((unsigned char) peek
)
3194 || (peek
>= 'A' && peek
<= 'Z'))
3195 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3198 const char *new_last_source_name
= NULL
;
3203 RETURN_IF_ERROR (result_add (dm
, "std"));
3207 RETURN_IF_ERROR (result_add (dm
, "std::allocator"));
3208 new_last_source_name
= "allocator";
3213 RETURN_IF_ERROR (result_add (dm
, "std::basic_string"));
3214 new_last_source_name
= "basic_string";
3221 RETURN_IF_ERROR (result_add (dm
, "std::string"));
3222 new_last_source_name
= "string";
3226 RETURN_IF_ERROR (result_add (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3227 new_last_source_name
= "basic_string";
3235 RETURN_IF_ERROR (result_add (dm
, "std::istream"));
3236 new_last_source_name
= "istream";
3240 RETURN_IF_ERROR (result_add (dm
, "std::basic_istream<char, std::char_traints<char> >"));
3241 new_last_source_name
= "basic_istream";
3249 RETURN_IF_ERROR (result_add (dm
, "std::ostream"));
3250 new_last_source_name
= "ostream";
3254 RETURN_IF_ERROR (result_add (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3255 new_last_source_name
= "basic_ostream";
3263 RETURN_IF_ERROR (result_add (dm
, "std::iostream"));
3264 new_last_source_name
= "iostream";
3268 RETURN_IF_ERROR (result_add (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3269 new_last_source_name
= "basic_iostream";
3275 return "Unrecognized <substitution>.";
3278 /* Consume the character we just processed. */
3281 if (new_last_source_name
!= NULL
)
3283 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3284 new_last_source_name
))
3285 return STATUS_ALLOCATION_FAILED
;
3291 /* Look up the substitution text. Since `S_' is the most recent
3292 substitution, `S0_' is the second-most-recent, etc., shift the
3293 numbering by one. */
3294 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3296 return "Substitution number out of range.";
3298 /* Emit the substitution text. */
3299 RETURN_IF_ERROR (result_add_string (dm
, text
));
3301 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3305 /* Demangles and emits a <local-name>.
3307 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3308 := Z <function encoding> E s [<discriminator>] */
3311 demangle_local_name (dm
)
3314 DEMANGLE_TRACE ("local-name", dm
);
3316 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3317 RETURN_IF_ERROR (demangle_encoding (dm
));
3318 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3319 RETURN_IF_ERROR (result_add (dm
, "::"));
3321 if (peek_char (dm
) == 's')
3323 /* Local character string literal. */
3324 RETURN_IF_ERROR (result_add (dm
, "string literal"));
3325 /* Consume the s. */
3327 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3332 /* Local name for some other entity. Demangle its name. */
3333 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3334 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3340 /* Optimonally demangles and emits a <discriminator>. If there is no
3341 <discriminator> at the current position in the mangled string, the
3342 descriminator is assumed to be zero. Emit the discriminator number
3343 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3344 discriminator is zero.
3346 <discriminator> ::= _ <number> */
3349 demangle_discriminator (dm
, suppress_first
)
3353 /* Output for <discriminator>s to the demangled name is completely
3354 suppressed if not in verbose mode. */
3356 if (peek_char (dm
) == '_')
3358 /* Consume the underscore. */
3361 RETURN_IF_ERROR (result_add (dm
, " [#"));
3362 /* Check if there's a number following the underscore. */
3363 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3366 /* Demangle the number. */
3367 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3369 /* Write the discriminator. The mangled number is two
3370 less than the discriminator ordinal, counting from
3372 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 2,
3373 (dyn_string_t
) dm
->result
));
3378 /* A missing digit correspond to one. */
3379 RETURN_IF_ERROR (result_add_char (dm
, '1'));
3382 RETURN_IF_ERROR (result_add_char (dm
, ']'));
3384 else if (!suppress_first
)
3387 RETURN_IF_ERROR (result_add (dm
, " [#0]"));
3393 /* Demangle NAME into RESULT, which must be an initialized
3394 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3395 an error message, and the contents of RESULT are unchanged. */
3398 cp_demangle (name
, result
)
3400 dyn_string_t result
;
3403 int length
= strlen (name
);
3405 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3407 demangling_t dm
= demangling_new (name
);
3409 return STATUS_ALLOCATION_FAILED
;
3411 status
= result_push (dm
);
3412 if (status
!= STATUS_OK
)
3414 demangling_delete (dm
);
3418 status
= demangle_mangled_name (dm
);
3419 if (STATUS_NO_ERROR (status
))
3421 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3422 if (!dyn_string_copy (result
, demangled
))
3423 return STATUS_ALLOCATION_FAILED
;
3424 dyn_string_delete (demangled
);
3427 demangling_delete (dm
);
3431 /* It's evidently not a mangled C++ name. It could be the name
3432 of something with C linkage, though, so just copy NAME into
3434 if (!dyn_string_copy_cstr (result
, name
))
3435 return STATUS_ALLOCATION_FAILED
;
3442 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3443 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3444 an error message, and the contents of RESULT are unchanged. */
3448 cp_demangle_type (type_name
, result
)
3449 const char* type_name
;
3450 dyn_string_t result
;
3453 demangling_t dm
= demangling_new (type_name
);
3456 return STATUS_ALLOCATION_FAILED
;
3458 /* Demangle the type name. The demangled name is stored in dm. */
3459 status
= result_push (dm
);
3460 if (status
!= STATUS_OK
)
3462 demangling_delete (dm
);
3466 status
= demangle_type (dm
);
3468 if (STATUS_NO_ERROR (status
))
3470 /* The demangling succeeded. Pop the result out of dm and copy
3472 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3473 if (!dyn_string_copy (result
, demangled
))
3474 return STATUS_ALLOCATION_FAILED
;
3475 dyn_string_delete (demangled
);
3479 demangling_delete (dm
);
3484 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3486 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3487 demangling. MANGLED_NAME is a NUL-terminated character string
3488 containing the name to be demangled.
3490 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3491 *LENGTH bytes, into which the demangled name is stored. If
3492 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3493 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3494 is placed in a region of memory allocated with malloc.
3496 If LENGTH is non-NULL, the length of the buffer conaining the
3497 demangled name, is placed in *LENGTH.
3499 The return value is a pointer to the start of the NUL-terminated
3500 demangled name, or NULL if the demangling fails. The caller is
3501 responsible for deallocating this memory using free.
3503 *STATUS is set to one of the following values:
3504 0: The demangling operation succeeded.
3505 -1: A memory allocation failiure occurred.
3506 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3507 -3: One of the arguments is invalid.
3509 The demagling is performed using the C++ ABI mangling rules, with
3513 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3514 const char *mangled_name
;
3515 char *output_buffer
;
3519 struct dyn_string demangled_name
;
3525 if (mangled_name
== NULL
) {
3530 /* Did the caller provide a buffer for the demangled name? */
3531 if (output_buffer
== NULL
) {
3532 /* No; dyn_string will malloc a buffer for us. */
3533 if (!dyn_string_init (&demangled_name
, 0))
3540 /* Yes. Check that the length was provided. */
3541 if (length
== NULL
) {
3545 /* Install the buffer into a dyn_string. */
3546 demangled_name
.allocated
= *length
;
3547 demangled_name
.length
= 0;
3548 demangled_name
.s
= output_buffer
;
3551 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3552 /* MANGLED_NAME apprears to be a function or variable name.
3553 Demangle it accordingly. */
3554 result
= cp_demangle (mangled_name
, &demangled_name
);
3556 /* Try to demangled MANGLED_NAME as the name of a type. */
3557 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3559 if (result
== STATUS_OK
)
3560 /* The demangling succeeded. */
3562 /* If LENGTH isn't NULL, store the allocated buffer length
3563 there; the buffer may have been realloced by dyn_string
3566 *length
= demangled_name
.allocated
;
3567 /* The operation was a success. */
3569 return dyn_string_buf (&demangled_name
);
3571 else if (result
== STATUS_ALLOCATION_FAILED
)
3572 /* A call to malloc or realloc failed during the demangling
3579 /* The demangling failed for another reason, most probably because
3580 MANGLED_NAME isn't a valid mangled name. */
3582 /* If the buffer containing the demangled name wasn't provided
3583 by the caller, free it. */
3584 if (output_buffer
== NULL
)
3585 free (dyn_string_buf (&demangled_name
));
3591 #else /* !IN_LIBGCC2 */
3593 /* Variant entry point for integration with the existing cplus-dem
3594 demangler. Attempts to demangle MANGLED. If the demangling
3595 succeeds, returns a buffer, allocated with malloc, containing the
3596 demangled name. The caller must deallocate the buffer using free.
3597 If the demangling failes, returns NULL. */
3600 cplus_demangle_v3 (mangled
)
3601 const char* mangled
;
3603 dyn_string_t demangled
;
3606 /* If this isn't a mangled name, don't pretend to demangle it. */
3607 if (strncmp (mangled
, "_Z", 2) != 0)
3610 /* Create a dyn_string to hold the demangled name. */
3611 demangled
= dyn_string_new (0);
3612 /* Attempt the demangling. */
3613 status
= cp_demangle ((char *) mangled
, demangled
);
3615 if (STATUS_NO_ERROR (status
))
3616 /* Demangling succeeded. */
3618 /* Grab the demangled result from the dyn_string. It was
3619 allocated with malloc, so we can return it directly. */
3620 char *return_value
= dyn_string_release (demangled
);
3621 /* Hand back the demangled name. */
3622 return return_value
;
3624 else if (status
== STATUS_ALLOCATION_FAILED
)
3626 fprintf (stderr
, "Memory allocation failed.\n");
3630 /* Demangling failed. */
3632 dyn_string_delete (demangled
);
3637 #endif /* IN_LIBGCC2 */
3639 #ifdef STANDALONE_DEMANGLER
3643 static void print_usage
3644 PARAMS ((FILE* fp
, int exit_value
));
3646 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3647 #define is_mangled_char(CHAR) \
3648 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3649 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3651 /* The name of this program, as invoked. */
3652 const char* program_name
;
3654 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3657 print_usage (fp
, exit_value
)
3661 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3662 fprintf (fp
, "Options:\n");
3663 fprintf (fp
, " -h,--help Display this message.\n");
3664 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3665 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3666 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3671 /* Option specification for getopt_long. */
3672 static struct option long_options
[] =
3674 { "help", no_argument
, NULL
, 'h' },
3675 { "strict", no_argument
, NULL
, 's' },
3676 { "verbose", no_argument
, NULL
, 'v' },
3677 { NULL
, no_argument
, NULL
, 0 },
3680 /* Main entry for a demangling filter executable. It will demangle
3681 its command line arguments, if any. If none are provided, it will
3682 filter stdin to stdout, replacing any recognized mangled C++ names
3683 with their demangled equivalents. */
3694 /* Use the program name of this program, as invoked. */
3695 program_name
= argv
[0];
3697 /* Parse options. */
3700 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3703 case '?': /* Unrecognized option. */
3704 print_usage (stderr
, 1);
3708 print_usage (stdout
, 0);
3720 while (opt_char
!= -1);
3723 /* No command line arguments were provided. Filter stdin. */
3725 dyn_string_t mangled
= dyn_string_new (3);
3726 dyn_string_t demangled
= dyn_string_new (0);
3729 /* Read all of input. */
3730 while (!feof (stdin
))
3732 char c
= getchar ();
3734 /* The first character of a mangled name is an underscore. */
3739 /* It's not a mangled name. Print the character and go
3746 /* The second character of a mangled name is a capital `Z'. */
3751 /* It's not a mangled name. Print the previous
3752 underscore, the `Z', and go on. */
3758 /* Start keeping track of the candidate mangled name. */
3759 dyn_string_append_char (mangled
, '_');
3760 dyn_string_append_char (mangled
, 'Z');
3762 /* Pile characters into mangled until we hit one that can't
3763 occur in a mangled name. */
3765 while (!feof (stdin
) && is_mangled_char (c
))
3767 dyn_string_append_char (mangled
, c
);
3773 /* Attempt to demangle the name. */
3774 status
= cp_demangle (dyn_string_buf (mangled
), demangled
);
3776 /* If the demangling succeeded, great! Print out the
3777 demangled version. */
3778 if (STATUS_NO_ERROR (status
))
3779 fputs (dyn_string_buf (demangled
), stdout
);
3780 /* Abort on allocation failures. */
3781 else if (status
== STATUS_ALLOCATION_FAILED
)
3783 fprintf (stderr
, "Memory allocation failed.\n");
3786 /* Otherwise, it might not have been a mangled name. Just
3787 print out the original text. */
3789 fputs (dyn_string_buf (mangled
), stdout
);
3791 /* If we haven't hit EOF yet, we've read one character that
3792 can't occur in a mangled name, so print it out. */
3796 /* Clear the candidate mangled name, to start afresh next
3797 time we hit a `_Z'. */
3798 dyn_string_clear (mangled
);
3801 dyn_string_delete (mangled
);
3802 dyn_string_delete (demangled
);
3805 /* Demangle command line arguments. */
3807 dyn_string_t result
= dyn_string_new (0);
3809 /* Loop over command line arguments. */
3810 for (i
= optind
; i
< argc
; ++i
)
3812 /* Attempt to demangle. */
3813 status
= cp_demangle (argv
[i
], result
);
3815 /* If it worked, print the demangled name. */
3816 if (STATUS_NO_ERROR (status
))
3817 printf ("%s\n", dyn_string_buf (result
));
3818 /* Abort on allocaiton failures. */
3819 else if (status
== STATUS_ALLOCATION_FAILED
)
3821 fprintf (stderr
, "Memory allocaiton failed.\n");
3824 /* If not, print the error message to stderr instead. */
3826 fprintf (stderr
, "%s\n", status
);
3828 dyn_string_delete (result
);
3834 #endif /* STANDALONE_DEMANGLER */