1 /* Demangler for IA64 / g++ V3 ABI.
2 Copyright (C) 2000, 2001 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 /* Character(s) to use for namespace separation in demangled output */
72 #define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
74 /* If flag_verbose is zero, some simplifications will be made to the
75 output to make it easier to read and supress details that are
76 generally not of interest to the average C++ programmer.
77 Otherwise, the demangled representation will attempt to convey as
78 much information as the mangled form. */
79 static int flag_verbose
;
81 /* If flag_strict is non-zero, demangle strictly according to the
82 specification -- don't demangle special g++ manglings. */
83 static int flag_strict
;
85 /* String_list_t is an extended form of dyn_string_t which provides a
86 link field and a caret position for additions to the string. A
87 string_list_t may safely be cast to and used as a dyn_string_t. */
89 struct string_list_def
91 /* The dyn_string; must be first. */
92 struct dyn_string string
;
94 /* The position at which additional text is added to this string
95 (using the result_add* macros). This value is an offset from the
96 end of the string, not the beginning (and should be
100 /* The next string in the list. */
101 struct string_list_def
*next
;
104 typedef struct string_list_def
*string_list_t
;
106 /* Data structure representing a potential substitution. */
108 struct substitution_def
110 /* The demangled text of the substitution. */
113 /* Whether this substitution represents a template item. */
117 /* Data structure representing a template argument list. */
119 struct template_arg_list_def
121 /* The next (lower) template argument list in the stack of currently
122 active template arguments. */
123 struct template_arg_list_def
*next
;
125 /* The first element in the list of template arguments in
126 left-to-right order. */
127 string_list_t first_argument
;
129 /* The last element in the arguments lists. */
130 string_list_t last_argument
;
133 typedef struct template_arg_list_def
*template_arg_list_t
;
135 /* Data structure to maintain the state of the current demangling. */
137 struct demangling_def
139 /* The full mangled name being mangled. */
142 /* Pointer into name at the current position. */
145 /* Stack for strings containing demangled result generated so far.
146 Text is emitted to the topmost (first) string. */
147 string_list_t result
;
149 /* The number of presently available substitutions. */
150 int num_substitutions
;
152 /* The allocated size of the substitutions array. */
153 int substitutions_allocated
;
155 /* An array of available substitutions. The number of elements in
156 the array is given by num_substitions, and the allocated array
157 size in substitutions_size.
159 The most recent substition is at the end, so
161 - `S_' corresponds to substititutions[num_substitutions - 1]
162 - `S0_' corresponds to substititutions[num_substitutions - 2]
165 struct substitution_def
*substitutions
;
167 /* The stack of template argument lists. */
168 template_arg_list_t template_arg_lists
;
170 /* The most recently demangled source-name. */
171 dyn_string_t last_source_name
;
173 /* Language style to use for demangled output. */
177 typedef struct demangling_def
*demangling_t
;
179 /* This type is the standard return code from most functions. Values
180 other than STATUS_OK contain descriptive messages. */
181 typedef const char *status_t
;
183 /* Special values that can be used as a status_t. */
184 #define STATUS_OK NULL
185 #define STATUS_ERROR "Error."
186 #define STATUS_UNIMPLEMENTED "Unimplemented."
187 #define STATUS_INTERNAL_ERROR "Internal error."
189 /* This status code indicates a failure in malloc or realloc. */
190 static const char *const status_allocation_failed
= "Allocation failed.";
191 #define STATUS_ALLOCATION_FAILED status_allocation_failed
193 /* Non-zero if STATUS indicates that no error has occurred. */
194 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
196 /* Evaluate EXPR, which must produce a status_t. If the status code
197 indicates an error, return from the current function with that
199 #define RETURN_IF_ERROR(EXPR) \
203 if (!STATUS_NO_ERROR (s)) \
208 static status_t int_to_dyn_string
209 PARAMS ((int, dyn_string_t
));
210 static string_list_t string_list_new
212 static void string_list_delete
213 PARAMS ((string_list_t
));
214 static status_t result_add_separated_char
215 PARAMS ((demangling_t
, int));
216 static status_t result_push
217 PARAMS ((demangling_t
));
218 static string_list_t result_pop
219 PARAMS ((demangling_t
));
220 static int substitution_start
221 PARAMS ((demangling_t
));
222 static status_t substitution_add
223 PARAMS ((demangling_t
, int, int));
224 static dyn_string_t substitution_get
225 PARAMS ((demangling_t
, int, int *));
226 #ifdef CP_DEMANGLE_DEBUG
227 static void substitutions_print
228 PARAMS ((demangling_t
, FILE *));
230 static template_arg_list_t template_arg_list_new
232 static void template_arg_list_delete
233 PARAMS ((template_arg_list_t
));
234 static void template_arg_list_add_arg
235 PARAMS ((template_arg_list_t
, string_list_t
));
236 static string_list_t template_arg_list_get_arg
237 PARAMS ((template_arg_list_t
, int));
238 static void push_template_arg_list
239 PARAMS ((demangling_t
, template_arg_list_t
));
240 static void pop_to_template_arg_list
241 PARAMS ((demangling_t
, template_arg_list_t
));
242 #ifdef CP_DEMANGLE_DEBUG
243 static void template_arg_list_print
244 PARAMS ((template_arg_list_t
, FILE *));
246 static template_arg_list_t current_template_arg_list
247 PARAMS ((demangling_t
));
248 static demangling_t demangling_new
249 PARAMS ((const char *, int));
250 static void demangling_delete
251 PARAMS ((demangling_t
));
253 /* The last character of DS. Warning: DS is evaluated twice. */
254 #define dyn_string_last_char(DS) \
255 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
257 /* Append a space character (` ') to DS if it does not already end
258 with one. Evaluates to 1 on success, or 0 on allocation failure. */
259 #define dyn_string_append_space(DS) \
260 ((dyn_string_length (DS) > 0 \
261 && dyn_string_last_char (DS) != ' ') \
262 ? dyn_string_append_char ((DS), ' ') \
265 /* Returns the index of the current position in the mangled name. */
266 #define current_position(DM) ((DM)->next - (DM)->name)
268 /* Returns the character at the current position of the mangled name. */
269 #define peek_char(DM) (*((DM)->next))
271 /* Returns the character one past the current position of the mangled
273 #define peek_char_next(DM) \
274 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
276 /* Returns the character at the current position, and advances the
277 current position to the next character. */
278 #define next_char(DM) (*((DM)->next)++)
280 /* Returns non-zero if the current position is the end of the mangled
281 name, i.e. one past the last character. */
282 #define end_of_name_p(DM) (peek_char (DM) == '\0')
284 /* Advances the current position by one character. */
285 #define advance_char(DM) (++(DM)->next)
287 /* Returns the string containing the current demangled result. */
288 #define result_string(DM) (&(DM)->result->string)
290 /* Returns the position at which new text is inserted into the
292 #define result_caret_pos(DM) \
293 (result_length (DM) + \
294 ((string_list_t) result_string (DM))->caret_position)
296 /* Adds a dyn_string_t to the demangled result. */
297 #define result_add_string(DM, STRING) \
298 (dyn_string_insert (&(DM)->result->string, \
299 result_caret_pos (DM), (STRING)) \
300 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
302 /* Adds NUL-terminated string CSTR to the demangled result. */
303 #define result_add(DM, CSTR) \
304 (dyn_string_insert_cstr (&(DM)->result->string, \
305 result_caret_pos (DM), (CSTR)) \
306 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
308 /* Adds character CHAR to the demangled result. */
309 #define result_add_char(DM, CHAR) \
310 (dyn_string_insert_char (&(DM)->result->string, \
311 result_caret_pos (DM), (CHAR)) \
312 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
314 /* Inserts a dyn_string_t to the demangled result at position POS. */
315 #define result_insert_string(DM, POS, STRING) \
316 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
317 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
319 /* Inserts NUL-terminated string CSTR to the demangled result at
321 #define result_insert(DM, POS, CSTR) \
322 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
323 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
325 /* Inserts character CHAR to the demangled result at position POS. */
326 #define result_insert_char(DM, POS, CHAR) \
327 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
328 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
330 /* The length of the current demangled result. */
331 #define result_length(DM) \
332 dyn_string_length (&(DM)->result->string)
334 /* Appends a (less-than, greater-than) character to the result in DM
335 to (open, close) a template argument or parameter list. Appends a
336 space first if necessary to prevent spurious elision of angle
337 brackets with the previous character. */
338 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
339 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
341 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
342 success. On failure, deletes DS and returns an error code. */
345 int_to_dyn_string (value
, ds
)
352 /* Handle zero up front. */
355 if (!dyn_string_append_char (ds
, '0'))
356 return STATUS_ALLOCATION_FAILED
;
360 /* For negative numbers, emit a minus sign. */
363 if (!dyn_string_append_char (ds
, '-'))
364 return STATUS_ALLOCATION_FAILED
;
368 /* Find the power of 10 of the first digit. */
376 /* Write the digits. */
379 int digit
= value
/ mask
;
381 if (!dyn_string_append_char (ds
, '0' + digit
))
382 return STATUS_ALLOCATION_FAILED
;
384 value
-= digit
* mask
;
391 /* Creates a new string list node. The contents of the string are
392 empty, but the initial buffer allocation is LENGTH. The string
393 list node should be deleted with string_list_delete. Returns NULL
394 if allocation fails. */
397 string_list_new (length
)
400 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
401 s
->caret_position
= 0;
404 if (!dyn_string_init ((dyn_string_t
) s
, length
))
409 /* Deletes the entire string list starting at NODE. */
412 string_list_delete (node
)
417 string_list_t next
= node
->next
;
423 /* Appends CHARACTER to the demangled result. If the current trailing
424 character of the result is CHARACTER, a space is inserted first. */
427 result_add_separated_char (dm
, character
)
431 char *result
= dyn_string_buf (result_string (dm
));
432 int caret_pos
= result_caret_pos (dm
);
434 /* Add a space if the last character is already the character we
436 if (caret_pos
> 0 && result
[caret_pos
- 1] == character
)
437 RETURN_IF_ERROR (result_add_char (dm
, ' '));
438 /* Add the character. */
439 RETURN_IF_ERROR (result_add_char (dm
, character
));
444 /* Allocates and pushes a new string onto the demangled results stack
445 for DM. Subsequent demangling with DM will emit to the new string.
446 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
447 allocation failure. */
453 string_list_t new_string
= string_list_new (0);
454 if (new_string
== NULL
)
455 /* Allocation failed. */
456 return STATUS_ALLOCATION_FAILED
;
458 /* Link the new string to the front of the list of result strings. */
459 new_string
->next
= (string_list_t
) dm
->result
;
460 dm
->result
= new_string
;
464 /* Removes and returns the topmost element on the demangled results
465 stack for DM. The caller assumes ownership for the returned
472 string_list_t top
= dm
->result
;
473 dm
->result
= top
->next
;
477 /* Returns the current value of the caret for the result string. The
478 value is an offet from the end of the result string. */
481 result_get_caret (dm
)
484 return ((string_list_t
) result_string (dm
))->caret_position
;
487 /* Sets the value of the caret for the result string, counted as an
488 offet from the end of the result string. */
491 result_set_caret (dm
, position
)
495 ((string_list_t
) result_string (dm
))->caret_position
= position
;
498 /* Shifts the position of the next addition to the result by
499 POSITION_OFFSET. A negative value shifts the caret to the left. */
502 result_shift_caret (dm
, position_offset
)
506 ((string_list_t
) result_string (dm
))->caret_position
+= position_offset
;
509 /* Returns non-zero if the character that comes right before the place
510 where text will be added to the result is a space. In this case,
511 the caller should supress adding another space. */
514 result_previous_char_is_space (dm
)
517 char *result
= dyn_string_buf (result_string (dm
));
518 int pos
= result_caret_pos (dm
);
519 return pos
> 0 && result
[pos
- 1] == ' ';
522 /* Returns the start position of a fragment of the demangled result
523 that will be a substitution candidate. Should be called at the
524 start of productions that can add substitutions. */
527 substitution_start (dm
)
530 return result_caret_pos (dm
);
533 /* Adds the suffix of the current demangled result of DM starting at
534 START_POSITION as a potential substitution. If TEMPLATE_P is
535 non-zero, this potential substitution is a template-id. */
538 substitution_add (dm
, start_position
, template_p
)
543 dyn_string_t result
= result_string (dm
);
544 dyn_string_t substitution
= dyn_string_new (0);
547 if (substitution
== NULL
)
548 return STATUS_ALLOCATION_FAILED
;
550 /* Extract the substring of the current demangling result that
551 represents the subsitution candidate. */
552 if (!dyn_string_substring (substitution
,
553 result
, start_position
, result_caret_pos (dm
)))
555 dyn_string_delete (substitution
);
556 return STATUS_ALLOCATION_FAILED
;
559 /* If there's no room for the new entry, grow the array. */
560 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
562 size_t new_array_size
;
563 if (dm
->substitutions_allocated
> 0)
564 dm
->substitutions_allocated
*= 2;
566 dm
->substitutions_allocated
= 2;
568 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
570 dm
->substitutions
= (struct substitution_def
*)
571 realloc (dm
->substitutions
, new_array_size
);
572 if (dm
->substitutions
== NULL
)
573 /* Realloc failed. */
575 dyn_string_delete (substitution
);
576 return STATUS_ALLOCATION_FAILED
;
580 /* Add the substitution to the array. */
581 i
= dm
->num_substitutions
++;
582 dm
->substitutions
[i
].text
= substitution
;
583 dm
->substitutions
[i
].template_p
= template_p
;
585 #ifdef CP_DEMANGLE_DEBUG
586 substitutions_print (dm
, stderr
);
592 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
593 non-zero if the substitution is a template-id, zero otherwise.
594 N is numbered from zero. DM retains ownership of the returned
595 string. If N is negative, or equal to or greater than the current
596 number of substitution candidates, returns NULL. */
599 substitution_get (dm
, n
, template_p
)
604 struct substitution_def
*sub
;
606 /* Make sure N is in the valid range. */
607 if (n
< 0 || n
>= dm
->num_substitutions
)
610 sub
= &(dm
->substitutions
[n
]);
611 *template_p
= sub
->template_p
;
615 #ifdef CP_DEMANGLE_DEBUG
616 /* Debugging routine to print the current substitutions to FP. */
619 substitutions_print (dm
, fp
)
624 int num
= dm
->num_substitutions
;
626 fprintf (fp
, "SUBSTITUTIONS:\n");
627 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
630 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
633 fprintf (fp
, " S_ ");
635 fprintf (fp
, " S%d_", seq_id
);
636 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
640 #endif /* CP_DEMANGLE_DEBUG */
642 /* Creates a new template argument list. Returns NULL if allocation
645 static template_arg_list_t
646 template_arg_list_new ()
648 template_arg_list_t new_list
=
649 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
650 if (new_list
== NULL
)
652 /* Initialize the new list to have no arguments. */
653 new_list
->first_argument
= NULL
;
654 new_list
->last_argument
= NULL
;
655 /* Return the new list. */
659 /* Deletes a template argument list and the template arguments it
663 template_arg_list_delete (list
)
664 template_arg_list_t list
;
666 /* If there are any arguments on LIST, delete them. */
667 if (list
->first_argument
!= NULL
)
668 string_list_delete (list
->first_argument
);
673 /* Adds ARG to the template argument list ARG_LIST. */
676 template_arg_list_add_arg (arg_list
, arg
)
677 template_arg_list_t arg_list
;
680 if (arg_list
->first_argument
== NULL
)
681 /* If there were no arguments before, ARG is the first one. */
682 arg_list
->first_argument
= arg
;
684 /* Make ARG the last argument on the list. */
685 arg_list
->last_argument
->next
= arg
;
686 /* Make ARG the last on the list. */
687 arg_list
->last_argument
= arg
;
691 /* Returns the template arugment at position INDEX in template
692 argument list ARG_LIST. */
695 template_arg_list_get_arg (arg_list
, index
)
696 template_arg_list_t arg_list
;
699 string_list_t arg
= arg_list
->first_argument
;
700 /* Scan down the list of arguments to find the one at position
706 /* Ran out of arguments before INDEX hit zero. That's an
710 /* Return the argument at position INDEX. */
714 /* Pushes ARG_LIST onto the top of the template argument list stack. */
717 push_template_arg_list (dm
, arg_list
)
719 template_arg_list_t arg_list
;
721 arg_list
->next
= dm
->template_arg_lists
;
722 dm
->template_arg_lists
= arg_list
;
723 #ifdef CP_DEMANGLE_DEBUG
724 fprintf (stderr
, " ** pushing template arg list\n");
725 template_arg_list_print (arg_list
, stderr
);
729 /* Pops and deletes elements on the template argument list stack until
730 arg_list is the topmost element. If arg_list is NULL, all elements
731 are popped and deleted. */
734 pop_to_template_arg_list (dm
, arg_list
)
736 template_arg_list_t arg_list
;
738 while (dm
->template_arg_lists
!= arg_list
)
740 template_arg_list_t top
= dm
->template_arg_lists
;
741 /* Disconnect the topmost element from the list. */
742 dm
->template_arg_lists
= top
->next
;
743 /* Delete the popped element. */
744 template_arg_list_delete (top
);
745 #ifdef CP_DEMANGLE_DEBUG
746 fprintf (stderr
, " ** removing template arg list\n");
751 #ifdef CP_DEMANGLE_DEBUG
753 /* Prints the contents of ARG_LIST to FP. */
756 template_arg_list_print (arg_list
, fp
)
757 template_arg_list_t arg_list
;
763 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
764 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
767 fprintf (fp
, " T_ : ");
769 fprintf (fp
, " T%d_ : ", index
);
771 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
775 #endif /* CP_DEMANGLE_DEBUG */
777 /* Returns the topmost element on the stack of template argument
778 lists. If there is no list of template arguments, returns NULL. */
780 static template_arg_list_t
781 current_template_arg_list (dm
)
784 return dm
->template_arg_lists
;
787 /* Allocates a demangling_t object for demangling mangled NAME. A new
788 result must be pushed before the returned object can be used.
789 Returns NULL if allocation fails. */
792 demangling_new (name
, style
)
797 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
804 dm
->num_substitutions
= 0;
805 dm
->substitutions_allocated
= 10;
806 dm
->template_arg_lists
= NULL
;
807 dm
->last_source_name
= dyn_string_new (0);
808 if (dm
->last_source_name
== NULL
)
810 dm
->substitutions
= (struct substitution_def
*)
811 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
812 if (dm
->substitutions
== NULL
)
814 dyn_string_delete (dm
->last_source_name
);
822 /* Deallocates a demangling_t object and all memory associated with
826 demangling_delete (dm
)
830 template_arg_list_t arg_list
= dm
->template_arg_lists
;
832 /* Delete the stack of template argument lists. */
833 while (arg_list
!= NULL
)
835 template_arg_list_t next
= arg_list
->next
;
836 template_arg_list_delete (arg_list
);
839 /* Delete the list of substitutions. */
840 for (i
= dm
->num_substitutions
; --i
>= 0; )
841 dyn_string_delete (dm
->substitutions
[i
].text
);
842 free (dm
->substitutions
);
843 /* Delete the demangled result. */
844 string_list_delete (dm
->result
);
845 /* Delete the stored identifier name. */
846 dyn_string_delete (dm
->last_source_name
);
847 /* Delete the context object itself. */
851 /* These functions demangle an alternative of the corresponding
852 production in the mangling spec. The first argument of each is a
853 demangling context structure for the current demangling
854 operation. Most emit demangled text directly to the topmost result
855 string on the result string stack in the demangling context
858 static status_t demangle_char
859 PARAMS ((demangling_t
, int));
860 static status_t demangle_mangled_name
861 PARAMS ((demangling_t
));
862 static status_t demangle_encoding
863 PARAMS ((demangling_t
));
864 static status_t demangle_name
865 PARAMS ((demangling_t
, int *));
866 static status_t demangle_nested_name
867 PARAMS ((demangling_t
, int *));
868 static status_t demangle_prefix
869 PARAMS ((demangling_t
, int *));
870 static status_t demangle_unqualified_name
871 PARAMS ((demangling_t
, int *));
872 static status_t demangle_source_name
873 PARAMS ((demangling_t
));
874 static status_t demangle_number
875 PARAMS ((demangling_t
, int *, int, int));
876 static status_t demangle_number_literally
877 PARAMS ((demangling_t
, dyn_string_t
, int, int));
878 static status_t demangle_identifier
879 PARAMS ((demangling_t
, int, dyn_string_t
));
880 static status_t demangle_operator_name
881 PARAMS ((demangling_t
, int, int *));
882 static status_t demangle_nv_offset
883 PARAMS ((demangling_t
));
884 static status_t demangle_v_offset
885 PARAMS ((demangling_t
));
886 static status_t demangle_call_offset
887 PARAMS ((demangling_t
));
888 static status_t demangle_special_name
889 PARAMS ((demangling_t
));
890 static status_t demangle_ctor_dtor_name
891 PARAMS ((demangling_t
));
892 static status_t demangle_type_ptr
893 PARAMS ((demangling_t
, int *, int));
894 static status_t demangle_type
895 PARAMS ((demangling_t
));
896 static status_t demangle_CV_qualifiers
897 PARAMS ((demangling_t
, dyn_string_t
));
898 static status_t demangle_builtin_type
899 PARAMS ((demangling_t
));
900 static status_t demangle_function_type
901 PARAMS ((demangling_t
, int *));
902 static status_t demangle_bare_function_type
903 PARAMS ((demangling_t
, int *));
904 static status_t demangle_class_enum_type
905 PARAMS ((demangling_t
, int *));
906 static status_t demangle_array_type
907 PARAMS ((demangling_t
, int *));
908 static status_t demangle_template_param
909 PARAMS ((demangling_t
));
910 static status_t demangle_template_args
911 PARAMS ((demangling_t
));
912 static status_t demangle_literal
913 PARAMS ((demangling_t
));
914 static status_t demangle_template_arg
915 PARAMS ((demangling_t
));
916 static status_t demangle_expression
917 PARAMS ((demangling_t
));
918 static status_t demangle_scope_expression
919 PARAMS ((demangling_t
));
920 static status_t demangle_expr_primary
921 PARAMS ((demangling_t
));
922 static status_t demangle_substitution
923 PARAMS ((demangling_t
, int *));
924 static status_t demangle_local_name
925 PARAMS ((demangling_t
));
926 static status_t demangle_discriminator
927 PARAMS ((demangling_t
, int));
928 static status_t cp_demangle
929 PARAMS ((const char *, dyn_string_t
, int));
931 static status_t cp_demangle_type
932 PARAMS ((const char*, dyn_string_t
));
935 /* When passed to demangle_bare_function_type, indicates that the
936 function's return type is not encoded before its parameter types. */
937 #define BFT_NO_RETURN_TYPE NULL
939 /* Check that the next character is C. If so, consume it. If not,
943 demangle_char (dm
, c
)
947 static char *error_message
= NULL
;
949 if (peek_char (dm
) == c
)
956 if (error_message
== NULL
)
957 error_message
= strdup ("Expected ?");
958 error_message
[9] = c
;
959 return error_message
;
963 /* Demangles and emits a <mangled-name>.
965 <mangled-name> ::= _Z <encoding> */
968 demangle_mangled_name (dm
)
971 DEMANGLE_TRACE ("mangled-name", dm
);
972 RETURN_IF_ERROR (demangle_char (dm
, '_'));
973 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
974 RETURN_IF_ERROR (demangle_encoding (dm
));
978 /* Demangles and emits an <encoding>.
980 <encoding> ::= <function name> <bare-function-type>
982 ::= <special-name> */
985 demangle_encoding (dm
)
988 int encode_return_type
;
990 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
991 char peek
= peek_char (dm
);
993 DEMANGLE_TRACE ("encoding", dm
);
995 /* Remember where the name starts. If it turns out to be a template
996 function, we'll have to insert the return type here. */
997 start_position
= result_caret_pos (dm
);
999 if (peek
== 'G' || peek
== 'T')
1000 RETURN_IF_ERROR (demangle_special_name (dm
));
1003 /* Now demangle the name. */
1004 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
1006 /* If there's anything left, the name was a function name, with
1007 maybe its return type, and its parameter types, following. */
1008 if (!end_of_name_p (dm
)
1009 && peek_char (dm
) != 'E')
1011 if (encode_return_type
)
1012 /* Template functions have their return type encoded. The
1013 return type should be inserted at start_position. */
1015 (demangle_bare_function_type (dm
, &start_position
));
1017 /* Non-template functions don't have their return type
1020 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
1024 /* Pop off template argument lists that were built during the
1025 mangling of this name, to restore the old template context. */
1026 pop_to_template_arg_list (dm
, old_arg_list
);
1031 /* Demangles and emits a <name>.
1033 <name> ::= <unscoped-name>
1034 ::= <unscoped-template-name> <template-args>
1038 <unscoped-name> ::= <unqualified-name>
1039 ::= St <unqualified-name> # ::std::
1041 <unscoped-template-name>
1043 ::= <substitution> */
1046 demangle_name (dm
, encode_return_type
)
1048 int *encode_return_type
;
1050 int start
= substitution_start (dm
);
1051 char peek
= peek_char (dm
);
1052 int is_std_substitution
= 0;
1054 /* Generally, the return type is encoded if the function is a
1055 template-id, and suppressed otherwise. There are a few cases,
1056 though, in which the return type is not encoded even for a
1057 templated function. In these cases, this flag is set. */
1058 int suppress_return_type
= 0;
1060 DEMANGLE_TRACE ("name", dm
);
1065 /* This is a <nested-name>. */
1066 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1070 RETURN_IF_ERROR (demangle_local_name (dm
));
1071 *encode_return_type
= 0;
1075 /* The `St' substitution allows a name nested in std:: to appear
1076 without being enclosed in a nested name. */
1077 if (peek_char_next (dm
) == 't')
1079 (void) next_char (dm
);
1080 (void) next_char (dm
);
1081 RETURN_IF_ERROR (result_add (dm
, "std::"));
1083 (demangle_unqualified_name (dm
, &suppress_return_type
));
1084 is_std_substitution
= 1;
1087 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1088 /* Check if a template argument list immediately follows.
1089 If so, then we just demangled an <unqualified-template-name>. */
1090 if (peek_char (dm
) == 'I')
1092 /* A template name of the form std::<unqualified-name> is a
1093 substitution candidate. */
1094 if (is_std_substitution
)
1095 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1096 /* Demangle the <template-args> here. */
1097 RETURN_IF_ERROR (demangle_template_args (dm
));
1098 *encode_return_type
= !suppress_return_type
;
1101 *encode_return_type
= 0;
1106 /* This is an <unscoped-name> or <unscoped-template-name>. */
1107 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1109 /* If the <unqualified-name> is followed by template args, this
1110 is an <unscoped-template-name>. */
1111 if (peek_char (dm
) == 'I')
1113 /* Add a substitution for the unqualified template name. */
1114 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1116 RETURN_IF_ERROR (demangle_template_args (dm
));
1117 *encode_return_type
= !suppress_return_type
;
1120 *encode_return_type
= 0;
1128 /* Demangles and emits a <nested-name>.
1130 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1133 demangle_nested_name (dm
, encode_return_type
)
1135 int *encode_return_type
;
1139 DEMANGLE_TRACE ("nested-name", dm
);
1141 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1143 peek
= peek_char (dm
);
1144 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1146 dyn_string_t cv_qualifiers
;
1149 /* Snarf up CV qualifiers. */
1150 cv_qualifiers
= dyn_string_new (24);
1151 if (cv_qualifiers
== NULL
)
1152 return STATUS_ALLOCATION_FAILED
;
1153 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1155 /* Emit them, preceded by a space. */
1156 status
= result_add_char (dm
, ' ');
1157 if (STATUS_NO_ERROR (status
))
1158 status
= result_add_string (dm
, cv_qualifiers
);
1159 /* The CV qualifiers that occur in a <nested-name> will be
1160 qualifiers for member functions. These are placed at the end
1161 of the function. Therefore, shift the caret to the left by
1162 the length of the qualifiers, so other text is inserted
1163 before them and they stay at the end. */
1164 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
) - 1);
1166 dyn_string_delete (cv_qualifiers
);
1167 RETURN_IF_ERROR (status
);
1170 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1171 /* No need to demangle the final <unqualified-name>; demangle_prefix
1173 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1178 /* Demangles and emits a <prefix>.
1180 <prefix> ::= <prefix> <unqualified-name>
1181 ::= <template-prefix> <template-args>
1185 <template-prefix> ::= <prefix>
1186 ::= <substitution> */
1189 demangle_prefix (dm
, encode_return_type
)
1191 int *encode_return_type
;
1193 int start
= substitution_start (dm
);
1196 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1197 After <template-args>, it is set to non-zero; after everything
1198 else it is set to zero. */
1200 /* Generally, the return type is encoded if the function is a
1201 template-id, and suppressed otherwise. There are a few cases,
1202 though, in which the return type is not encoded even for a
1203 templated function. In these cases, this flag is set. */
1204 int suppress_return_type
= 0;
1206 DEMANGLE_TRACE ("prefix", dm
);
1212 if (end_of_name_p (dm
))
1213 return "Unexpected end of name in <compound-name>.";
1215 peek
= peek_char (dm
);
1217 /* We'll initialize suppress_return_type to false, and set it to true
1218 if we end up demangling a constructor name. However, make
1219 sure we're not actually about to demangle template arguments
1220 -- if so, this is the <template-args> following a
1221 <template-prefix>, so we'll want the previous flag value
1224 suppress_return_type
= 0;
1226 if (IS_DIGIT ((unsigned char) peek
)
1227 || (peek
>= 'a' && peek
<= 'z')
1228 || peek
== 'C' || peek
== 'D'
1231 /* We have another level of scope qualification. */
1233 RETURN_IF_ERROR (result_add (dm
, NAMESPACE_SEPARATOR
));
1238 /* The substitution determines whether this is a
1240 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1243 /* It's just a name. */
1245 (demangle_unqualified_name (dm
, &suppress_return_type
));
1246 *encode_return_type
= 0;
1249 else if (peek
== 'Z')
1250 RETURN_IF_ERROR (demangle_local_name (dm
));
1251 else if (peek
== 'I')
1253 RETURN_IF_ERROR (demangle_template_args (dm
));
1255 /* Now we want to indicate to the caller that we've
1256 demangled template arguments, thus the prefix was a
1257 <template-prefix>. That's so that the caller knows to
1258 demangle the function's return type, if this turns out to
1259 be a function name. But, if it's a member template
1260 constructor or a templated conversion operator, report it
1261 as untemplated. Those never get encoded return types. */
1262 *encode_return_type
= !suppress_return_type
;
1264 else if (peek
== 'E')
1268 return "Unexpected character in <compound-name>.";
1271 && peek_char (dm
) != 'E')
1272 /* Add a new substitution for the prefix thus far. */
1273 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1277 /* Demangles and emits an <unqualified-name>. If this
1278 <unqualified-name> is for a special function type that should never
1279 have its return type encoded (particularly, a constructor or
1280 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1283 <unqualified-name> ::= <operator-name>
1285 ::= <source-name> */
1288 demangle_unqualified_name (dm
, suppress_return_type
)
1290 int *suppress_return_type
;
1292 char peek
= peek_char (dm
);
1294 DEMANGLE_TRACE ("unqualified-name", dm
);
1296 /* By default, don't force suppression of the return type (though
1297 non-template functions still don't get a return type encoded). */
1298 *suppress_return_type
= 0;
1300 if (IS_DIGIT ((unsigned char) peek
))
1301 RETURN_IF_ERROR (demangle_source_name (dm
));
1302 else if (peek
>= 'a' && peek
<= 'z')
1306 /* Conversion operators never have a return type encoded. */
1307 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1308 *suppress_return_type
= 1;
1310 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1312 else if (peek
== 'C' || peek
== 'D')
1314 /* Constructors never have a return type encoded. */
1316 *suppress_return_type
= 1;
1318 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1321 return "Unexpected character in <unqualified-name>.";
1326 /* Demangles and emits <source-name>.
1328 <source-name> ::= <length number> <identifier> */
1331 demangle_source_name (dm
)
1336 DEMANGLE_TRACE ("source-name", dm
);
1338 /* Decode the length of the identifier. */
1339 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1341 return "Zero length in <source-name>.";
1343 /* Now the identifier itself. It's placed into last_source_name,
1344 where it can be used to build a constructor or destructor name. */
1345 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1346 dm
->last_source_name
));
1349 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
1354 /* Demangles a number, either a <number> or a <positive-number> at the
1355 current position, consuming all consecutive digit characters. Sets
1356 *VALUE to the resulting numberand returns STATUS_OK. The number is
1357 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1358 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1360 <number> ::= [n] <positive-number>
1362 <positive-number> ::= <decimal integer> */
1365 demangle_number (dm
, value
, base
, is_signed
)
1371 dyn_string_t number
= dyn_string_new (10);
1373 DEMANGLE_TRACE ("number", dm
);
1376 return STATUS_ALLOCATION_FAILED
;
1378 demangle_number_literally (dm
, number
, base
, is_signed
);
1379 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1380 dyn_string_delete (number
);
1385 /* Demangles a number at the current position. The digits (and minus
1386 sign, if present) that make up the number are appended to STR.
1387 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1388 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1389 accepted. Does not consume a trailing underscore or other
1390 terminating character. */
1393 demangle_number_literally (dm
, str
, base
, is_signed
)
1399 DEMANGLE_TRACE ("number*", dm
);
1401 if (base
!= 10 && base
!= 36)
1402 return STATUS_INTERNAL_ERROR
;
1404 /* An `n' denotes a negative number. */
1405 if (is_signed
&& peek_char (dm
) == 'n')
1407 /* Skip past the n. */
1409 /* The normal way to write a negative number is with a minus
1411 if (!dyn_string_append_char (str
, '-'))
1412 return STATUS_ALLOCATION_FAILED
;
1415 /* Loop until we hit a non-digit. */
1418 char peek
= peek_char (dm
);
1419 if (IS_DIGIT ((unsigned char) peek
)
1420 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1422 /* Accumulate digits. */
1423 if (!dyn_string_append_char (str
, next_char (dm
)))
1424 return STATUS_ALLOCATION_FAILED
;
1427 /* Not a digit? All done. */
1434 /* Demangles an identifier at the current position of LENGTH
1435 characters and places it in IDENTIFIER. */
1438 demangle_identifier (dm
, length
, identifier
)
1441 dyn_string_t identifier
;
1443 DEMANGLE_TRACE ("identifier", dm
);
1445 dyn_string_clear (identifier
);
1446 if (!dyn_string_resize (identifier
, length
))
1447 return STATUS_ALLOCATION_FAILED
;
1449 while (length
-- > 0)
1451 if (end_of_name_p (dm
))
1452 return "Unexpected end of name in <identifier>.";
1453 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1454 return STATUS_ALLOCATION_FAILED
;
1457 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1458 followed by the source file name and some random characters.
1459 Unless we're in strict mode, decipher these names appropriately. */
1462 char *name
= dyn_string_buf (identifier
);
1463 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1465 /* Compare the first, fixed part. */
1466 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1468 name
+= prefix_length
;
1469 /* The next character might be a period, an underscore, or
1470 dollar sign, depending on the target architecture's
1471 assembler's capabilities. After that comes an `N'. */
1472 if ((*name
== '.' || *name
== '_' || *name
== '$')
1473 && *(name
+ 1) == 'N')
1474 /* This looks like the anonymous namespace identifier.
1475 Replace it with something comprehensible. */
1476 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1483 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1484 the short form is emitted; otherwise the full source form
1485 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1486 operands that the operator takes.
1537 ::= cv <type> # cast
1538 ::= v [0-9] <source-name> # vendor extended operator */
1541 demangle_operator_name (dm
, short_name
, num_args
)
1546 struct operator_code
1548 /* The mangled code for this operator. */
1550 /* The source name of this operator. */
1552 /* The number of arguments this operator takes. */
1556 static const struct operator_code operators
[] =
1567 { "da", " delete[]", 1 },
1569 { "dl", " delete" , 1 },
1577 { "lS", "<<=" , 2 },
1586 { "na", " new[]" , 1 },
1590 { "nw", " new" , 1 },
1596 { "pm", "->*" , 2 },
1602 { "rS", ">>=" , 2 },
1605 { "sz", " sizeof" , 1 }
1608 const int num_operators
=
1609 sizeof (operators
) / sizeof (struct operator_code
);
1611 int c0
= next_char (dm
);
1612 int c1
= next_char (dm
);
1613 const struct operator_code
* p1
= operators
;
1614 const struct operator_code
* p2
= operators
+ num_operators
;
1616 DEMANGLE_TRACE ("operator-name", dm
);
1618 /* Is this a vendor-extended operator? */
1619 if (c0
== 'v' && IS_DIGIT (c1
))
1621 RETURN_IF_ERROR (result_add (dm
, "operator "));
1622 RETURN_IF_ERROR (demangle_source_name (dm
));
1627 /* Is this a conversion operator? */
1628 if (c0
== 'c' && c1
== 'v')
1630 RETURN_IF_ERROR (result_add (dm
, "operator "));
1631 /* Demangle the converted-to type. */
1632 RETURN_IF_ERROR (demangle_type (dm
));
1637 /* Perform a binary search for the operator code. */
1640 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1641 char match0
= p
->code
[0];
1642 char match1
= p
->code
[1];
1644 if (c0
== match0
&& c1
== match1
)
1648 RETURN_IF_ERROR (result_add (dm
, "operator"));
1649 RETURN_IF_ERROR (result_add (dm
, p
->name
));
1650 *num_args
= p
->num_args
;
1656 /* Couldn't find it. */
1657 return "Unknown code in <operator-name>.";
1660 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1667 /* Demangles and omits an <nv-offset>.
1669 <nv-offset> ::= <offset number> # non-virtual base override */
1672 demangle_nv_offset (dm
)
1675 dyn_string_t number
;
1676 status_t status
= STATUS_OK
;
1678 DEMANGLE_TRACE ("h-offset", dm
);
1680 /* Demangle the offset. */
1681 number
= dyn_string_new (4);
1683 return STATUS_ALLOCATION_FAILED
;
1684 demangle_number_literally (dm
, number
, 10, 1);
1686 /* Don't display the offset unless in verbose mode. */
1689 status
= result_add (dm
, " [nv:");
1690 if (STATUS_NO_ERROR (status
))
1691 status
= result_add_string (dm
, number
);
1692 if (STATUS_NO_ERROR (status
))
1693 status
= result_add_char (dm
, ']');
1697 dyn_string_delete (number
);
1698 RETURN_IF_ERROR (status
);
1702 /* Demangles and emits a <v-offset>.
1704 <v-offset> ::= <offset number> _ <virtual offset number>
1705 # virtual base override, with vcall offset */
1708 demangle_v_offset (dm
)
1711 dyn_string_t number
;
1712 status_t status
= STATUS_OK
;
1714 DEMANGLE_TRACE ("v-offset", dm
);
1716 /* Demangle the offset. */
1717 number
= dyn_string_new (4);
1719 return STATUS_ALLOCATION_FAILED
;
1720 demangle_number_literally (dm
, number
, 10, 1);
1722 /* Don't display the offset unless in verbose mode. */
1725 status
= result_add (dm
, " [v:");
1726 if (STATUS_NO_ERROR (status
))
1727 status
= result_add_string (dm
, number
);
1728 if (STATUS_NO_ERROR (status
))
1729 result_add_char (dm
, ',');
1731 dyn_string_delete (number
);
1732 RETURN_IF_ERROR (status
);
1734 /* Demangle the separator. */
1735 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1737 /* Demangle the vcall offset. */
1738 number
= dyn_string_new (4);
1740 return STATUS_ALLOCATION_FAILED
;
1741 demangle_number_literally (dm
, number
, 10, 1);
1743 /* Don't display the vcall offset unless in verbose mode. */
1746 status
= result_add_string (dm
, number
);
1747 if (STATUS_NO_ERROR (status
))
1748 status
= result_add_char (dm
, ']');
1750 dyn_string_delete (number
);
1751 RETURN_IF_ERROR (status
);
1756 /* Demangles and emits a <call-offset>.
1758 <call-offset> ::= h <nv-offset> _
1759 ::= v <v-offset> _ */
1762 demangle_call_offset (dm
)
1765 DEMANGLE_TRACE ("call-offset", dm
);
1767 switch (peek_char (dm
))
1771 /* Demangle the offset. */
1772 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1773 /* Demangle the separator. */
1774 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1779 /* Demangle the offset. */
1780 RETURN_IF_ERROR (demangle_v_offset (dm
));
1781 /* Demangle the separator. */
1782 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1786 return "Unrecognized <call-offset>.";
1792 /* Demangles and emits a <special-name>.
1794 <special-name> ::= GV <object name> # Guard variable
1795 ::= TV <type> # virtual table
1797 ::= TI <type> # typeinfo structure
1798 ::= TS <type> # typeinfo name
1800 Other relevant productions include thunks:
1802 <special-name> ::= T <call-offset> <base encoding>
1803 # base is the nominal target function of thunk
1805 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1806 # base is the nominal target function of thunk
1807 # first call-offset is 'this' adjustment
1808 # second call-offset is result adjustment
1812 <call-offset> ::= h <nv-offset> _
1815 Also demangles the special g++ manglings,
1817 <special-name> ::= TC <type> <offset number> _ <base type>
1818 # construction vtable
1819 ::= TF <type> # typeinfo function (old ABI only)
1820 ::= TJ <type> # java Class structure */
1823 demangle_special_name (dm
)
1826 dyn_string_t number
;
1828 char peek
= peek_char (dm
);
1830 DEMANGLE_TRACE ("special-name", dm
);
1834 /* A guard variable name. Consume the G. */
1836 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1837 RETURN_IF_ERROR (result_add (dm
, "guard variable for "));
1838 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1840 else if (peek
== 'T')
1842 status_t status
= STATUS_OK
;
1844 /* Other C++ implementation miscellania. Consume the T. */
1847 switch (peek_char (dm
))
1850 /* Virtual table. */
1852 RETURN_IF_ERROR (result_add (dm
, "vtable for "));
1853 RETURN_IF_ERROR (demangle_type (dm
));
1857 /* VTT structure. */
1859 RETURN_IF_ERROR (result_add (dm
, "VTT for "));
1860 RETURN_IF_ERROR (demangle_type (dm
));
1864 /* Typeinfo structure. */
1866 RETURN_IF_ERROR (result_add (dm
, "typeinfo for "));
1867 RETURN_IF_ERROR (demangle_type (dm
));
1871 /* Typeinfo function. Used only in old ABI with new mangling. */
1873 RETURN_IF_ERROR (result_add (dm
, "typeinfo fn for "));
1874 RETURN_IF_ERROR (demangle_type (dm
));
1878 /* Character string containing type name, used in typeinfo. */
1880 RETURN_IF_ERROR (result_add (dm
, "typeinfo name for "));
1881 RETURN_IF_ERROR (demangle_type (dm
));
1885 /* The java Class variable corresponding to a C++ class. */
1887 RETURN_IF_ERROR (result_add (dm
, "java Class for "));
1888 RETURN_IF_ERROR (demangle_type (dm
));
1892 /* Non-virtual thunk. */
1894 RETURN_IF_ERROR (result_add (dm
, "non-virtual thunk"));
1895 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1896 /* Demangle the separator. */
1897 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1898 /* Demangle and emit the target name and function type. */
1899 RETURN_IF_ERROR (result_add (dm
, " to "));
1900 RETURN_IF_ERROR (demangle_encoding (dm
));
1904 /* Virtual thunk. */
1906 RETURN_IF_ERROR (result_add (dm
, "virtual thunk"));
1907 RETURN_IF_ERROR (demangle_v_offset (dm
));
1908 /* Demangle the separator. */
1909 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1910 /* Demangle and emit the target function. */
1911 RETURN_IF_ERROR (result_add (dm
, " to "));
1912 RETURN_IF_ERROR (demangle_encoding (dm
));
1916 /* Covariant return thunk. */
1918 RETURN_IF_ERROR (result_add (dm
, "covariant return thunk"));
1919 RETURN_IF_ERROR (demangle_call_offset (dm
));
1920 RETURN_IF_ERROR (demangle_call_offset (dm
));
1921 /* Demangle and emit the target function. */
1922 RETURN_IF_ERROR (result_add (dm
, " to "));
1923 RETURN_IF_ERROR (demangle_encoding (dm
));
1927 /* TC is a special g++ mangling for a construction vtable. */
1930 dyn_string_t derived_type
;
1933 RETURN_IF_ERROR (result_add (dm
, "construction vtable for "));
1935 /* Demangle the derived type off to the side. */
1936 RETURN_IF_ERROR (result_push (dm
));
1937 RETURN_IF_ERROR (demangle_type (dm
));
1938 derived_type
= (dyn_string_t
) result_pop (dm
);
1940 /* Demangle the offset. */
1941 number
= dyn_string_new (4);
1944 dyn_string_delete (derived_type
);
1945 return STATUS_ALLOCATION_FAILED
;
1947 demangle_number_literally (dm
, number
, 10, 1);
1948 /* Demangle the underscore separator. */
1949 status
= demangle_char (dm
, '_');
1951 /* Demangle the base type. */
1952 if (STATUS_NO_ERROR (status
))
1953 status
= demangle_type (dm
);
1955 /* Emit the derived type. */
1956 if (STATUS_NO_ERROR (status
))
1957 status
= result_add (dm
, "-in-");
1958 if (STATUS_NO_ERROR (status
))
1959 status
= result_add_string (dm
, derived_type
);
1960 dyn_string_delete (derived_type
);
1962 /* Don't display the offset unless in verbose mode. */
1965 status
= result_add_char (dm
, ' ');
1966 if (STATUS_NO_ERROR (status
))
1967 result_add_string (dm
, number
);
1969 dyn_string_delete (number
);
1970 RETURN_IF_ERROR (status
);
1973 /* If flag_strict, fall through. */
1976 return "Unrecognized <special-name>.";
1980 return STATUS_ERROR
;
1985 /* Demangles and emits a <ctor-dtor-name>.
1988 ::= C1 # complete object (in-charge) ctor
1989 ::= C2 # base object (not-in-charge) ctor
1990 ::= C3 # complete object (in-charge) allocating ctor
1991 ::= D0 # deleting (in-charge) dtor
1992 ::= D1 # complete object (in-charge) dtor
1993 ::= D2 # base object (not-in-charge) dtor */
1996 demangle_ctor_dtor_name (dm
)
1999 static const char *const ctor_flavors
[] =
2005 static const char *const dtor_flavors
[] =
2007 "in-charge deleting",
2013 char peek
= peek_char (dm
);
2015 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
2019 /* A constructor name. Consume the C. */
2021 if (peek_char (dm
) < '1' || peek_char (dm
) > '3')
2022 return "Unrecognized constructor.";
2023 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2024 /* Print the flavor of the constructor if in verbose mode. */
2025 flavor
= next_char (dm
) - '1';
2028 RETURN_IF_ERROR (result_add (dm
, "["));
2029 RETURN_IF_ERROR (result_add (dm
, ctor_flavors
[flavor
]));
2030 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2033 else if (peek
== 'D')
2035 /* A destructor name. Consume the D. */
2037 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
2038 return "Unrecognized destructor.";
2039 RETURN_IF_ERROR (result_add_char (dm
, '~'));
2040 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2041 /* Print the flavor of the destructor if in verbose mode. */
2042 flavor
= next_char (dm
) - '0';
2045 RETURN_IF_ERROR (result_add (dm
, " ["));
2046 RETURN_IF_ERROR (result_add (dm
, dtor_flavors
[flavor
]));
2047 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2051 return STATUS_ERROR
;
2056 /* Handle pointer, reference, and pointer-to-member cases for
2057 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2058 build a pointer/reference type. We snarf all these, plus the
2059 following <type>, all at once since we need to know whether we have
2060 a pointer to data or pointer to function to construct the right
2061 output syntax. C++'s pointer syntax is hairy.
2063 This function adds substitution candidates for every nested
2064 pointer/reference type it processes, including the outermost, final
2065 type, assuming the substitution starts at SUBSTITUTION_START in the
2066 demangling result. For example, if this function demangles
2067 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2068 `Foo**', in that order.
2070 *INSERT_POS is a quantity used internally, when this function calls
2071 itself recursively, to figure out where to insert pointer
2072 punctuation on the way up. On entry to this function, INSERT_POS
2073 should point to a temporary value, but that value need not be
2078 ::= <pointer-to-member-type>
2080 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2083 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2086 int substitution_start
;
2089 int is_substitution_candidate
= 1;
2091 DEMANGLE_TRACE ("type*", dm
);
2093 /* Scan forward, collecting pointers and references into symbols,
2094 until we hit something else. Then emit the type. */
2095 switch (peek_char (dm
))
2098 /* A pointer. Snarf the `P'. */
2100 /* Demangle the underlying type. */
2101 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2102 substitution_start
));
2103 /* Insert an asterisk where we're told to; it doesn't
2104 necessarily go at the end. If we're doing Java style output,
2105 there is no pointer symbol. */
2106 if (dm
->style
!= DMGL_JAVA
)
2107 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2108 /* The next (outermost) pointer or reference character should go
2114 /* A reference. Snarf the `R'. */
2116 /* Demangle the underlying type. */
2117 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2118 substitution_start
));
2119 /* Insert an ampersand where we're told to; it doesn't
2120 necessarily go at the end. */
2121 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2122 /* The next (outermost) pointer or reference character should go
2129 /* A pointer-to-member. */
2130 dyn_string_t class_type
;
2135 /* Capture the type of which this is a pointer-to-member. */
2136 RETURN_IF_ERROR (result_push (dm
));
2137 RETURN_IF_ERROR (demangle_type (dm
));
2138 class_type
= (dyn_string_t
) result_pop (dm
);
2140 if (peek_char (dm
) == 'F')
2141 /* A pointer-to-member function. We want output along the
2142 lines of `void (C::*) (int, int)'. Demangle the function
2143 type, which would in this case give `void () (int, int)'
2144 and set *insert_pos to the spot between the first
2146 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2147 else if (peek_char (dm
) == 'A')
2148 /* A pointer-to-member array variable. We want output that
2149 looks like `int (Klass::*) [10]'. Demangle the array type
2150 as `int () [10]', and set *insert_pos to the spot between
2152 status
= demangle_array_type (dm
, insert_pos
);
2155 /* A pointer-to-member variable. Demangle the type of the
2156 pointed-to member. */
2157 status
= demangle_type (dm
);
2158 /* Make it pretty. */
2159 if (STATUS_NO_ERROR (status
)
2160 && !result_previous_char_is_space (dm
))
2161 status
= result_add_char (dm
, ' ');
2162 /* The pointer-to-member notation (e.g. `C::*') follows the
2164 *insert_pos
= result_caret_pos (dm
);
2167 /* Build the pointer-to-member notation. */
2168 if (STATUS_NO_ERROR (status
))
2169 status
= result_insert (dm
, *insert_pos
, "::*");
2170 if (STATUS_NO_ERROR (status
))
2171 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2172 /* There may be additional levels of (pointer or reference)
2173 indirection in this type. If so, the `*' and `&' should be
2174 added after the pointer-to-member notation (e.g. `C::*&' for
2175 a reference to a pointer-to-member of class C). */
2176 *insert_pos
+= dyn_string_length (class_type
) + 3;
2179 dyn_string_delete (class_type
);
2181 RETURN_IF_ERROR (status
);
2186 /* Ooh, tricky, a pointer-to-function. When we demangle the
2187 function type, the return type should go at the very
2189 *insert_pos
= result_caret_pos (dm
);
2190 /* The parentheses indicate this is a function pointer or
2192 RETURN_IF_ERROR (result_add (dm
, "()"));
2193 /* Now demangle the function type. The return type will be
2194 inserted before the `()', and the argument list will go after
2196 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2197 /* We should now have something along the lines of
2198 `void () (int, int)'. The pointer or reference characters
2199 have to inside the first set of parentheses. *insert_pos has
2200 already been updated to point past the end of the return
2201 type. Move it one character over so it points inside the
2207 /* An array pointer or reference. demangle_array_type will figure
2208 out where the asterisks and ampersands go. */
2209 RETURN_IF_ERROR (demangle_array_type (dm
, insert_pos
));
2213 /* No more pointer or reference tokens; this is therefore a
2214 pointer to data. Finish up by demangling the underlying
2216 RETURN_IF_ERROR (demangle_type (dm
));
2217 /* The pointer or reference characters follow the underlying
2218 type, as in `int*&'. */
2219 *insert_pos
= result_caret_pos (dm
);
2220 /* Because of the production <type> ::= <substitution>,
2221 demangle_type will already have added the underlying type as
2222 a substitution candidate. Don't do it again. */
2223 is_substitution_candidate
= 0;
2227 if (is_substitution_candidate
)
2228 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2233 /* Demangles and emits a <type>.
2235 <type> ::= <builtin-type>
2237 ::= <class-enum-type>
2239 ::= <pointer-to-member-type>
2240 ::= <template-param>
2241 ::= <template-template-param> <template-args>
2242 ::= <CV-qualifiers> <type>
2243 ::= P <type> # pointer-to
2244 ::= R <type> # reference-to
2245 ::= C <type> # complex pair (C 2000)
2246 ::= G <type> # imaginary (C 2000)
2247 ::= U <source-name> <type> # vendor extended type qualifier
2248 ::= <substitution> */
2254 int start
= substitution_start (dm
);
2255 char peek
= peek_char (dm
);
2257 int encode_return_type
= 0;
2258 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2261 /* A <type> can be a <substitution>; therefore, this <type> is a
2262 substitution candidate unless a special condition holds (see
2264 int is_substitution_candidate
= 1;
2266 DEMANGLE_TRACE ("type", dm
);
2268 /* A <class-enum-type> can start with a digit (a <source-name>), an
2269 N (a <nested-name>), or a Z (a <local-name>). */
2270 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2271 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2272 /* Lower-case letters begin <builtin-type>s, except for `r', which
2273 denotes restrict. */
2274 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2276 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2277 /* Built-in types are not substitution candidates. */
2278 is_substitution_candidate
= 0;
2286 /* CV-qualifiers (including restrict). We have to demangle
2287 them off to the side, since C++ syntax puts them in a funny
2288 place for qualified pointer and reference types. */
2291 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2292 int old_caret_position
= result_get_caret (dm
);
2294 if (cv_qualifiers
== NULL
)
2295 return STATUS_ALLOCATION_FAILED
;
2297 /* Decode all adjacent CV qualifiers. */
2298 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2299 /* Emit them, and shift the caret left so that the
2300 underlying type will be emitted before the qualifiers. */
2301 status
= result_add_string (dm
, cv_qualifiers
);
2302 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2304 dyn_string_delete (cv_qualifiers
);
2305 RETURN_IF_ERROR (status
);
2306 /* Also prepend a blank, if needed. */
2307 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2308 result_shift_caret (dm
, -1);
2310 /* Demangle the underlying type. It will be emitted before
2311 the CV qualifiers, since we moved the caret. */
2312 RETURN_IF_ERROR (demangle_type (dm
));
2314 /* Put the caret back where it was previously. */
2315 result_set_caret (dm
, old_caret_position
);
2320 return "Non-pointer or -reference function type.";
2323 RETURN_IF_ERROR (demangle_array_type (dm
, NULL
));
2327 /* It's either a <template-param> or a
2328 <template-template-param>. In either case, demangle the
2330 RETURN_IF_ERROR (demangle_template_param (dm
));
2332 /* Check for a template argument list; if one is found, it's a
2333 <template-template-param> ::= <template-param>
2334 ::= <substitution> */
2335 if (peek_char (dm
) == 'I')
2337 /* Add a substitution candidate. The template parameter
2338 `T' token is a substitution candidate by itself,
2339 without the template argument list. */
2340 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2342 /* Now demangle the template argument list. */
2343 RETURN_IF_ERROR (demangle_template_args (dm
));
2344 /* The entire type, including the template template
2345 parameter and its argument list, will be added as a
2346 substitution candidate below. */
2352 /* First check if this is a special substitution. If it is,
2353 this is a <class-enum-type>. Special substitutions have a
2354 letter following the `S'; other substitutions have a digit
2356 peek_next
= peek_char_next (dm
);
2357 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2359 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2361 /* The substituted name may have been a template name.
2362 Check if template arguments follow, and if so, demangle
2364 if (peek_char (dm
) == 'I')
2365 RETURN_IF_ERROR (demangle_template_args (dm
));
2367 /* A substitution token is not itself a substitution
2368 candidate. (However, if the substituted template is
2369 instantiated, the resulting type is.) */
2370 is_substitution_candidate
= 0;
2374 /* Now some trickiness. We have a special substitution
2375 here. Often, the special substitution provides the
2376 name of a template that's subsequently instantiated,
2377 for instance `SaIcE' => std::allocator<char>. In these
2378 cases we need to add a substitution candidate for the
2379 entire <class-enum-type> and thus don't want to clear
2380 the is_substitution_candidate flag.
2382 However, it's possible that what we have here is a
2383 substitution token representing an entire type, such as
2384 `Ss' => std::string. In this case, we mustn't add a
2385 new substitution candidate for this substitution token.
2386 To detect this case, remember where the start of the
2387 substitution token is. */
2388 const char *next
= dm
->next
;
2389 /* Now demangle the <class-enum-type>. */
2391 (demangle_class_enum_type (dm
, &encode_return_type
));
2392 /* If all that was just demangled is the two-character
2393 special substitution token, supress the addition of a
2394 new candidate for it. */
2395 if (dm
->next
== next
+ 2)
2396 is_substitution_candidate
= 0;
2404 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2405 /* demangle_type_ptr adds all applicable substitution
2407 is_substitution_candidate
= 0;
2411 /* A C99 complex type. */
2412 RETURN_IF_ERROR (result_add (dm
, "complex "));
2414 RETURN_IF_ERROR (demangle_type (dm
));
2418 /* A C99 imaginary type. */
2419 RETURN_IF_ERROR (result_add (dm
, "imaginary "));
2421 RETURN_IF_ERROR (demangle_type (dm
));
2425 /* Vendor-extended type qualifier. */
2427 RETURN_IF_ERROR (demangle_source_name (dm
));
2428 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2429 RETURN_IF_ERROR (demangle_type (dm
));
2433 return "Unexpected character in <type>.";
2436 if (is_substitution_candidate
)
2437 /* Add a new substitution for the type. If this type was a
2438 <template-param>, pass its index since from the point of
2439 substitutions; a <template-param> token is a substitution
2440 candidate distinct from the type that is substituted for it. */
2441 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2443 /* Pop off template argument lists added during mangling of this
2445 pop_to_template_arg_list (dm
, old_arg_list
);
2450 /* C++ source names of builtin types, indexed by the mangled code
2451 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2452 static const char *const builtin_type_names
[26] =
2454 "signed char", /* a */
2458 "long double", /* e */
2460 "__float128", /* g */
2461 "unsigned char", /* h */
2466 "unsigned long", /* m */
2468 "unsigned __int128", /* o */
2473 "unsigned short", /* t */
2477 "long long", /* x */
2478 "unsigned long long", /* y */
2482 /* Java source names of builtin types. Types that arn't valid in Java
2483 are also included here - we don't fail if someone attempts to demangle a
2484 C++ symbol in Java style. */
2485 static const char *const java_builtin_type_names
[26] =
2487 "signed char", /* a */
2488 "boolean", /* C++ "bool" */ /* b */
2489 "byte", /* C++ "char" */ /* c */
2491 "long double", /* e */
2493 "__float128", /* g */
2494 "unsigned char", /* h */
2499 "unsigned long", /* m */
2501 "unsigned __int128", /* o */
2506 "unsigned short", /* t */
2509 "char", /* C++ "wchar_t" */ /* w */
2510 "long", /* C++ "long long" */ /* x */
2511 "unsigned long long", /* y */
2515 /* Demangles and emits a <builtin-type>.
2517 <builtin-type> ::= v # void
2522 ::= h # unsigned char
2524 ::= t # unsigned short
2526 ::= j # unsigned int
2528 ::= m # unsigned long
2529 ::= x # long long, __int64
2530 ::= y # unsigned long long, __int64
2532 ::= o # unsigned __int128
2535 ::= e # long double, __float80
2538 ::= u <source-name> # vendor extended type */
2541 demangle_builtin_type (dm
)
2545 char code
= peek_char (dm
);
2547 DEMANGLE_TRACE ("builtin-type", dm
);
2552 RETURN_IF_ERROR (demangle_source_name (dm
));
2555 else if (code
>= 'a' && code
<= 'z')
2557 const char *type_name
;
2558 /* Java uses different names for some built-in types. */
2559 if (dm
->style
== DMGL_JAVA
)
2560 type_name
= java_builtin_type_names
[code
- 'a'];
2562 type_name
= builtin_type_names
[code
- 'a'];
2563 if (type_name
== NULL
)
2564 return "Unrecognized <builtin-type> code.";
2566 RETURN_IF_ERROR (result_add (dm
, type_name
));
2571 return "Non-alphabetic <builtin-type> code.";
2574 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2575 restrict) at the current position. The qualifiers are appended to
2576 QUALIFIERS. Returns STATUS_OK. */
2579 demangle_CV_qualifiers (dm
, qualifiers
)
2581 dyn_string_t qualifiers
;
2583 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2587 switch (peek_char (dm
))
2590 if (!dyn_string_append_space (qualifiers
))
2591 return STATUS_ALLOCATION_FAILED
;
2592 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2593 return STATUS_ALLOCATION_FAILED
;
2597 if (!dyn_string_append_space (qualifiers
))
2598 return STATUS_ALLOCATION_FAILED
;
2599 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2600 return STATUS_ALLOCATION_FAILED
;
2604 if (!dyn_string_append_space (qualifiers
))
2605 return STATUS_ALLOCATION_FAILED
;
2606 if (!dyn_string_append_cstr (qualifiers
, "const"))
2607 return STATUS_ALLOCATION_FAILED
;
2618 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2619 position in the result string of the start of the function
2620 identifier, at which the function's return type will be inserted;
2621 *FUNCTION_NAME_POS is updated to position past the end of the
2622 function's return type.
2624 <function-type> ::= F [Y] <bare-function-type> E */
2627 demangle_function_type (dm
, function_name_pos
)
2629 int *function_name_pos
;
2631 DEMANGLE_TRACE ("function-type", dm
);
2632 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2633 if (peek_char (dm
) == 'Y')
2635 /* Indicate this function has C linkage if in verbose mode. */
2637 RETURN_IF_ERROR (result_add (dm
, " [extern \"C\"] "));
2640 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2641 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2645 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2646 position in the result string at which the function return type
2647 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2648 function's return type is assumed not to be encoded.
2650 <bare-function-type> ::= <signature type>+ */
2653 demangle_bare_function_type (dm
, return_type_pos
)
2655 int *return_type_pos
;
2657 /* Sequence is the index of the current function parameter, counting
2658 from zero. The value -1 denotes the return type. */
2660 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2662 DEMANGLE_TRACE ("bare-function-type", dm
);
2664 RETURN_IF_ERROR (result_add_char (dm
, '('));
2665 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2668 /* We're decoding the function's return type. */
2670 dyn_string_t return_type
;
2671 status_t status
= STATUS_OK
;
2673 /* Decode the return type off to the side. */
2674 RETURN_IF_ERROR (result_push (dm
));
2675 RETURN_IF_ERROR (demangle_type (dm
));
2676 return_type
= (dyn_string_t
) result_pop (dm
);
2678 /* Add a space to the end of the type. Insert the return
2679 type where we've been asked to. */
2680 if (!dyn_string_append_space (return_type
))
2681 status
= STATUS_ALLOCATION_FAILED
;
2682 if (STATUS_NO_ERROR (status
))
2684 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2686 status
= STATUS_ALLOCATION_FAILED
;
2688 *return_type_pos
+= dyn_string_length (return_type
);
2691 dyn_string_delete (return_type
);
2692 RETURN_IF_ERROR (status
);
2696 /* Skip `void' parameter types. One should only occur as
2697 the only type in a parameter list; in that case, we want
2698 to print `foo ()' instead of `foo (void)'. */
2699 if (peek_char (dm
) == 'v')
2700 /* Consume the v. */
2704 /* Separate parameter types by commas. */
2706 RETURN_IF_ERROR (result_add (dm
, ", "));
2707 /* Demangle the type. */
2708 RETURN_IF_ERROR (demangle_type (dm
));
2714 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2716 /* We should have demangled at least one parameter type (which would
2717 be void, for a function that takes no parameters), plus the
2718 return type, if we were supposed to demangle that. */
2720 return "Missing function return type.";
2721 else if (sequence
== 0)
2722 return "Missing function parameter.";
2727 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2728 non-zero if the type is a template-id, zero otherwise.
2730 <class-enum-type> ::= <name> */
2733 demangle_class_enum_type (dm
, encode_return_type
)
2735 int *encode_return_type
;
2737 DEMANGLE_TRACE ("class-enum-type", dm
);
2739 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2743 /* Demangles and emits an <array-type>.
2745 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2746 pointer or reference to an array, except that asterisk and
2747 ampersand punctuation is omitted (since it's not know at this
2748 point). *PTR_INSERT_POS is set to the position in the demangled
2749 name at which this punctuation should be inserted. For example,
2750 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2751 between the parentheses.
2753 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2754 pointer- or reference-qualified. Then, for example, `A10_i' is
2755 demangled simply as `int[10]'.
2757 <array-type> ::= A [<dimension number>] _ <element type>
2758 ::= A <dimension expression> _ <element type> */
2761 demangle_array_type (dm
, ptr_insert_pos
)
2763 int *ptr_insert_pos
;
2765 status_t status
= STATUS_OK
;
2766 dyn_string_t array_size
= NULL
;
2769 DEMANGLE_TRACE ("array-type", dm
);
2771 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2773 /* Demangle the array size into array_size. */
2774 peek
= peek_char (dm
);
2776 /* Array bound is omitted. This is a C99-style VLA. */
2778 else if (IS_DIGIT (peek_char (dm
)))
2780 /* It looks like a constant array bound. */
2781 array_size
= dyn_string_new (10);
2782 if (array_size
== NULL
)
2783 return STATUS_ALLOCATION_FAILED
;
2784 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2788 /* Anything is must be an expression for a nont-constant array
2789 bound. This happens if the array type occurs in a template
2790 and the array bound references a template parameter. */
2791 RETURN_IF_ERROR (result_push (dm
));
2792 RETURN_IF_ERROR (demangle_expression (dm
));
2793 array_size
= (dyn_string_t
) result_pop (dm
);
2795 /* array_size may have been allocated by now, so we can't use
2796 RETURN_IF_ERROR until it's been deallocated. */
2798 /* Demangle the base type of the array. */
2799 if (STATUS_NO_ERROR (status
))
2800 status
= demangle_char (dm
, '_');
2801 if (STATUS_NO_ERROR (status
))
2802 status
= demangle_type (dm
);
2804 if (ptr_insert_pos
!= NULL
)
2806 /* This array is actually part of an pointer- or
2807 reference-to-array type. Format appropriately, except we
2808 don't know which and how much punctuation to use. */
2809 if (STATUS_NO_ERROR (status
))
2810 status
= result_add (dm
, " () ");
2811 /* Let the caller know where to insert the punctuation. */
2812 *ptr_insert_pos
= result_caret_pos (dm
) - 2;
2815 /* Emit the array dimension syntax. */
2816 if (STATUS_NO_ERROR (status
))
2817 status
= result_add_char (dm
, '[');
2818 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2819 status
= result_add_string (dm
, array_size
);
2820 if (STATUS_NO_ERROR (status
))
2821 status
= result_add_char (dm
, ']');
2822 if (array_size
!= NULL
)
2823 dyn_string_delete (array_size
);
2825 RETURN_IF_ERROR (status
);
2830 /* Demangles and emits a <template-param>.
2832 <template-param> ::= T_ # first template parameter
2833 ::= T <parameter-2 number> _ */
2836 demangle_template_param (dm
)
2840 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2843 DEMANGLE_TRACE ("template-param", dm
);
2845 /* Make sure there is a template argmust list in which to look up
2846 this parameter reference. */
2847 if (current_arg_list
== NULL
)
2848 return "Template parameter outside of template.";
2850 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2851 if (peek_char (dm
) == '_')
2855 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2858 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2860 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2862 /* parm_number exceeded the number of arguments in the current
2863 template argument list. */
2864 return "Template parameter number out of bounds.";
2865 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2870 /* Demangles and emits a <template-args>.
2872 <template-args> ::= I <template-arg>+ E */
2875 demangle_template_args (dm
)
2879 dyn_string_t old_last_source_name
;
2880 template_arg_list_t arg_list
= template_arg_list_new ();
2882 if (arg_list
== NULL
)
2883 return STATUS_ALLOCATION_FAILED
;
2885 /* Preserve the most recently demangled source name. */
2886 old_last_source_name
= dm
->last_source_name
;
2887 dm
->last_source_name
= dyn_string_new (0);
2889 DEMANGLE_TRACE ("template-args", dm
);
2891 if (dm
->last_source_name
== NULL
)
2892 return STATUS_ALLOCATION_FAILED
;
2894 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2895 RETURN_IF_ERROR (result_open_template_list (dm
));
2903 RETURN_IF_ERROR (result_add (dm
, ", "));
2905 /* Capture the template arg. */
2906 RETURN_IF_ERROR (result_push (dm
));
2907 RETURN_IF_ERROR (demangle_template_arg (dm
));
2908 arg
= result_pop (dm
);
2910 /* Emit it in the demangled name. */
2911 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2913 /* Save it for use in expanding <template-param>s. */
2914 template_arg_list_add_arg (arg_list
, arg
);
2916 while (peek_char (dm
) != 'E');
2917 /* Append the '>'. */
2918 RETURN_IF_ERROR (result_close_template_list (dm
));
2920 /* Consume the 'E'. */
2923 /* Restore the most recent demangled source name. */
2924 dyn_string_delete (dm
->last_source_name
);
2925 dm
->last_source_name
= old_last_source_name
;
2927 /* Push the list onto the top of the stack of template argument
2928 lists, so that arguments from it are used from now on when
2929 expanding <template-param>s. */
2930 push_template_arg_list (dm
, arg_list
);
2935 /* This function, which does not correspond to a production in the
2936 mangling spec, handles the `literal' production for both
2937 <template-arg> and <expr-primary>. It does not expect or consume
2938 the initial `L' or final `E'. The demangling is given by:
2940 <literal> ::= <type> </value/ number>
2942 and the emitted output is `(type)number'. */
2945 demangle_literal (dm
)
2948 char peek
= peek_char (dm
);
2949 dyn_string_t value_string
;
2952 DEMANGLE_TRACE ("literal", dm
);
2954 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2956 /* If not in verbose mode and this is a builtin type, see if we
2957 can produce simpler numerical output. In particular, for
2958 integer types shorter than `long', just write the number
2959 without type information; for bools, write `true' or `false'.
2960 Other refinements could be made here too. */
2962 /* This constant string is used to map from <builtin-type> codes
2963 (26 letters of the alphabet) to codes that determine how the
2964 value will be displayed. The codes are:
2968 A space means the value will be represented using cast
2970 static const char *const code_map
= "ibi iii ll ii i ";
2972 char code
= code_map
[peek
- 'a'];
2973 /* FIXME: Implement demangling of floats and doubles. */
2975 return STATUS_UNIMPLEMENTED
;
2978 /* It's a boolean. */
2981 /* Consume the b. */
2983 /* Look at the next character. It should be 0 or 1,
2984 corresponding to false or true, respectively. */
2985 value
= peek_char (dm
);
2987 RETURN_IF_ERROR (result_add (dm
, "false"));
2988 else if (value
== '1')
2989 RETURN_IF_ERROR (result_add (dm
, "true"));
2991 return "Unrecognized bool constant.";
2992 /* Consume the 0 or 1. */
2996 else if (code
== 'i' || code
== 'l')
2998 /* It's an integer or long. */
3000 /* Consume the type character. */
3003 /* Demangle the number and write it out. */
3004 value_string
= dyn_string_new (0);
3005 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3006 if (STATUS_NO_ERROR (status
))
3007 status
= result_add_string (dm
, value_string
);
3008 /* For long integers, append an l. */
3009 if (code
== 'l' && STATUS_NO_ERROR (status
))
3010 status
= result_add_char (dm
, code
);
3011 dyn_string_delete (value_string
);
3013 RETURN_IF_ERROR (status
);
3016 /* ...else code == ' ', so fall through to represent this
3017 literal's type explicitly using cast syntax. */
3020 RETURN_IF_ERROR (result_add_char (dm
, '('));
3021 RETURN_IF_ERROR (demangle_type (dm
));
3022 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3024 value_string
= dyn_string_new (0);
3025 if (value_string
== NULL
)
3026 return STATUS_ALLOCATION_FAILED
;
3028 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3029 if (STATUS_NO_ERROR (status
))
3030 status
= result_add_string (dm
, value_string
);
3031 dyn_string_delete (value_string
);
3032 RETURN_IF_ERROR (status
);
3037 /* Demangles and emits a <template-arg>.
3039 <template-arg> ::= <type> # type
3040 ::= L <type> <value number> E # literal
3041 ::= LZ <encoding> E # external name
3042 ::= X <expression> E # expression */
3045 demangle_template_arg (dm
)
3048 DEMANGLE_TRACE ("template-arg", dm
);
3050 switch (peek_char (dm
))
3055 if (peek_char (dm
) == 'Z')
3057 /* External name. */
3059 /* FIXME: Standard is contradictory here. */
3060 RETURN_IF_ERROR (demangle_encoding (dm
));
3063 RETURN_IF_ERROR (demangle_literal (dm
));
3064 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3070 RETURN_IF_ERROR (demangle_expression (dm
));
3071 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3075 RETURN_IF_ERROR (demangle_type (dm
));
3082 /* Demangles and emits an <expression>.
3084 <expression> ::= <unary operator-name> <expression>
3085 ::= <binary operator-name> <expression> <expression>
3087 ::= <scope-expression> */
3090 demangle_expression (dm
)
3093 char peek
= peek_char (dm
);
3095 DEMANGLE_TRACE ("expression", dm
);
3097 if (peek
== 'L' || peek
== 'T')
3098 RETURN_IF_ERROR (demangle_expr_primary (dm
));
3099 else if (peek
== 's' && peek_char_next (dm
) == 'r')
3100 RETURN_IF_ERROR (demangle_scope_expression (dm
));
3102 /* An operator expression. */
3105 status_t status
= STATUS_OK
;
3106 dyn_string_t operator_name
;
3108 /* We have an operator name. Since we want to output binary
3109 operations in infix notation, capture the operator name
3111 RETURN_IF_ERROR (result_push (dm
));
3112 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
3113 operator_name
= (dyn_string_t
) result_pop (dm
);
3115 /* If it's binary, do an operand first. */
3118 status
= result_add_char (dm
, '(');
3119 if (STATUS_NO_ERROR (status
))
3120 status
= demangle_expression (dm
);
3121 if (STATUS_NO_ERROR (status
))
3122 status
= result_add_char (dm
, ')');
3125 /* Emit the operator. */
3126 if (STATUS_NO_ERROR (status
))
3127 status
= result_add_string (dm
, operator_name
);
3128 dyn_string_delete (operator_name
);
3129 RETURN_IF_ERROR (status
);
3131 /* Emit its second (if binary) or only (if unary) operand. */
3132 RETURN_IF_ERROR (result_add_char (dm
, '('));
3133 RETURN_IF_ERROR (demangle_expression (dm
));
3134 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3136 /* The ternary operator takes a third operand. */
3139 RETURN_IF_ERROR (result_add (dm
, ":("));
3140 RETURN_IF_ERROR (demangle_expression (dm
));
3141 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3148 /* Demangles and emits a <scope-expression>.
3150 <scope-expression> ::= sr <qualifying type> <source-name>
3151 ::= sr <qualifying type> <encoding> */
3154 demangle_scope_expression (dm
)
3157 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3158 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3159 RETURN_IF_ERROR (demangle_type (dm
));
3160 RETURN_IF_ERROR (result_add (dm
, "::"));
3161 RETURN_IF_ERROR (demangle_encoding (dm
));
3165 /* Demangles and emits an <expr-primary>.
3167 <expr-primary> ::= <template-param>
3168 ::= L <type> <value number> E # literal
3169 ::= L <mangled-name> E # external name */
3172 demangle_expr_primary (dm
)
3175 char peek
= peek_char (dm
);
3177 DEMANGLE_TRACE ("expr-primary", dm
);
3180 RETURN_IF_ERROR (demangle_template_param (dm
));
3181 else if (peek
== 'L')
3183 /* Consume the `L'. */
3185 peek
= peek_char (dm
);
3188 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3190 RETURN_IF_ERROR (demangle_literal (dm
));
3192 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3195 return STATUS_ERROR
;
3200 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3201 if the substitution is the name of a template, zero otherwise.
3203 <substitution> ::= S <seq-id> _
3207 ::= Sa # ::std::allocator
3208 ::= Sb # ::std::basic_string
3209 ::= Ss # ::std::basic_string<char,
3210 ::std::char_traits<char>,
3211 ::std::allocator<char> >
3212 ::= Si # ::std::basic_istream<char,
3213 std::char_traits<char> >
3214 ::= So # ::std::basic_ostream<char,
3215 std::char_traits<char> >
3216 ::= Sd # ::std::basic_iostream<char,
3217 std::char_traits<char> >
3221 demangle_substitution (dm
, template_p
)
3229 DEMANGLE_TRACE ("substitution", dm
);
3231 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3233 /* Scan the substitution sequence index. A missing number denotes
3235 peek
= peek_char (dm
);
3238 /* If the following character is 0-9 or a capital letter, interpret
3239 the sequence up to the next underscore as a base-36 substitution
3241 else if (IS_DIGIT ((unsigned char) peek
)
3242 || (peek
>= 'A' && peek
<= 'Z'))
3243 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3246 const char *new_last_source_name
= NULL
;
3251 RETURN_IF_ERROR (result_add (dm
, "std"));
3255 RETURN_IF_ERROR (result_add (dm
, "std::allocator"));
3256 new_last_source_name
= "allocator";
3261 RETURN_IF_ERROR (result_add (dm
, "std::basic_string"));
3262 new_last_source_name
= "basic_string";
3269 RETURN_IF_ERROR (result_add (dm
, "std::string"));
3270 new_last_source_name
= "string";
3274 RETURN_IF_ERROR (result_add (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3275 new_last_source_name
= "basic_string";
3283 RETURN_IF_ERROR (result_add (dm
, "std::istream"));
3284 new_last_source_name
= "istream";
3288 RETURN_IF_ERROR (result_add (dm
, "std::basic_istream<char, std::char_traints<char> >"));
3289 new_last_source_name
= "basic_istream";
3297 RETURN_IF_ERROR (result_add (dm
, "std::ostream"));
3298 new_last_source_name
= "ostream";
3302 RETURN_IF_ERROR (result_add (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3303 new_last_source_name
= "basic_ostream";
3311 RETURN_IF_ERROR (result_add (dm
, "std::iostream"));
3312 new_last_source_name
= "iostream";
3316 RETURN_IF_ERROR (result_add (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3317 new_last_source_name
= "basic_iostream";
3323 return "Unrecognized <substitution>.";
3326 /* Consume the character we just processed. */
3329 if (new_last_source_name
!= NULL
)
3331 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3332 new_last_source_name
))
3333 return STATUS_ALLOCATION_FAILED
;
3339 /* Look up the substitution text. Since `S_' is the most recent
3340 substitution, `S0_' is the second-most-recent, etc., shift the
3341 numbering by one. */
3342 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3344 return "Substitution number out of range.";
3346 /* Emit the substitution text. */
3347 RETURN_IF_ERROR (result_add_string (dm
, text
));
3349 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3353 /* Demangles and emits a <local-name>.
3355 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3356 := Z <function encoding> E s [<discriminator>] */
3359 demangle_local_name (dm
)
3362 DEMANGLE_TRACE ("local-name", dm
);
3364 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3365 RETURN_IF_ERROR (demangle_encoding (dm
));
3366 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3367 RETURN_IF_ERROR (result_add (dm
, "::"));
3369 if (peek_char (dm
) == 's')
3371 /* Local character string literal. */
3372 RETURN_IF_ERROR (result_add (dm
, "string literal"));
3373 /* Consume the s. */
3375 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3380 /* Local name for some other entity. Demangle its name. */
3381 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3382 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3388 /* Optimonally demangles and emits a <discriminator>. If there is no
3389 <discriminator> at the current position in the mangled string, the
3390 descriminator is assumed to be zero. Emit the discriminator number
3391 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3392 discriminator is zero.
3394 <discriminator> ::= _ <number> */
3397 demangle_discriminator (dm
, suppress_first
)
3401 /* Output for <discriminator>s to the demangled name is completely
3402 suppressed if not in verbose mode. */
3404 if (peek_char (dm
) == '_')
3406 /* Consume the underscore. */
3409 RETURN_IF_ERROR (result_add (dm
, " [#"));
3410 /* Check if there's a number following the underscore. */
3411 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3414 /* Demangle the number. */
3415 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3417 /* Write the discriminator. The mangled number is two
3418 less than the discriminator ordinal, counting from
3420 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 2,
3421 (dyn_string_t
) dm
->result
));
3426 /* A missing digit correspond to one. */
3427 RETURN_IF_ERROR (result_add_char (dm
, '1'));
3430 RETURN_IF_ERROR (result_add_char (dm
, ']'));
3432 else if (!suppress_first
)
3435 RETURN_IF_ERROR (result_add (dm
, " [#0]"));
3441 /* Demangle NAME into RESULT, which must be an initialized
3442 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3443 an error message, and the contents of RESULT are unchanged. */
3446 cp_demangle (name
, result
, style
)
3448 dyn_string_t result
;
3452 int length
= strlen (name
);
3454 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3456 demangling_t dm
= demangling_new (name
, style
);
3458 return STATUS_ALLOCATION_FAILED
;
3460 status
= result_push (dm
);
3461 if (status
!= STATUS_OK
)
3463 demangling_delete (dm
);
3467 status
= demangle_mangled_name (dm
);
3468 if (STATUS_NO_ERROR (status
))
3470 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3471 if (!dyn_string_copy (result
, demangled
))
3472 return STATUS_ALLOCATION_FAILED
;
3473 dyn_string_delete (demangled
);
3476 demangling_delete (dm
);
3480 /* It's evidently not a mangled C++ name. It could be the name
3481 of something with C linkage, though, so just copy NAME into
3483 if (!dyn_string_copy_cstr (result
, name
))
3484 return STATUS_ALLOCATION_FAILED
;
3491 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3492 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3493 an error message, and the contents of RESULT are unchanged. */
3497 cp_demangle_type (type_name
, result
)
3498 const char* type_name
;
3499 dyn_string_t result
;
3502 demangling_t dm
= demangling_new (type_name
);
3505 return STATUS_ALLOCATION_FAILED
;
3507 /* Demangle the type name. The demangled name is stored in dm. */
3508 status
= result_push (dm
);
3509 if (status
!= STATUS_OK
)
3511 demangling_delete (dm
);
3515 status
= demangle_type (dm
);
3517 if (STATUS_NO_ERROR (status
))
3519 /* The demangling succeeded. Pop the result out of dm and copy
3521 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3522 if (!dyn_string_copy (result
, demangled
))
3523 return STATUS_ALLOCATION_FAILED
;
3524 dyn_string_delete (demangled
);
3528 demangling_delete (dm
);
3533 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3535 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3536 demangling. MANGLED_NAME is a NUL-terminated character string
3537 containing the name to be demangled.
3539 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3540 *LENGTH bytes, into which the demangled name is stored. If
3541 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3542 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3543 is placed in a region of memory allocated with malloc.
3545 If LENGTH is non-NULL, the length of the buffer conaining the
3546 demangled name, is placed in *LENGTH.
3548 The return value is a pointer to the start of the NUL-terminated
3549 demangled name, or NULL if the demangling fails. The caller is
3550 responsible for deallocating this memory using free.
3552 *STATUS is set to one of the following values:
3553 0: The demangling operation succeeded.
3554 -1: A memory allocation failiure occurred.
3555 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3556 -3: One of the arguments is invalid.
3558 The demagling is performed using the C++ ABI mangling rules, with
3562 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3563 const char *mangled_name
;
3564 char *output_buffer
;
3568 struct dyn_string demangled_name
;
3574 if (mangled_name
== NULL
) {
3579 /* Did the caller provide a buffer for the demangled name? */
3580 if (output_buffer
== NULL
) {
3581 /* No; dyn_string will malloc a buffer for us. */
3582 if (!dyn_string_init (&demangled_name
, 0))
3589 /* Yes. Check that the length was provided. */
3590 if (length
== NULL
) {
3594 /* Install the buffer into a dyn_string. */
3595 demangled_name
.allocated
= *length
;
3596 demangled_name
.length
= 0;
3597 demangled_name
.s
= output_buffer
;
3600 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3601 /* MANGLED_NAME apprears to be a function or variable name.
3602 Demangle it accordingly. */
3603 result
= cp_demangle (mangled_name
, &demangled_name
, 0);
3605 /* Try to demangled MANGLED_NAME as the name of a type. */
3606 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3608 if (result
== STATUS_OK
)
3609 /* The demangling succeeded. */
3611 /* If LENGTH isn't NULL, store the allocated buffer length
3612 there; the buffer may have been realloced by dyn_string
3615 *length
= demangled_name
.allocated
;
3616 /* The operation was a success. */
3618 return dyn_string_buf (&demangled_name
);
3620 else if (result
== STATUS_ALLOCATION_FAILED
)
3621 /* A call to malloc or realloc failed during the demangling
3628 /* The demangling failed for another reason, most probably because
3629 MANGLED_NAME isn't a valid mangled name. */
3631 /* If the buffer containing the demangled name wasn't provided
3632 by the caller, free it. */
3633 if (output_buffer
== NULL
)
3634 free (dyn_string_buf (&demangled_name
));
3640 #else /* !IN_LIBGCC2 */
3642 /* Variant entry point for integration with the existing cplus-dem
3643 demangler. Attempts to demangle MANGLED. If the demangling
3644 succeeds, returns a buffer, allocated with malloc, containing the
3645 demangled name. The caller must deallocate the buffer using free.
3646 If the demangling failes, returns NULL. */
3649 cplus_demangle_v3 (mangled
)
3650 const char* mangled
;
3652 dyn_string_t demangled
;
3655 /* If this isn't a mangled name, don't pretend to demangle it. */
3656 if (strncmp (mangled
, "_Z", 2) != 0)
3659 /* Create a dyn_string to hold the demangled name. */
3660 demangled
= dyn_string_new (0);
3661 /* Attempt the demangling. */
3662 status
= cp_demangle ((char *) mangled
, demangled
, 0);
3664 if (STATUS_NO_ERROR (status
))
3665 /* Demangling succeeded. */
3667 /* Grab the demangled result from the dyn_string. It was
3668 allocated with malloc, so we can return it directly. */
3669 char *return_value
= dyn_string_release (demangled
);
3670 /* Hand back the demangled name. */
3671 return return_value
;
3673 else if (status
== STATUS_ALLOCATION_FAILED
)
3675 fprintf (stderr
, "Memory allocation failed.\n");
3679 /* Demangling failed. */
3681 dyn_string_delete (demangled
);
3686 /* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3687 conventions, but the output formatting is a little different.
3688 This instructs the C++ demangler not to emit pointer characters ("*"), and
3689 to use Java's namespace separator symbol ("." instead of "::"). It then
3690 does an additional pass over the demangled output to replace instances
3691 of JArray<TYPE> with TYPE[]. */
3694 java_demangle_v3 (mangled
)
3695 const char* mangled
;
3697 dyn_string_t demangled
;
3703 char *cplus_demangled
;
3706 /* Create a dyn_string to hold the demangled name. */
3707 demangled
= dyn_string_new (0);
3709 /* Attempt the demangling. */
3710 status
= cp_demangle ((char *) mangled
, demangled
, DMGL_JAVA
);
3712 if (STATUS_NO_ERROR (status
))
3713 /* Demangling succeeded. */
3715 /* Grab the demangled result from the dyn_string. */
3716 cplus_demangled
= dyn_string_release (demangled
);
3718 else if (status
== STATUS_ALLOCATION_FAILED
)
3720 fprintf (stderr
, "Memory allocation failed.\n");
3724 /* Demangling failed. */
3726 dyn_string_delete (demangled
);
3730 len
= strlen (cplus_demangled
);
3731 next
= cplus_demangled
;
3735 /* Replace occurances of JArray<TYPE> with TYPE[]. */
3738 char *open_str
= strstr (next
, "JArray<");
3739 char *close_str
= NULL
;
3741 close_str
= strchr (next
, '>');
3743 if (open_str
!= NULL
&& (close_str
== NULL
|| close_str
> open_str
))
3748 demangled
= dyn_string_new(len
);
3750 /* Copy prepending symbols, if any. */
3751 if (open_str
> next
)
3754 dyn_string_append_cstr (demangled
, next
);
3756 next
= open_str
+ 7;
3758 else if (close_str
!= NULL
)
3762 /* Copy prepending type symbol, if any. Squash any spurious
3764 if (close_str
> next
&& next
[0] != ' ')
3767 dyn_string_append_cstr (demangled
, next
);
3769 dyn_string_append_cstr (demangled
, "[]");
3770 next
= close_str
+ 1;
3774 /* There are no more arrays. Copy the rest of the symbol, or
3775 simply return the original symbol if no changes were made. */
3776 if (next
== cplus_demangled
)
3777 return cplus_demangled
;
3779 dyn_string_append_cstr (demangled
, next
);
3784 free (cplus_demangled
);
3786 return_value
= dyn_string_release (demangled
);
3787 return return_value
;
3790 #endif /* IN_LIBGCC2 */
3792 #ifdef STANDALONE_DEMANGLER
3796 static void print_usage
3797 PARAMS ((FILE* fp
, int exit_value
));
3799 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3800 #define is_mangled_char(CHAR) \
3801 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3802 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3804 /* The name of this program, as invoked. */
3805 const char* program_name
;
3807 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3810 print_usage (fp
, exit_value
)
3814 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3815 fprintf (fp
, "Options:\n");
3816 fprintf (fp
, " -h,--help Display this message.\n");
3817 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3818 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3819 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3824 /* Option specification for getopt_long. */
3825 static struct option long_options
[] =
3827 { "help", no_argument
, NULL
, 'h' },
3828 { "strict", no_argument
, NULL
, 's' },
3829 { "verbose", no_argument
, NULL
, 'v' },
3830 { NULL
, no_argument
, NULL
, 0 },
3833 /* Main entry for a demangling filter executable. It will demangle
3834 its command line arguments, if any. If none are provided, it will
3835 filter stdin to stdout, replacing any recognized mangled C++ names
3836 with their demangled equivalents. */
3847 /* Use the program name of this program, as invoked. */
3848 program_name
= argv
[0];
3850 /* Parse options. */
3853 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3856 case '?': /* Unrecognized option. */
3857 print_usage (stderr
, 1);
3861 print_usage (stdout
, 0);
3873 while (opt_char
!= -1);
3876 /* No command line arguments were provided. Filter stdin. */
3878 dyn_string_t mangled
= dyn_string_new (3);
3879 dyn_string_t demangled
= dyn_string_new (0);
3882 /* Read all of input. */
3883 while (!feof (stdin
))
3885 char c
= getchar ();
3887 /* The first character of a mangled name is an underscore. */
3892 /* It's not a mangled name. Print the character and go
3899 /* The second character of a mangled name is a capital `Z'. */
3904 /* It's not a mangled name. Print the previous
3905 underscore, the `Z', and go on. */
3911 /* Start keeping track of the candidate mangled name. */
3912 dyn_string_append_char (mangled
, '_');
3913 dyn_string_append_char (mangled
, 'Z');
3915 /* Pile characters into mangled until we hit one that can't
3916 occur in a mangled name. */
3918 while (!feof (stdin
) && is_mangled_char (c
))
3920 dyn_string_append_char (mangled
, c
);
3926 /* Attempt to demangle the name. */
3927 status
= cp_demangle (dyn_string_buf (mangled
), demangled
, 0);
3929 /* If the demangling succeeded, great! Print out the
3930 demangled version. */
3931 if (STATUS_NO_ERROR (status
))
3932 fputs (dyn_string_buf (demangled
), stdout
);
3933 /* Abort on allocation failures. */
3934 else if (status
== STATUS_ALLOCATION_FAILED
)
3936 fprintf (stderr
, "Memory allocation failed.\n");
3939 /* Otherwise, it might not have been a mangled name. Just
3940 print out the original text. */
3942 fputs (dyn_string_buf (mangled
), stdout
);
3944 /* If we haven't hit EOF yet, we've read one character that
3945 can't occur in a mangled name, so print it out. */
3949 /* Clear the candidate mangled name, to start afresh next
3950 time we hit a `_Z'. */
3951 dyn_string_clear (mangled
);
3954 dyn_string_delete (mangled
);
3955 dyn_string_delete (demangled
);
3958 /* Demangle command line arguments. */
3960 dyn_string_t result
= dyn_string_new (0);
3962 /* Loop over command line arguments. */
3963 for (i
= optind
; i
< argc
; ++i
)
3965 /* Attempt to demangle. */
3966 status
= cp_demangle (argv
[i
], result
, 0);
3968 /* If it worked, print the demangled name. */
3969 if (STATUS_NO_ERROR (status
))
3970 printf ("%s\n", dyn_string_buf (result
));
3971 /* Abort on allocaiton failures. */
3972 else if (status
== STATUS_ALLOCATION_FAILED
)
3974 fprintf (stderr
, "Memory allocation failed.\n");
3977 /* If not, print the error message to stderr instead. */
3979 fprintf (stderr
, "%s\n", status
);
3981 dyn_string_delete (result
);
3987 #endif /* STANDALONE_DEMANGLER */