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. */
176 /* Set to non-zero iff this name is a constructor. The actual value
177 indicates what sort of constructor this is; see demangle.h. */
178 enum gnu_v3_ctor_kinds is_constructor
;
180 /* Set to non-zero iff this name is a destructor. The actual value
181 indicates what sort of destructor this is; see demangle.h. */
182 enum gnu_v3_dtor_kinds is_destructor
;
186 typedef struct demangling_def
*demangling_t
;
188 /* This type is the standard return code from most functions. Values
189 other than STATUS_OK contain descriptive messages. */
190 typedef const char *status_t
;
192 /* Special values that can be used as a status_t. */
193 #define STATUS_OK NULL
194 #define STATUS_ERROR "Error."
195 #define STATUS_UNIMPLEMENTED "Unimplemented."
196 #define STATUS_INTERNAL_ERROR "Internal error."
198 /* This status code indicates a failure in malloc or realloc. */
199 static const char *const status_allocation_failed
= "Allocation failed.";
200 #define STATUS_ALLOCATION_FAILED status_allocation_failed
202 /* Non-zero if STATUS indicates that no error has occurred. */
203 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
205 /* Evaluate EXPR, which must produce a status_t. If the status code
206 indicates an error, return from the current function with that
208 #define RETURN_IF_ERROR(EXPR) \
212 if (!STATUS_NO_ERROR (s)) \
217 static status_t int_to_dyn_string
218 PARAMS ((int, dyn_string_t
));
219 static string_list_t string_list_new
221 static void string_list_delete
222 PARAMS ((string_list_t
));
223 static status_t result_add_separated_char
224 PARAMS ((demangling_t
, int));
225 static status_t result_push
226 PARAMS ((demangling_t
));
227 static string_list_t result_pop
228 PARAMS ((demangling_t
));
229 static int substitution_start
230 PARAMS ((demangling_t
));
231 static status_t substitution_add
232 PARAMS ((demangling_t
, int, int));
233 static dyn_string_t substitution_get
234 PARAMS ((demangling_t
, int, int *));
235 #ifdef CP_DEMANGLE_DEBUG
236 static void substitutions_print
237 PARAMS ((demangling_t
, FILE *));
239 static template_arg_list_t template_arg_list_new
241 static void template_arg_list_delete
242 PARAMS ((template_arg_list_t
));
243 static void template_arg_list_add_arg
244 PARAMS ((template_arg_list_t
, string_list_t
));
245 static string_list_t template_arg_list_get_arg
246 PARAMS ((template_arg_list_t
, int));
247 static void push_template_arg_list
248 PARAMS ((demangling_t
, template_arg_list_t
));
249 static void pop_to_template_arg_list
250 PARAMS ((demangling_t
, template_arg_list_t
));
251 #ifdef CP_DEMANGLE_DEBUG
252 static void template_arg_list_print
253 PARAMS ((template_arg_list_t
, FILE *));
255 static template_arg_list_t current_template_arg_list
256 PARAMS ((demangling_t
));
257 static demangling_t demangling_new
258 PARAMS ((const char *, int));
259 static void demangling_delete
260 PARAMS ((demangling_t
));
262 /* The last character of DS. Warning: DS is evaluated twice. */
263 #define dyn_string_last_char(DS) \
264 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
266 /* Append a space character (` ') to DS if it does not already end
267 with one. Evaluates to 1 on success, or 0 on allocation failure. */
268 #define dyn_string_append_space(DS) \
269 ((dyn_string_length (DS) > 0 \
270 && dyn_string_last_char (DS) != ' ') \
271 ? dyn_string_append_char ((DS), ' ') \
274 /* Returns the index of the current position in the mangled name. */
275 #define current_position(DM) ((DM)->next - (DM)->name)
277 /* Returns the character at the current position of the mangled name. */
278 #define peek_char(DM) (*((DM)->next))
280 /* Returns the character one past the current position of the mangled
282 #define peek_char_next(DM) \
283 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
285 /* Returns the character at the current position, and advances the
286 current position to the next character. */
287 #define next_char(DM) (*((DM)->next)++)
289 /* Returns non-zero if the current position is the end of the mangled
290 name, i.e. one past the last character. */
291 #define end_of_name_p(DM) (peek_char (DM) == '\0')
293 /* Advances the current position by one character. */
294 #define advance_char(DM) (++(DM)->next)
296 /* Returns the string containing the current demangled result. */
297 #define result_string(DM) (&(DM)->result->string)
299 /* Returns the position at which new text is inserted into the
301 #define result_caret_pos(DM) \
302 (result_length (DM) + \
303 ((string_list_t) result_string (DM))->caret_position)
305 /* Adds a dyn_string_t to the demangled result. */
306 #define result_add_string(DM, STRING) \
307 (dyn_string_insert (&(DM)->result->string, \
308 result_caret_pos (DM), (STRING)) \
309 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
311 /* Adds NUL-terminated string CSTR to the demangled result. */
312 #define result_add(DM, CSTR) \
313 (dyn_string_insert_cstr (&(DM)->result->string, \
314 result_caret_pos (DM), (CSTR)) \
315 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
317 /* Adds character CHAR to the demangled result. */
318 #define result_add_char(DM, CHAR) \
319 (dyn_string_insert_char (&(DM)->result->string, \
320 result_caret_pos (DM), (CHAR)) \
321 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
323 /* Inserts a dyn_string_t to the demangled result at position POS. */
324 #define result_insert_string(DM, POS, STRING) \
325 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
326 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
328 /* Inserts NUL-terminated string CSTR to the demangled result at
330 #define result_insert(DM, POS, CSTR) \
331 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
332 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
334 /* Inserts character CHAR to the demangled result at position POS. */
335 #define result_insert_char(DM, POS, CHAR) \
336 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
337 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
339 /* The length of the current demangled result. */
340 #define result_length(DM) \
341 dyn_string_length (&(DM)->result->string)
343 /* Appends a (less-than, greater-than) character to the result in DM
344 to (open, close) a template argument or parameter list. Appends a
345 space first if necessary to prevent spurious elision of angle
346 brackets with the previous character. */
347 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
348 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
350 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
351 success. On failure, deletes DS and returns an error code. */
354 int_to_dyn_string (value
, ds
)
361 /* Handle zero up front. */
364 if (!dyn_string_append_char (ds
, '0'))
365 return STATUS_ALLOCATION_FAILED
;
369 /* For negative numbers, emit a minus sign. */
372 if (!dyn_string_append_char (ds
, '-'))
373 return STATUS_ALLOCATION_FAILED
;
377 /* Find the power of 10 of the first digit. */
385 /* Write the digits. */
388 int digit
= value
/ mask
;
390 if (!dyn_string_append_char (ds
, '0' + digit
))
391 return STATUS_ALLOCATION_FAILED
;
393 value
-= digit
* mask
;
400 /* Creates a new string list node. The contents of the string are
401 empty, but the initial buffer allocation is LENGTH. The string
402 list node should be deleted with string_list_delete. Returns NULL
403 if allocation fails. */
406 string_list_new (length
)
409 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
410 s
->caret_position
= 0;
413 if (!dyn_string_init ((dyn_string_t
) s
, length
))
418 /* Deletes the entire string list starting at NODE. */
421 string_list_delete (node
)
426 string_list_t next
= node
->next
;
427 dyn_string_delete ((dyn_string_t
) node
);
432 /* Appends CHARACTER to the demangled result. If the current trailing
433 character of the result is CHARACTER, a space is inserted first. */
436 result_add_separated_char (dm
, character
)
440 char *result
= dyn_string_buf (result_string (dm
));
441 int caret_pos
= result_caret_pos (dm
);
443 /* Add a space if the last character is already the character we
445 if (caret_pos
> 0 && result
[caret_pos
- 1] == character
)
446 RETURN_IF_ERROR (result_add_char (dm
, ' '));
447 /* Add the character. */
448 RETURN_IF_ERROR (result_add_char (dm
, character
));
453 /* Allocates and pushes a new string onto the demangled results stack
454 for DM. Subsequent demangling with DM will emit to the new string.
455 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
456 allocation failure. */
462 string_list_t new_string
= string_list_new (0);
463 if (new_string
== NULL
)
464 /* Allocation failed. */
465 return STATUS_ALLOCATION_FAILED
;
467 /* Link the new string to the front of the list of result strings. */
468 new_string
->next
= (string_list_t
) dm
->result
;
469 dm
->result
= new_string
;
473 /* Removes and returns the topmost element on the demangled results
474 stack for DM. The caller assumes ownership for the returned
481 string_list_t top
= dm
->result
;
482 dm
->result
= top
->next
;
486 /* Returns the current value of the caret for the result string. The
487 value is an offet from the end of the result string. */
490 result_get_caret (dm
)
493 return ((string_list_t
) result_string (dm
))->caret_position
;
496 /* Sets the value of the caret for the result string, counted as an
497 offet from the end of the result string. */
500 result_set_caret (dm
, position
)
504 ((string_list_t
) result_string (dm
))->caret_position
= position
;
507 /* Shifts the position of the next addition to the result by
508 POSITION_OFFSET. A negative value shifts the caret to the left. */
511 result_shift_caret (dm
, position_offset
)
515 ((string_list_t
) result_string (dm
))->caret_position
+= position_offset
;
518 /* Returns non-zero if the character that comes right before the place
519 where text will be added to the result is a space. In this case,
520 the caller should supress adding another space. */
523 result_previous_char_is_space (dm
)
526 char *result
= dyn_string_buf (result_string (dm
));
527 int pos
= result_caret_pos (dm
);
528 return pos
> 0 && result
[pos
- 1] == ' ';
531 /* Returns the start position of a fragment of the demangled result
532 that will be a substitution candidate. Should be called at the
533 start of productions that can add substitutions. */
536 substitution_start (dm
)
539 return result_caret_pos (dm
);
542 /* Adds the suffix of the current demangled result of DM starting at
543 START_POSITION as a potential substitution. If TEMPLATE_P is
544 non-zero, this potential substitution is a template-id. */
547 substitution_add (dm
, start_position
, template_p
)
552 dyn_string_t result
= result_string (dm
);
553 dyn_string_t substitution
= dyn_string_new (0);
556 if (substitution
== NULL
)
557 return STATUS_ALLOCATION_FAILED
;
559 /* Extract the substring of the current demangling result that
560 represents the subsitution candidate. */
561 if (!dyn_string_substring (substitution
,
562 result
, start_position
, result_caret_pos (dm
)))
564 dyn_string_delete (substitution
);
565 return STATUS_ALLOCATION_FAILED
;
568 /* If there's no room for the new entry, grow the array. */
569 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
571 size_t new_array_size
;
572 if (dm
->substitutions_allocated
> 0)
573 dm
->substitutions_allocated
*= 2;
575 dm
->substitutions_allocated
= 2;
577 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
579 dm
->substitutions
= (struct substitution_def
*)
580 realloc (dm
->substitutions
, new_array_size
);
581 if (dm
->substitutions
== NULL
)
582 /* Realloc failed. */
584 dyn_string_delete (substitution
);
585 return STATUS_ALLOCATION_FAILED
;
589 /* Add the substitution to the array. */
590 i
= dm
->num_substitutions
++;
591 dm
->substitutions
[i
].text
= substitution
;
592 dm
->substitutions
[i
].template_p
= template_p
;
594 #ifdef CP_DEMANGLE_DEBUG
595 substitutions_print (dm
, stderr
);
601 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
602 non-zero if the substitution is a template-id, zero otherwise.
603 N is numbered from zero. DM retains ownership of the returned
604 string. If N is negative, or equal to or greater than the current
605 number of substitution candidates, returns NULL. */
608 substitution_get (dm
, n
, template_p
)
613 struct substitution_def
*sub
;
615 /* Make sure N is in the valid range. */
616 if (n
< 0 || n
>= dm
->num_substitutions
)
619 sub
= &(dm
->substitutions
[n
]);
620 *template_p
= sub
->template_p
;
624 #ifdef CP_DEMANGLE_DEBUG
625 /* Debugging routine to print the current substitutions to FP. */
628 substitutions_print (dm
, fp
)
633 int num
= dm
->num_substitutions
;
635 fprintf (fp
, "SUBSTITUTIONS:\n");
636 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
639 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
642 fprintf (fp
, " S_ ");
644 fprintf (fp
, " S%d_", seq_id
);
645 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
649 #endif /* CP_DEMANGLE_DEBUG */
651 /* Creates a new template argument list. Returns NULL if allocation
654 static template_arg_list_t
655 template_arg_list_new ()
657 template_arg_list_t new_list
=
658 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
659 if (new_list
== NULL
)
661 /* Initialize the new list to have no arguments. */
662 new_list
->first_argument
= NULL
;
663 new_list
->last_argument
= NULL
;
664 /* Return the new list. */
668 /* Deletes a template argument list and the template arguments it
672 template_arg_list_delete (list
)
673 template_arg_list_t list
;
675 /* If there are any arguments on LIST, delete them. */
676 if (list
->first_argument
!= NULL
)
677 string_list_delete (list
->first_argument
);
682 /* Adds ARG to the template argument list ARG_LIST. */
685 template_arg_list_add_arg (arg_list
, arg
)
686 template_arg_list_t arg_list
;
689 if (arg_list
->first_argument
== NULL
)
690 /* If there were no arguments before, ARG is the first one. */
691 arg_list
->first_argument
= arg
;
693 /* Make ARG the last argument on the list. */
694 arg_list
->last_argument
->next
= arg
;
695 /* Make ARG the last on the list. */
696 arg_list
->last_argument
= arg
;
700 /* Returns the template arugment at position INDEX in template
701 argument list ARG_LIST. */
704 template_arg_list_get_arg (arg_list
, index
)
705 template_arg_list_t arg_list
;
708 string_list_t arg
= arg_list
->first_argument
;
709 /* Scan down the list of arguments to find the one at position
715 /* Ran out of arguments before INDEX hit zero. That's an
719 /* Return the argument at position INDEX. */
723 /* Pushes ARG_LIST onto the top of the template argument list stack. */
726 push_template_arg_list (dm
, arg_list
)
728 template_arg_list_t arg_list
;
730 arg_list
->next
= dm
->template_arg_lists
;
731 dm
->template_arg_lists
= arg_list
;
732 #ifdef CP_DEMANGLE_DEBUG
733 fprintf (stderr
, " ** pushing template arg list\n");
734 template_arg_list_print (arg_list
, stderr
);
738 /* Pops and deletes elements on the template argument list stack until
739 arg_list is the topmost element. If arg_list is NULL, all elements
740 are popped and deleted. */
743 pop_to_template_arg_list (dm
, arg_list
)
745 template_arg_list_t arg_list
;
747 while (dm
->template_arg_lists
!= arg_list
)
749 template_arg_list_t top
= dm
->template_arg_lists
;
750 /* Disconnect the topmost element from the list. */
751 dm
->template_arg_lists
= top
->next
;
752 /* Delete the popped element. */
753 template_arg_list_delete (top
);
754 #ifdef CP_DEMANGLE_DEBUG
755 fprintf (stderr
, " ** removing template arg list\n");
760 #ifdef CP_DEMANGLE_DEBUG
762 /* Prints the contents of ARG_LIST to FP. */
765 template_arg_list_print (arg_list
, fp
)
766 template_arg_list_t arg_list
;
772 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
773 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
776 fprintf (fp
, " T_ : ");
778 fprintf (fp
, " T%d_ : ", index
);
780 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
784 #endif /* CP_DEMANGLE_DEBUG */
786 /* Returns the topmost element on the stack of template argument
787 lists. If there is no list of template arguments, returns NULL. */
789 static template_arg_list_t
790 current_template_arg_list (dm
)
793 return dm
->template_arg_lists
;
796 /* Allocates a demangling_t object for demangling mangled NAME. A new
797 result must be pushed before the returned object can be used.
798 Returns NULL if allocation fails. */
801 demangling_new (name
, style
)
806 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
813 dm
->num_substitutions
= 0;
814 dm
->substitutions_allocated
= 10;
815 dm
->template_arg_lists
= NULL
;
816 dm
->last_source_name
= dyn_string_new (0);
817 if (dm
->last_source_name
== NULL
)
819 dm
->substitutions
= (struct substitution_def
*)
820 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
821 if (dm
->substitutions
== NULL
)
823 dyn_string_delete (dm
->last_source_name
);
827 dm
->is_constructor
= 0;
828 dm
->is_destructor
= 0;
833 /* Deallocates a demangling_t object and all memory associated with
837 demangling_delete (dm
)
841 template_arg_list_t arg_list
= dm
->template_arg_lists
;
843 /* Delete the stack of template argument lists. */
844 while (arg_list
!= NULL
)
846 template_arg_list_t next
= arg_list
->next
;
847 template_arg_list_delete (arg_list
);
850 /* Delete the list of substitutions. */
851 for (i
= dm
->num_substitutions
; --i
>= 0; )
852 dyn_string_delete (dm
->substitutions
[i
].text
);
853 free (dm
->substitutions
);
854 /* Delete the demangled result. */
855 string_list_delete (dm
->result
);
856 /* Delete the stored identifier name. */
857 dyn_string_delete (dm
->last_source_name
);
858 /* Delete the context object itself. */
862 /* These functions demangle an alternative of the corresponding
863 production in the mangling spec. The first argument of each is a
864 demangling context structure for the current demangling
865 operation. Most emit demangled text directly to the topmost result
866 string on the result string stack in the demangling context
869 static status_t demangle_char
870 PARAMS ((demangling_t
, int));
871 static status_t demangle_mangled_name
872 PARAMS ((demangling_t
));
873 static status_t demangle_encoding
874 PARAMS ((demangling_t
));
875 static status_t demangle_name
876 PARAMS ((demangling_t
, int *));
877 static status_t demangle_nested_name
878 PARAMS ((demangling_t
, int *));
879 static status_t demangle_prefix
880 PARAMS ((demangling_t
, int *));
881 static status_t demangle_unqualified_name
882 PARAMS ((demangling_t
, int *));
883 static status_t demangle_source_name
884 PARAMS ((demangling_t
));
885 static status_t demangle_number
886 PARAMS ((demangling_t
, int *, int, int));
887 static status_t demangle_number_literally
888 PARAMS ((demangling_t
, dyn_string_t
, int, int));
889 static status_t demangle_identifier
890 PARAMS ((demangling_t
, int, dyn_string_t
));
891 static status_t demangle_operator_name
892 PARAMS ((demangling_t
, int, int *));
893 static status_t demangle_nv_offset
894 PARAMS ((demangling_t
));
895 static status_t demangle_v_offset
896 PARAMS ((demangling_t
));
897 static status_t demangle_call_offset
898 PARAMS ((demangling_t
));
899 static status_t demangle_special_name
900 PARAMS ((demangling_t
));
901 static status_t demangle_ctor_dtor_name
902 PARAMS ((demangling_t
));
903 static status_t demangle_type_ptr
904 PARAMS ((demangling_t
, int *, int));
905 static status_t demangle_type
906 PARAMS ((demangling_t
));
907 static status_t demangle_CV_qualifiers
908 PARAMS ((demangling_t
, dyn_string_t
));
909 static status_t demangle_builtin_type
910 PARAMS ((demangling_t
));
911 static status_t demangle_function_type
912 PARAMS ((demangling_t
, int *));
913 static status_t demangle_bare_function_type
914 PARAMS ((demangling_t
, int *));
915 static status_t demangle_class_enum_type
916 PARAMS ((demangling_t
, int *));
917 static status_t demangle_array_type
918 PARAMS ((demangling_t
, int *));
919 static status_t demangle_template_param
920 PARAMS ((demangling_t
));
921 static status_t demangle_template_args
922 PARAMS ((demangling_t
));
923 static status_t demangle_literal
924 PARAMS ((demangling_t
));
925 static status_t demangle_template_arg
926 PARAMS ((demangling_t
));
927 static status_t demangle_expression
928 PARAMS ((demangling_t
));
929 static status_t demangle_scope_expression
930 PARAMS ((demangling_t
));
931 static status_t demangle_expr_primary
932 PARAMS ((demangling_t
));
933 static status_t demangle_substitution
934 PARAMS ((demangling_t
, int *));
935 static status_t demangle_local_name
936 PARAMS ((demangling_t
));
937 static status_t demangle_discriminator
938 PARAMS ((demangling_t
, int));
939 static status_t cp_demangle
940 PARAMS ((const char *, dyn_string_t
, int));
942 static status_t cp_demangle_type
943 PARAMS ((const char*, dyn_string_t
));
946 /* When passed to demangle_bare_function_type, indicates that the
947 function's return type is not encoded before its parameter types. */
948 #define BFT_NO_RETURN_TYPE NULL
950 /* Check that the next character is C. If so, consume it. If not,
954 demangle_char (dm
, c
)
958 static char *error_message
= NULL
;
960 if (peek_char (dm
) == c
)
967 if (error_message
== NULL
)
968 error_message
= strdup ("Expected ?");
969 error_message
[9] = c
;
970 return error_message
;
974 /* Demangles and emits a <mangled-name>.
976 <mangled-name> ::= _Z <encoding> */
979 demangle_mangled_name (dm
)
982 DEMANGLE_TRACE ("mangled-name", dm
);
983 RETURN_IF_ERROR (demangle_char (dm
, '_'));
984 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
985 RETURN_IF_ERROR (demangle_encoding (dm
));
989 /* Demangles and emits an <encoding>.
991 <encoding> ::= <function name> <bare-function-type>
993 ::= <special-name> */
996 demangle_encoding (dm
)
999 int encode_return_type
;
1001 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1002 char peek
= peek_char (dm
);
1004 DEMANGLE_TRACE ("encoding", dm
);
1006 /* Remember where the name starts. If it turns out to be a template
1007 function, we'll have to insert the return type here. */
1008 start_position
= result_caret_pos (dm
);
1010 if (peek
== 'G' || peek
== 'T')
1011 RETURN_IF_ERROR (demangle_special_name (dm
));
1014 /* Now demangle the name. */
1015 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
1017 /* If there's anything left, the name was a function name, with
1018 maybe its return type, and its parameter types, following. */
1019 if (!end_of_name_p (dm
)
1020 && peek_char (dm
) != 'E')
1022 if (encode_return_type
)
1023 /* Template functions have their return type encoded. The
1024 return type should be inserted at start_position. */
1026 (demangle_bare_function_type (dm
, &start_position
));
1028 /* Non-template functions don't have their return type
1031 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
1035 /* Pop off template argument lists that were built during the
1036 mangling of this name, to restore the old template context. */
1037 pop_to_template_arg_list (dm
, old_arg_list
);
1042 /* Demangles and emits a <name>.
1044 <name> ::= <unscoped-name>
1045 ::= <unscoped-template-name> <template-args>
1049 <unscoped-name> ::= <unqualified-name>
1050 ::= St <unqualified-name> # ::std::
1052 <unscoped-template-name>
1054 ::= <substitution> */
1057 demangle_name (dm
, encode_return_type
)
1059 int *encode_return_type
;
1061 int start
= substitution_start (dm
);
1062 char peek
= peek_char (dm
);
1063 int is_std_substitution
= 0;
1065 /* Generally, the return type is encoded if the function is a
1066 template-id, and suppressed otherwise. There are a few cases,
1067 though, in which the return type is not encoded even for a
1068 templated function. In these cases, this flag is set. */
1069 int suppress_return_type
= 0;
1071 DEMANGLE_TRACE ("name", dm
);
1076 /* This is a <nested-name>. */
1077 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1081 RETURN_IF_ERROR (demangle_local_name (dm
));
1082 *encode_return_type
= 0;
1086 /* The `St' substitution allows a name nested in std:: to appear
1087 without being enclosed in a nested name. */
1088 if (peek_char_next (dm
) == 't')
1090 (void) next_char (dm
);
1091 (void) next_char (dm
);
1092 RETURN_IF_ERROR (result_add (dm
, "std::"));
1094 (demangle_unqualified_name (dm
, &suppress_return_type
));
1095 is_std_substitution
= 1;
1098 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1099 /* Check if a template argument list immediately follows.
1100 If so, then we just demangled an <unqualified-template-name>. */
1101 if (peek_char (dm
) == 'I')
1103 /* A template name of the form std::<unqualified-name> is a
1104 substitution candidate. */
1105 if (is_std_substitution
)
1106 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1107 /* Demangle the <template-args> here. */
1108 RETURN_IF_ERROR (demangle_template_args (dm
));
1109 *encode_return_type
= !suppress_return_type
;
1112 *encode_return_type
= 0;
1117 /* This is an <unscoped-name> or <unscoped-template-name>. */
1118 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1120 /* If the <unqualified-name> is followed by template args, this
1121 is an <unscoped-template-name>. */
1122 if (peek_char (dm
) == 'I')
1124 /* Add a substitution for the unqualified template name. */
1125 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1127 RETURN_IF_ERROR (demangle_template_args (dm
));
1128 *encode_return_type
= !suppress_return_type
;
1131 *encode_return_type
= 0;
1139 /* Demangles and emits a <nested-name>.
1141 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1144 demangle_nested_name (dm
, encode_return_type
)
1146 int *encode_return_type
;
1150 DEMANGLE_TRACE ("nested-name", dm
);
1152 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1154 peek
= peek_char (dm
);
1155 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1157 dyn_string_t cv_qualifiers
;
1160 /* Snarf up CV qualifiers. */
1161 cv_qualifiers
= dyn_string_new (24);
1162 if (cv_qualifiers
== NULL
)
1163 return STATUS_ALLOCATION_FAILED
;
1164 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1166 /* Emit them, preceded by a space. */
1167 status
= result_add_char (dm
, ' ');
1168 if (STATUS_NO_ERROR (status
))
1169 status
= result_add_string (dm
, cv_qualifiers
);
1170 /* The CV qualifiers that occur in a <nested-name> will be
1171 qualifiers for member functions. These are placed at the end
1172 of the function. Therefore, shift the caret to the left by
1173 the length of the qualifiers, so other text is inserted
1174 before them and they stay at the end. */
1175 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
) - 1);
1177 dyn_string_delete (cv_qualifiers
);
1178 RETURN_IF_ERROR (status
);
1181 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1182 /* No need to demangle the final <unqualified-name>; demangle_prefix
1184 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1189 /* Demangles and emits a <prefix>.
1191 <prefix> ::= <prefix> <unqualified-name>
1192 ::= <template-prefix> <template-args>
1196 <template-prefix> ::= <prefix>
1197 ::= <substitution> */
1200 demangle_prefix (dm
, encode_return_type
)
1202 int *encode_return_type
;
1204 int start
= substitution_start (dm
);
1207 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1208 After <template-args>, it is set to non-zero; after everything
1209 else it is set to zero. */
1211 /* Generally, the return type is encoded if the function is a
1212 template-id, and suppressed otherwise. There are a few cases,
1213 though, in which the return type is not encoded even for a
1214 templated function. In these cases, this flag is set. */
1215 int suppress_return_type
= 0;
1217 DEMANGLE_TRACE ("prefix", dm
);
1223 if (end_of_name_p (dm
))
1224 return "Unexpected end of name in <compound-name>.";
1226 peek
= peek_char (dm
);
1228 /* We'll initialize suppress_return_type to false, and set it to true
1229 if we end up demangling a constructor name. However, make
1230 sure we're not actually about to demangle template arguments
1231 -- if so, this is the <template-args> following a
1232 <template-prefix>, so we'll want the previous flag value
1235 suppress_return_type
= 0;
1237 if (IS_DIGIT ((unsigned char) peek
)
1238 || (peek
>= 'a' && peek
<= 'z')
1239 || peek
== 'C' || peek
== 'D'
1242 /* We have another level of scope qualification. */
1244 RETURN_IF_ERROR (result_add (dm
, NAMESPACE_SEPARATOR
));
1249 /* The substitution determines whether this is a
1251 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1254 /* It's just a name. */
1256 (demangle_unqualified_name (dm
, &suppress_return_type
));
1257 *encode_return_type
= 0;
1260 else if (peek
== 'Z')
1261 RETURN_IF_ERROR (demangle_local_name (dm
));
1262 else if (peek
== 'I')
1264 RETURN_IF_ERROR (demangle_template_args (dm
));
1266 /* Now we want to indicate to the caller that we've
1267 demangled template arguments, thus the prefix was a
1268 <template-prefix>. That's so that the caller knows to
1269 demangle the function's return type, if this turns out to
1270 be a function name. But, if it's a member template
1271 constructor or a templated conversion operator, report it
1272 as untemplated. Those never get encoded return types. */
1273 *encode_return_type
= !suppress_return_type
;
1275 else if (peek
== 'E')
1279 return "Unexpected character in <compound-name>.";
1282 && peek_char (dm
) != 'E')
1283 /* Add a new substitution for the prefix thus far. */
1284 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1288 /* Demangles and emits an <unqualified-name>. If this
1289 <unqualified-name> is for a special function type that should never
1290 have its return type encoded (particularly, a constructor or
1291 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1294 <unqualified-name> ::= <operator-name>
1296 ::= <source-name> */
1299 demangle_unqualified_name (dm
, suppress_return_type
)
1301 int *suppress_return_type
;
1303 char peek
= peek_char (dm
);
1305 DEMANGLE_TRACE ("unqualified-name", dm
);
1307 /* By default, don't force suppression of the return type (though
1308 non-template functions still don't get a return type encoded). */
1309 *suppress_return_type
= 0;
1311 if (IS_DIGIT ((unsigned char) peek
))
1312 RETURN_IF_ERROR (demangle_source_name (dm
));
1313 else if (peek
>= 'a' && peek
<= 'z')
1317 /* Conversion operators never have a return type encoded. */
1318 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1319 *suppress_return_type
= 1;
1321 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1323 else if (peek
== 'C' || peek
== 'D')
1325 /* Constructors never have a return type encoded. */
1327 *suppress_return_type
= 1;
1329 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1332 return "Unexpected character in <unqualified-name>.";
1337 /* Demangles and emits <source-name>.
1339 <source-name> ::= <length number> <identifier> */
1342 demangle_source_name (dm
)
1347 DEMANGLE_TRACE ("source-name", dm
);
1349 /* Decode the length of the identifier. */
1350 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1352 return "Zero length in <source-name>.";
1354 /* Now the identifier itself. It's placed into last_source_name,
1355 where it can be used to build a constructor or destructor name. */
1356 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1357 dm
->last_source_name
));
1360 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
1365 /* Demangles a number, either a <number> or a <positive-number> at the
1366 current position, consuming all consecutive digit characters. Sets
1367 *VALUE to the resulting numberand returns STATUS_OK. The number is
1368 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1369 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1371 <number> ::= [n] <positive-number>
1373 <positive-number> ::= <decimal integer> */
1376 demangle_number (dm
, value
, base
, is_signed
)
1382 dyn_string_t number
= dyn_string_new (10);
1384 DEMANGLE_TRACE ("number", dm
);
1387 return STATUS_ALLOCATION_FAILED
;
1389 demangle_number_literally (dm
, number
, base
, is_signed
);
1390 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1391 dyn_string_delete (number
);
1396 /* Demangles a number at the current position. The digits (and minus
1397 sign, if present) that make up the number are appended to STR.
1398 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1399 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1400 accepted. Does not consume a trailing underscore or other
1401 terminating character. */
1404 demangle_number_literally (dm
, str
, base
, is_signed
)
1410 DEMANGLE_TRACE ("number*", dm
);
1412 if (base
!= 10 && base
!= 36)
1413 return STATUS_INTERNAL_ERROR
;
1415 /* An `n' denotes a negative number. */
1416 if (is_signed
&& peek_char (dm
) == 'n')
1418 /* Skip past the n. */
1420 /* The normal way to write a negative number is with a minus
1422 if (!dyn_string_append_char (str
, '-'))
1423 return STATUS_ALLOCATION_FAILED
;
1426 /* Loop until we hit a non-digit. */
1429 char peek
= peek_char (dm
);
1430 if (IS_DIGIT ((unsigned char) peek
)
1431 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1433 /* Accumulate digits. */
1434 if (!dyn_string_append_char (str
, next_char (dm
)))
1435 return STATUS_ALLOCATION_FAILED
;
1438 /* Not a digit? All done. */
1445 /* Demangles an identifier at the current position of LENGTH
1446 characters and places it in IDENTIFIER. */
1449 demangle_identifier (dm
, length
, identifier
)
1452 dyn_string_t identifier
;
1454 DEMANGLE_TRACE ("identifier", dm
);
1456 dyn_string_clear (identifier
);
1457 if (!dyn_string_resize (identifier
, length
))
1458 return STATUS_ALLOCATION_FAILED
;
1460 while (length
-- > 0)
1462 if (end_of_name_p (dm
))
1463 return "Unexpected end of name in <identifier>.";
1464 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1465 return STATUS_ALLOCATION_FAILED
;
1468 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1469 followed by the source file name and some random characters.
1470 Unless we're in strict mode, decipher these names appropriately. */
1473 char *name
= dyn_string_buf (identifier
);
1474 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1476 /* Compare the first, fixed part. */
1477 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1479 name
+= prefix_length
;
1480 /* The next character might be a period, an underscore, or
1481 dollar sign, depending on the target architecture's
1482 assembler's capabilities. After that comes an `N'. */
1483 if ((*name
== '.' || *name
== '_' || *name
== '$')
1484 && *(name
+ 1) == 'N')
1485 /* This looks like the anonymous namespace identifier.
1486 Replace it with something comprehensible. */
1487 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1494 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1495 the short form is emitted; otherwise the full source form
1496 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1497 operands that the operator takes.
1548 ::= cv <type> # cast
1549 ::= v [0-9] <source-name> # vendor extended operator */
1552 demangle_operator_name (dm
, short_name
, num_args
)
1557 struct operator_code
1559 /* The mangled code for this operator. */
1561 /* The source name of this operator. */
1563 /* The number of arguments this operator takes. */
1567 static const struct operator_code operators
[] =
1578 { "da", " delete[]", 1 },
1580 { "dl", " delete" , 1 },
1588 { "lS", "<<=" , 2 },
1597 { "na", " new[]" , 1 },
1601 { "nw", " new" , 1 },
1607 { "pm", "->*" , 2 },
1613 { "rS", ">>=" , 2 },
1616 { "sz", " sizeof" , 1 }
1619 const int num_operators
=
1620 sizeof (operators
) / sizeof (struct operator_code
);
1622 int c0
= next_char (dm
);
1623 int c1
= next_char (dm
);
1624 const struct operator_code
* p1
= operators
;
1625 const struct operator_code
* p2
= operators
+ num_operators
;
1627 DEMANGLE_TRACE ("operator-name", dm
);
1629 /* Is this a vendor-extended operator? */
1630 if (c0
== 'v' && IS_DIGIT (c1
))
1632 RETURN_IF_ERROR (result_add (dm
, "operator "));
1633 RETURN_IF_ERROR (demangle_source_name (dm
));
1638 /* Is this a conversion operator? */
1639 if (c0
== 'c' && c1
== 'v')
1641 RETURN_IF_ERROR (result_add (dm
, "operator "));
1642 /* Demangle the converted-to type. */
1643 RETURN_IF_ERROR (demangle_type (dm
));
1648 /* Perform a binary search for the operator code. */
1651 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1652 char match0
= p
->code
[0];
1653 char match1
= p
->code
[1];
1655 if (c0
== match0
&& c1
== match1
)
1659 RETURN_IF_ERROR (result_add (dm
, "operator"));
1660 RETURN_IF_ERROR (result_add (dm
, p
->name
));
1661 *num_args
= p
->num_args
;
1667 /* Couldn't find it. */
1668 return "Unknown code in <operator-name>.";
1671 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1678 /* Demangles and omits an <nv-offset>.
1680 <nv-offset> ::= <offset number> # non-virtual base override */
1683 demangle_nv_offset (dm
)
1686 dyn_string_t number
;
1687 status_t status
= STATUS_OK
;
1689 DEMANGLE_TRACE ("h-offset", dm
);
1691 /* Demangle the offset. */
1692 number
= dyn_string_new (4);
1694 return STATUS_ALLOCATION_FAILED
;
1695 demangle_number_literally (dm
, number
, 10, 1);
1697 /* Don't display the offset unless in verbose mode. */
1700 status
= result_add (dm
, " [nv:");
1701 if (STATUS_NO_ERROR (status
))
1702 status
= result_add_string (dm
, number
);
1703 if (STATUS_NO_ERROR (status
))
1704 status
= result_add_char (dm
, ']');
1708 dyn_string_delete (number
);
1709 RETURN_IF_ERROR (status
);
1713 /* Demangles and emits a <v-offset>.
1715 <v-offset> ::= <offset number> _ <virtual offset number>
1716 # virtual base override, with vcall offset */
1719 demangle_v_offset (dm
)
1722 dyn_string_t number
;
1723 status_t status
= STATUS_OK
;
1725 DEMANGLE_TRACE ("v-offset", dm
);
1727 /* Demangle the offset. */
1728 number
= dyn_string_new (4);
1730 return STATUS_ALLOCATION_FAILED
;
1731 demangle_number_literally (dm
, number
, 10, 1);
1733 /* Don't display the offset unless in verbose mode. */
1736 status
= result_add (dm
, " [v:");
1737 if (STATUS_NO_ERROR (status
))
1738 status
= result_add_string (dm
, number
);
1739 if (STATUS_NO_ERROR (status
))
1740 result_add_char (dm
, ',');
1742 dyn_string_delete (number
);
1743 RETURN_IF_ERROR (status
);
1745 /* Demangle the separator. */
1746 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1748 /* Demangle the vcall offset. */
1749 number
= dyn_string_new (4);
1751 return STATUS_ALLOCATION_FAILED
;
1752 demangle_number_literally (dm
, number
, 10, 1);
1754 /* Don't display the vcall offset unless in verbose mode. */
1757 status
= result_add_string (dm
, number
);
1758 if (STATUS_NO_ERROR (status
))
1759 status
= result_add_char (dm
, ']');
1761 dyn_string_delete (number
);
1762 RETURN_IF_ERROR (status
);
1767 /* Demangles and emits a <call-offset>.
1769 <call-offset> ::= h <nv-offset> _
1770 ::= v <v-offset> _ */
1773 demangle_call_offset (dm
)
1776 DEMANGLE_TRACE ("call-offset", dm
);
1778 switch (peek_char (dm
))
1782 /* Demangle the offset. */
1783 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1784 /* Demangle the separator. */
1785 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1790 /* Demangle the offset. */
1791 RETURN_IF_ERROR (demangle_v_offset (dm
));
1792 /* Demangle the separator. */
1793 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1797 return "Unrecognized <call-offset>.";
1803 /* Demangles and emits a <special-name>.
1805 <special-name> ::= GV <object name> # Guard variable
1806 ::= TV <type> # virtual table
1808 ::= TI <type> # typeinfo structure
1809 ::= TS <type> # typeinfo name
1811 Other relevant productions include thunks:
1813 <special-name> ::= T <call-offset> <base encoding>
1814 # base is the nominal target function of thunk
1816 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1817 # base is the nominal target function of thunk
1818 # first call-offset is 'this' adjustment
1819 # second call-offset is result adjustment
1823 <call-offset> ::= h <nv-offset> _
1826 Also demangles the special g++ manglings,
1828 <special-name> ::= TC <type> <offset number> _ <base type>
1829 # construction vtable
1830 ::= TF <type> # typeinfo function (old ABI only)
1831 ::= TJ <type> # java Class structure */
1834 demangle_special_name (dm
)
1837 dyn_string_t number
;
1839 char peek
= peek_char (dm
);
1841 DEMANGLE_TRACE ("special-name", dm
);
1845 /* Consume the G. */
1847 switch (peek_char (dm
))
1850 /* A guard variable name. */
1852 RETURN_IF_ERROR (result_add (dm
, "guard variable for "));
1853 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1857 /* A reference temporary. */
1859 RETURN_IF_ERROR (result_add (dm
, "reference temporary for "));
1860 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1864 return "Unrecognized <special-name>.";
1867 else if (peek
== 'T')
1869 status_t status
= STATUS_OK
;
1871 /* Other C++ implementation miscellania. Consume the T. */
1874 switch (peek_char (dm
))
1877 /* Virtual table. */
1879 RETURN_IF_ERROR (result_add (dm
, "vtable for "));
1880 RETURN_IF_ERROR (demangle_type (dm
));
1884 /* VTT structure. */
1886 RETURN_IF_ERROR (result_add (dm
, "VTT for "));
1887 RETURN_IF_ERROR (demangle_type (dm
));
1891 /* Typeinfo structure. */
1893 RETURN_IF_ERROR (result_add (dm
, "typeinfo for "));
1894 RETURN_IF_ERROR (demangle_type (dm
));
1898 /* Typeinfo function. Used only in old ABI with new mangling. */
1900 RETURN_IF_ERROR (result_add (dm
, "typeinfo fn for "));
1901 RETURN_IF_ERROR (demangle_type (dm
));
1905 /* Character string containing type name, used in typeinfo. */
1907 RETURN_IF_ERROR (result_add (dm
, "typeinfo name for "));
1908 RETURN_IF_ERROR (demangle_type (dm
));
1912 /* The java Class variable corresponding to a C++ class. */
1914 RETURN_IF_ERROR (result_add (dm
, "java Class for "));
1915 RETURN_IF_ERROR (demangle_type (dm
));
1919 /* Non-virtual thunk. */
1921 RETURN_IF_ERROR (result_add (dm
, "non-virtual thunk"));
1922 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1923 /* Demangle the separator. */
1924 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1925 /* Demangle and emit the target name and function type. */
1926 RETURN_IF_ERROR (result_add (dm
, " to "));
1927 RETURN_IF_ERROR (demangle_encoding (dm
));
1931 /* Virtual thunk. */
1933 RETURN_IF_ERROR (result_add (dm
, "virtual thunk"));
1934 RETURN_IF_ERROR (demangle_v_offset (dm
));
1935 /* Demangle the separator. */
1936 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1937 /* Demangle and emit the target function. */
1938 RETURN_IF_ERROR (result_add (dm
, " to "));
1939 RETURN_IF_ERROR (demangle_encoding (dm
));
1943 /* Covariant return thunk. */
1945 RETURN_IF_ERROR (result_add (dm
, "covariant return thunk"));
1946 RETURN_IF_ERROR (demangle_call_offset (dm
));
1947 RETURN_IF_ERROR (demangle_call_offset (dm
));
1948 /* Demangle and emit the target function. */
1949 RETURN_IF_ERROR (result_add (dm
, " to "));
1950 RETURN_IF_ERROR (demangle_encoding (dm
));
1954 /* TC is a special g++ mangling for a construction vtable. */
1957 dyn_string_t derived_type
;
1960 RETURN_IF_ERROR (result_add (dm
, "construction vtable for "));
1962 /* Demangle the derived type off to the side. */
1963 RETURN_IF_ERROR (result_push (dm
));
1964 RETURN_IF_ERROR (demangle_type (dm
));
1965 derived_type
= (dyn_string_t
) result_pop (dm
);
1967 /* Demangle the offset. */
1968 number
= dyn_string_new (4);
1971 dyn_string_delete (derived_type
);
1972 return STATUS_ALLOCATION_FAILED
;
1974 demangle_number_literally (dm
, number
, 10, 1);
1975 /* Demangle the underscore separator. */
1976 status
= demangle_char (dm
, '_');
1978 /* Demangle the base type. */
1979 if (STATUS_NO_ERROR (status
))
1980 status
= demangle_type (dm
);
1982 /* Emit the derived type. */
1983 if (STATUS_NO_ERROR (status
))
1984 status
= result_add (dm
, "-in-");
1985 if (STATUS_NO_ERROR (status
))
1986 status
= result_add_string (dm
, derived_type
);
1987 dyn_string_delete (derived_type
);
1989 /* Don't display the offset unless in verbose mode. */
1992 status
= result_add_char (dm
, ' ');
1993 if (STATUS_NO_ERROR (status
))
1994 result_add_string (dm
, number
);
1996 dyn_string_delete (number
);
1997 RETURN_IF_ERROR (status
);
2000 /* If flag_strict, fall through. */
2003 return "Unrecognized <special-name>.";
2007 return STATUS_ERROR
;
2012 /* Demangles and emits a <ctor-dtor-name>.
2015 ::= C1 # complete object (in-charge) ctor
2016 ::= C2 # base object (not-in-charge) ctor
2017 ::= C3 # complete object (in-charge) allocating ctor
2018 ::= D0 # deleting (in-charge) dtor
2019 ::= D1 # complete object (in-charge) dtor
2020 ::= D2 # base object (not-in-charge) dtor */
2023 demangle_ctor_dtor_name (dm
)
2026 static const char *const ctor_flavors
[] =
2032 static const char *const dtor_flavors
[] =
2034 "in-charge deleting",
2040 char peek
= peek_char (dm
);
2042 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
2046 /* A constructor name. Consume the C. */
2048 flavor
= next_char (dm
);
2049 if (flavor
< '1' || flavor
> '3')
2050 return "Unrecognized constructor.";
2051 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2054 case '1': dm
->is_constructor
= gnu_v3_complete_object_ctor
;
2056 case '2': dm
->is_constructor
= gnu_v3_base_object_ctor
;
2058 case '3': dm
->is_constructor
= gnu_v3_complete_object_allocating_ctor
;
2061 /* Print the flavor of the constructor if in verbose mode. */
2064 RETURN_IF_ERROR (result_add (dm
, "["));
2065 RETURN_IF_ERROR (result_add (dm
, ctor_flavors
[flavor
- '1']));
2066 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2069 else if (peek
== 'D')
2071 /* A destructor name. Consume the D. */
2073 flavor
= next_char (dm
);
2074 if (flavor
< '0' || flavor
> '2')
2075 return "Unrecognized destructor.";
2076 RETURN_IF_ERROR (result_add_char (dm
, '~'));
2077 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2080 case '0': dm
->is_destructor
= gnu_v3_deleting_dtor
;
2082 case '1': dm
->is_destructor
= gnu_v3_complete_object_dtor
;
2084 case '2': dm
->is_destructor
= gnu_v3_base_object_dtor
;
2087 /* Print the flavor of the destructor if in verbose mode. */
2090 RETURN_IF_ERROR (result_add (dm
, " ["));
2091 RETURN_IF_ERROR (result_add (dm
, dtor_flavors
[flavor
- '0']));
2092 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2096 return STATUS_ERROR
;
2101 /* Handle pointer, reference, and pointer-to-member cases for
2102 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2103 build a pointer/reference type. We snarf all these, plus the
2104 following <type>, all at once since we need to know whether we have
2105 a pointer to data or pointer to function to construct the right
2106 output syntax. C++'s pointer syntax is hairy.
2108 This function adds substitution candidates for every nested
2109 pointer/reference type it processes, including the outermost, final
2110 type, assuming the substitution starts at SUBSTITUTION_START in the
2111 demangling result. For example, if this function demangles
2112 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2113 `Foo**', in that order.
2115 *INSERT_POS is a quantity used internally, when this function calls
2116 itself recursively, to figure out where to insert pointer
2117 punctuation on the way up. On entry to this function, INSERT_POS
2118 should point to a temporary value, but that value need not be
2123 ::= <pointer-to-member-type>
2125 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2128 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2131 int substitution_start
;
2134 int is_substitution_candidate
= 1;
2136 DEMANGLE_TRACE ("type*", dm
);
2138 /* Scan forward, collecting pointers and references into symbols,
2139 until we hit something else. Then emit the type. */
2140 switch (peek_char (dm
))
2143 /* A pointer. Snarf the `P'. */
2145 /* Demangle the underlying type. */
2146 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2147 substitution_start
));
2148 /* Insert an asterisk where we're told to; it doesn't
2149 necessarily go at the end. If we're doing Java style output,
2150 there is no pointer symbol. */
2151 if (dm
->style
!= DMGL_JAVA
)
2152 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2153 /* The next (outermost) pointer or reference character should go
2159 /* A reference. Snarf the `R'. */
2161 /* Demangle the underlying type. */
2162 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2163 substitution_start
));
2164 /* Insert an ampersand where we're told to; it doesn't
2165 necessarily go at the end. */
2166 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2167 /* The next (outermost) pointer or reference character should go
2174 /* A pointer-to-member. */
2175 dyn_string_t class_type
;
2180 /* Capture the type of which this is a pointer-to-member. */
2181 RETURN_IF_ERROR (result_push (dm
));
2182 RETURN_IF_ERROR (demangle_type (dm
));
2183 class_type
= (dyn_string_t
) result_pop (dm
);
2185 if (peek_char (dm
) == 'F')
2186 /* A pointer-to-member function. We want output along the
2187 lines of `void (C::*) (int, int)'. Demangle the function
2188 type, which would in this case give `void () (int, int)'
2189 and set *insert_pos to the spot between the first
2191 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2192 else if (peek_char (dm
) == 'A')
2193 /* A pointer-to-member array variable. We want output that
2194 looks like `int (Klass::*) [10]'. Demangle the array type
2195 as `int () [10]', and set *insert_pos to the spot between
2197 status
= demangle_array_type (dm
, insert_pos
);
2200 /* A pointer-to-member variable. Demangle the type of the
2201 pointed-to member. */
2202 status
= demangle_type (dm
);
2203 /* Make it pretty. */
2204 if (STATUS_NO_ERROR (status
)
2205 && !result_previous_char_is_space (dm
))
2206 status
= result_add_char (dm
, ' ');
2207 /* The pointer-to-member notation (e.g. `C::*') follows the
2209 *insert_pos
= result_caret_pos (dm
);
2212 /* Build the pointer-to-member notation. */
2213 if (STATUS_NO_ERROR (status
))
2214 status
= result_insert (dm
, *insert_pos
, "::*");
2215 if (STATUS_NO_ERROR (status
))
2216 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2217 /* There may be additional levels of (pointer or reference)
2218 indirection in this type. If so, the `*' and `&' should be
2219 added after the pointer-to-member notation (e.g. `C::*&' for
2220 a reference to a pointer-to-member of class C). */
2221 *insert_pos
+= dyn_string_length (class_type
) + 3;
2224 dyn_string_delete (class_type
);
2226 RETURN_IF_ERROR (status
);
2231 /* Ooh, tricky, a pointer-to-function. When we demangle the
2232 function type, the return type should go at the very
2234 *insert_pos
= result_caret_pos (dm
);
2235 /* The parentheses indicate this is a function pointer or
2237 RETURN_IF_ERROR (result_add (dm
, "()"));
2238 /* Now demangle the function type. The return type will be
2239 inserted before the `()', and the argument list will go after
2241 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2242 /* We should now have something along the lines of
2243 `void () (int, int)'. The pointer or reference characters
2244 have to inside the first set of parentheses. *insert_pos has
2245 already been updated to point past the end of the return
2246 type. Move it one character over so it points inside the
2252 /* An array pointer or reference. demangle_array_type will figure
2253 out where the asterisks and ampersands go. */
2254 RETURN_IF_ERROR (demangle_array_type (dm
, insert_pos
));
2258 /* No more pointer or reference tokens; this is therefore a
2259 pointer to data. Finish up by demangling the underlying
2261 RETURN_IF_ERROR (demangle_type (dm
));
2262 /* The pointer or reference characters follow the underlying
2263 type, as in `int*&'. */
2264 *insert_pos
= result_caret_pos (dm
);
2265 /* Because of the production <type> ::= <substitution>,
2266 demangle_type will already have added the underlying type as
2267 a substitution candidate. Don't do it again. */
2268 is_substitution_candidate
= 0;
2272 if (is_substitution_candidate
)
2273 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2278 /* Demangles and emits a <type>.
2280 <type> ::= <builtin-type>
2282 ::= <class-enum-type>
2284 ::= <pointer-to-member-type>
2285 ::= <template-param>
2286 ::= <template-template-param> <template-args>
2287 ::= <CV-qualifiers> <type>
2288 ::= P <type> # pointer-to
2289 ::= R <type> # reference-to
2290 ::= C <type> # complex pair (C 2000)
2291 ::= G <type> # imaginary (C 2000)
2292 ::= U <source-name> <type> # vendor extended type qualifier
2293 ::= <substitution> */
2299 int start
= substitution_start (dm
);
2300 char peek
= peek_char (dm
);
2302 int encode_return_type
= 0;
2303 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2306 /* A <type> can be a <substitution>; therefore, this <type> is a
2307 substitution candidate unless a special condition holds (see
2309 int is_substitution_candidate
= 1;
2311 DEMANGLE_TRACE ("type", dm
);
2313 /* A <class-enum-type> can start with a digit (a <source-name>), an
2314 N (a <nested-name>), or a Z (a <local-name>). */
2315 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2316 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2317 /* Lower-case letters begin <builtin-type>s, except for `r', which
2318 denotes restrict. */
2319 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2321 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2322 /* Built-in types are not substitution candidates. */
2323 is_substitution_candidate
= 0;
2331 /* CV-qualifiers (including restrict). We have to demangle
2332 them off to the side, since C++ syntax puts them in a funny
2333 place for qualified pointer and reference types. */
2336 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2337 int old_caret_position
= result_get_caret (dm
);
2339 if (cv_qualifiers
== NULL
)
2340 return STATUS_ALLOCATION_FAILED
;
2342 /* Decode all adjacent CV qualifiers. */
2343 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2344 /* Emit them, and shift the caret left so that the
2345 underlying type will be emitted before the qualifiers. */
2346 status
= result_add_string (dm
, cv_qualifiers
);
2347 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2349 dyn_string_delete (cv_qualifiers
);
2350 RETURN_IF_ERROR (status
);
2351 /* Also prepend a blank, if needed. */
2352 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2353 result_shift_caret (dm
, -1);
2355 /* Demangle the underlying type. It will be emitted before
2356 the CV qualifiers, since we moved the caret. */
2357 RETURN_IF_ERROR (demangle_type (dm
));
2359 /* Put the caret back where it was previously. */
2360 result_set_caret (dm
, old_caret_position
);
2365 return "Non-pointer or -reference function type.";
2368 RETURN_IF_ERROR (demangle_array_type (dm
, NULL
));
2372 /* It's either a <template-param> or a
2373 <template-template-param>. In either case, demangle the
2375 RETURN_IF_ERROR (demangle_template_param (dm
));
2377 /* Check for a template argument list; if one is found, it's a
2378 <template-template-param> ::= <template-param>
2379 ::= <substitution> */
2380 if (peek_char (dm
) == 'I')
2382 /* Add a substitution candidate. The template parameter
2383 `T' token is a substitution candidate by itself,
2384 without the template argument list. */
2385 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2387 /* Now demangle the template argument list. */
2388 RETURN_IF_ERROR (demangle_template_args (dm
));
2389 /* The entire type, including the template template
2390 parameter and its argument list, will be added as a
2391 substitution candidate below. */
2397 /* First check if this is a special substitution. If it is,
2398 this is a <class-enum-type>. Special substitutions have a
2399 letter following the `S'; other substitutions have a digit
2401 peek_next
= peek_char_next (dm
);
2402 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2404 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2406 /* The substituted name may have been a template name.
2407 Check if template arguments follow, and if so, demangle
2409 if (peek_char (dm
) == 'I')
2410 RETURN_IF_ERROR (demangle_template_args (dm
));
2412 /* A substitution token is not itself a substitution
2413 candidate. (However, if the substituted template is
2414 instantiated, the resulting type is.) */
2415 is_substitution_candidate
= 0;
2419 /* Now some trickiness. We have a special substitution
2420 here. Often, the special substitution provides the
2421 name of a template that's subsequently instantiated,
2422 for instance `SaIcE' => std::allocator<char>. In these
2423 cases we need to add a substitution candidate for the
2424 entire <class-enum-type> and thus don't want to clear
2425 the is_substitution_candidate flag.
2427 However, it's possible that what we have here is a
2428 substitution token representing an entire type, such as
2429 `Ss' => std::string. In this case, we mustn't add a
2430 new substitution candidate for this substitution token.
2431 To detect this case, remember where the start of the
2432 substitution token is. */
2433 const char *next
= dm
->next
;
2434 /* Now demangle the <class-enum-type>. */
2436 (demangle_class_enum_type (dm
, &encode_return_type
));
2437 /* If all that was just demangled is the two-character
2438 special substitution token, supress the addition of a
2439 new candidate for it. */
2440 if (dm
->next
== next
+ 2)
2441 is_substitution_candidate
= 0;
2449 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2450 /* demangle_type_ptr adds all applicable substitution
2452 is_substitution_candidate
= 0;
2456 /* A C99 complex type. */
2457 RETURN_IF_ERROR (result_add (dm
, "complex "));
2459 RETURN_IF_ERROR (demangle_type (dm
));
2463 /* A C99 imaginary type. */
2464 RETURN_IF_ERROR (result_add (dm
, "imaginary "));
2466 RETURN_IF_ERROR (demangle_type (dm
));
2470 /* Vendor-extended type qualifier. */
2472 RETURN_IF_ERROR (demangle_source_name (dm
));
2473 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2474 RETURN_IF_ERROR (demangle_type (dm
));
2478 return "Unexpected character in <type>.";
2481 if (is_substitution_candidate
)
2482 /* Add a new substitution for the type. If this type was a
2483 <template-param>, pass its index since from the point of
2484 substitutions; a <template-param> token is a substitution
2485 candidate distinct from the type that is substituted for it. */
2486 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2488 /* Pop off template argument lists added during mangling of this
2490 pop_to_template_arg_list (dm
, old_arg_list
);
2495 /* C++ source names of builtin types, indexed by the mangled code
2496 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2497 static const char *const builtin_type_names
[26] =
2499 "signed char", /* a */
2503 "long double", /* e */
2505 "__float128", /* g */
2506 "unsigned char", /* h */
2511 "unsigned long", /* m */
2513 "unsigned __int128", /* o */
2518 "unsigned short", /* t */
2522 "long long", /* x */
2523 "unsigned long long", /* y */
2527 /* Java source names of builtin types. Types that arn't valid in Java
2528 are also included here - we don't fail if someone attempts to demangle a
2529 C++ symbol in Java style. */
2530 static const char *const java_builtin_type_names
[26] =
2532 "signed char", /* a */
2533 "boolean", /* C++ "bool" */ /* b */
2534 "byte", /* C++ "char" */ /* c */
2536 "long double", /* e */
2538 "__float128", /* g */
2539 "unsigned char", /* h */
2544 "unsigned long", /* m */
2546 "unsigned __int128", /* o */
2551 "unsigned short", /* t */
2554 "char", /* C++ "wchar_t" */ /* w */
2555 "long", /* C++ "long long" */ /* x */
2556 "unsigned long long", /* y */
2560 /* Demangles and emits a <builtin-type>.
2562 <builtin-type> ::= v # void
2567 ::= h # unsigned char
2569 ::= t # unsigned short
2571 ::= j # unsigned int
2573 ::= m # unsigned long
2574 ::= x # long long, __int64
2575 ::= y # unsigned long long, __int64
2577 ::= o # unsigned __int128
2580 ::= e # long double, __float80
2583 ::= u <source-name> # vendor extended type */
2586 demangle_builtin_type (dm
)
2590 char code
= peek_char (dm
);
2592 DEMANGLE_TRACE ("builtin-type", dm
);
2597 RETURN_IF_ERROR (demangle_source_name (dm
));
2600 else if (code
>= 'a' && code
<= 'z')
2602 const char *type_name
;
2603 /* Java uses different names for some built-in types. */
2604 if (dm
->style
== DMGL_JAVA
)
2605 type_name
= java_builtin_type_names
[code
- 'a'];
2607 type_name
= builtin_type_names
[code
- 'a'];
2608 if (type_name
== NULL
)
2609 return "Unrecognized <builtin-type> code.";
2611 RETURN_IF_ERROR (result_add (dm
, type_name
));
2616 return "Non-alphabetic <builtin-type> code.";
2619 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2620 restrict) at the current position. The qualifiers are appended to
2621 QUALIFIERS. Returns STATUS_OK. */
2624 demangle_CV_qualifiers (dm
, qualifiers
)
2626 dyn_string_t qualifiers
;
2628 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2632 switch (peek_char (dm
))
2635 if (!dyn_string_append_space (qualifiers
))
2636 return STATUS_ALLOCATION_FAILED
;
2637 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2638 return STATUS_ALLOCATION_FAILED
;
2642 if (!dyn_string_append_space (qualifiers
))
2643 return STATUS_ALLOCATION_FAILED
;
2644 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2645 return STATUS_ALLOCATION_FAILED
;
2649 if (!dyn_string_append_space (qualifiers
))
2650 return STATUS_ALLOCATION_FAILED
;
2651 if (!dyn_string_append_cstr (qualifiers
, "const"))
2652 return STATUS_ALLOCATION_FAILED
;
2663 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2664 position in the result string of the start of the function
2665 identifier, at which the function's return type will be inserted;
2666 *FUNCTION_NAME_POS is updated to position past the end of the
2667 function's return type.
2669 <function-type> ::= F [Y] <bare-function-type> E */
2672 demangle_function_type (dm
, function_name_pos
)
2674 int *function_name_pos
;
2676 DEMANGLE_TRACE ("function-type", dm
);
2677 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2678 if (peek_char (dm
) == 'Y')
2680 /* Indicate this function has C linkage if in verbose mode. */
2682 RETURN_IF_ERROR (result_add (dm
, " [extern \"C\"] "));
2685 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2686 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2690 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2691 position in the result string at which the function return type
2692 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2693 function's return type is assumed not to be encoded.
2695 <bare-function-type> ::= <signature type>+ */
2698 demangle_bare_function_type (dm
, return_type_pos
)
2700 int *return_type_pos
;
2702 /* Sequence is the index of the current function parameter, counting
2703 from zero. The value -1 denotes the return type. */
2705 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2707 DEMANGLE_TRACE ("bare-function-type", dm
);
2709 RETURN_IF_ERROR (result_add_char (dm
, '('));
2710 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2713 /* We're decoding the function's return type. */
2715 dyn_string_t return_type
;
2716 status_t status
= STATUS_OK
;
2718 /* Decode the return type off to the side. */
2719 RETURN_IF_ERROR (result_push (dm
));
2720 RETURN_IF_ERROR (demangle_type (dm
));
2721 return_type
= (dyn_string_t
) result_pop (dm
);
2723 /* Add a space to the end of the type. Insert the return
2724 type where we've been asked to. */
2725 if (!dyn_string_append_space (return_type
))
2726 status
= STATUS_ALLOCATION_FAILED
;
2727 if (STATUS_NO_ERROR (status
))
2729 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2731 status
= STATUS_ALLOCATION_FAILED
;
2733 *return_type_pos
+= dyn_string_length (return_type
);
2736 dyn_string_delete (return_type
);
2737 RETURN_IF_ERROR (status
);
2741 /* Skip `void' parameter types. One should only occur as
2742 the only type in a parameter list; in that case, we want
2743 to print `foo ()' instead of `foo (void)'. */
2744 if (peek_char (dm
) == 'v')
2745 /* Consume the v. */
2749 /* Separate parameter types by commas. */
2751 RETURN_IF_ERROR (result_add (dm
, ", "));
2752 /* Demangle the type. */
2753 RETURN_IF_ERROR (demangle_type (dm
));
2759 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2761 /* We should have demangled at least one parameter type (which would
2762 be void, for a function that takes no parameters), plus the
2763 return type, if we were supposed to demangle that. */
2765 return "Missing function return type.";
2766 else if (sequence
== 0)
2767 return "Missing function parameter.";
2772 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2773 non-zero if the type is a template-id, zero otherwise.
2775 <class-enum-type> ::= <name> */
2778 demangle_class_enum_type (dm
, encode_return_type
)
2780 int *encode_return_type
;
2782 DEMANGLE_TRACE ("class-enum-type", dm
);
2784 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2788 /* Demangles and emits an <array-type>.
2790 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2791 pointer or reference to an array, except that asterisk and
2792 ampersand punctuation is omitted (since it's not know at this
2793 point). *PTR_INSERT_POS is set to the position in the demangled
2794 name at which this punctuation should be inserted. For example,
2795 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2796 between the parentheses.
2798 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2799 pointer- or reference-qualified. Then, for example, `A10_i' is
2800 demangled simply as `int[10]'.
2802 <array-type> ::= A [<dimension number>] _ <element type>
2803 ::= A <dimension expression> _ <element type> */
2806 demangle_array_type (dm
, ptr_insert_pos
)
2808 int *ptr_insert_pos
;
2810 status_t status
= STATUS_OK
;
2811 dyn_string_t array_size
= NULL
;
2814 DEMANGLE_TRACE ("array-type", dm
);
2816 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2818 /* Demangle the array size into array_size. */
2819 peek
= peek_char (dm
);
2821 /* Array bound is omitted. This is a C99-style VLA. */
2823 else if (IS_DIGIT (peek_char (dm
)))
2825 /* It looks like a constant array bound. */
2826 array_size
= dyn_string_new (10);
2827 if (array_size
== NULL
)
2828 return STATUS_ALLOCATION_FAILED
;
2829 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2833 /* Anything is must be an expression for a nont-constant array
2834 bound. This happens if the array type occurs in a template
2835 and the array bound references a template parameter. */
2836 RETURN_IF_ERROR (result_push (dm
));
2837 RETURN_IF_ERROR (demangle_expression (dm
));
2838 array_size
= (dyn_string_t
) result_pop (dm
);
2840 /* array_size may have been allocated by now, so we can't use
2841 RETURN_IF_ERROR until it's been deallocated. */
2843 /* Demangle the base type of the array. */
2844 if (STATUS_NO_ERROR (status
))
2845 status
= demangle_char (dm
, '_');
2846 if (STATUS_NO_ERROR (status
))
2847 status
= demangle_type (dm
);
2849 if (ptr_insert_pos
!= NULL
)
2851 /* This array is actually part of an pointer- or
2852 reference-to-array type. Format appropriately, except we
2853 don't know which and how much punctuation to use. */
2854 if (STATUS_NO_ERROR (status
))
2855 status
= result_add (dm
, " () ");
2856 /* Let the caller know where to insert the punctuation. */
2857 *ptr_insert_pos
= result_caret_pos (dm
) - 2;
2860 /* Emit the array dimension syntax. */
2861 if (STATUS_NO_ERROR (status
))
2862 status
= result_add_char (dm
, '[');
2863 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2864 status
= result_add_string (dm
, array_size
);
2865 if (STATUS_NO_ERROR (status
))
2866 status
= result_add_char (dm
, ']');
2867 if (array_size
!= NULL
)
2868 dyn_string_delete (array_size
);
2870 RETURN_IF_ERROR (status
);
2875 /* Demangles and emits a <template-param>.
2877 <template-param> ::= T_ # first template parameter
2878 ::= T <parameter-2 number> _ */
2881 demangle_template_param (dm
)
2885 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2888 DEMANGLE_TRACE ("template-param", dm
);
2890 /* Make sure there is a template argmust list in which to look up
2891 this parameter reference. */
2892 if (current_arg_list
== NULL
)
2893 return "Template parameter outside of template.";
2895 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2896 if (peek_char (dm
) == '_')
2900 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2903 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2905 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2907 /* parm_number exceeded the number of arguments in the current
2908 template argument list. */
2909 return "Template parameter number out of bounds.";
2910 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2915 /* Demangles and emits a <template-args>.
2917 <template-args> ::= I <template-arg>+ E */
2920 demangle_template_args (dm
)
2924 dyn_string_t old_last_source_name
;
2925 template_arg_list_t arg_list
= template_arg_list_new ();
2927 if (arg_list
== NULL
)
2928 return STATUS_ALLOCATION_FAILED
;
2930 /* Preserve the most recently demangled source name. */
2931 old_last_source_name
= dm
->last_source_name
;
2932 dm
->last_source_name
= dyn_string_new (0);
2934 DEMANGLE_TRACE ("template-args", dm
);
2936 if (dm
->last_source_name
== NULL
)
2937 return STATUS_ALLOCATION_FAILED
;
2939 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2940 RETURN_IF_ERROR (result_open_template_list (dm
));
2948 RETURN_IF_ERROR (result_add (dm
, ", "));
2950 /* Capture the template arg. */
2951 RETURN_IF_ERROR (result_push (dm
));
2952 RETURN_IF_ERROR (demangle_template_arg (dm
));
2953 arg
= result_pop (dm
);
2955 /* Emit it in the demangled name. */
2956 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2958 /* Save it for use in expanding <template-param>s. */
2959 template_arg_list_add_arg (arg_list
, arg
);
2961 while (peek_char (dm
) != 'E');
2962 /* Append the '>'. */
2963 RETURN_IF_ERROR (result_close_template_list (dm
));
2965 /* Consume the 'E'. */
2968 /* Restore the most recent demangled source name. */
2969 dyn_string_delete (dm
->last_source_name
);
2970 dm
->last_source_name
= old_last_source_name
;
2972 /* Push the list onto the top of the stack of template argument
2973 lists, so that arguments from it are used from now on when
2974 expanding <template-param>s. */
2975 push_template_arg_list (dm
, arg_list
);
2980 /* This function, which does not correspond to a production in the
2981 mangling spec, handles the `literal' production for both
2982 <template-arg> and <expr-primary>. It does not expect or consume
2983 the initial `L' or final `E'. The demangling is given by:
2985 <literal> ::= <type> </value/ number>
2987 and the emitted output is `(type)number'. */
2990 demangle_literal (dm
)
2993 char peek
= peek_char (dm
);
2994 dyn_string_t value_string
;
2997 DEMANGLE_TRACE ("literal", dm
);
2999 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
3001 /* If not in verbose mode and this is a builtin type, see if we
3002 can produce simpler numerical output. In particular, for
3003 integer types shorter than `long', just write the number
3004 without type information; for bools, write `true' or `false'.
3005 Other refinements could be made here too. */
3007 /* This constant string is used to map from <builtin-type> codes
3008 (26 letters of the alphabet) to codes that determine how the
3009 value will be displayed. The codes are:
3013 A space means the value will be represented using cast
3015 static const char *const code_map
= "ibi iii ll ii i ";
3017 char code
= code_map
[peek
- 'a'];
3018 /* FIXME: Implement demangling of floats and doubles. */
3020 return STATUS_UNIMPLEMENTED
;
3023 /* It's a boolean. */
3026 /* Consume the b. */
3028 /* Look at the next character. It should be 0 or 1,
3029 corresponding to false or true, respectively. */
3030 value
= peek_char (dm
);
3032 RETURN_IF_ERROR (result_add (dm
, "false"));
3033 else if (value
== '1')
3034 RETURN_IF_ERROR (result_add (dm
, "true"));
3036 return "Unrecognized bool constant.";
3037 /* Consume the 0 or 1. */
3041 else if (code
== 'i' || code
== 'l')
3043 /* It's an integer or long. */
3045 /* Consume the type character. */
3048 /* Demangle the number and write it out. */
3049 value_string
= dyn_string_new (0);
3050 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3051 if (STATUS_NO_ERROR (status
))
3052 status
= result_add_string (dm
, value_string
);
3053 /* For long integers, append an l. */
3054 if (code
== 'l' && STATUS_NO_ERROR (status
))
3055 status
= result_add_char (dm
, code
);
3056 dyn_string_delete (value_string
);
3058 RETURN_IF_ERROR (status
);
3061 /* ...else code == ' ', so fall through to represent this
3062 literal's type explicitly using cast syntax. */
3065 RETURN_IF_ERROR (result_add_char (dm
, '('));
3066 RETURN_IF_ERROR (demangle_type (dm
));
3067 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3069 value_string
= dyn_string_new (0);
3070 if (value_string
== NULL
)
3071 return STATUS_ALLOCATION_FAILED
;
3073 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3074 if (STATUS_NO_ERROR (status
))
3075 status
= result_add_string (dm
, value_string
);
3076 dyn_string_delete (value_string
);
3077 RETURN_IF_ERROR (status
);
3082 /* Demangles and emits a <template-arg>.
3084 <template-arg> ::= <type> # type
3085 ::= L <type> <value number> E # literal
3086 ::= LZ <encoding> E # external name
3087 ::= X <expression> E # expression */
3090 demangle_template_arg (dm
)
3093 DEMANGLE_TRACE ("template-arg", dm
);
3095 switch (peek_char (dm
))
3100 if (peek_char (dm
) == 'Z')
3102 /* External name. */
3104 /* FIXME: Standard is contradictory here. */
3105 RETURN_IF_ERROR (demangle_encoding (dm
));
3108 RETURN_IF_ERROR (demangle_literal (dm
));
3109 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3115 RETURN_IF_ERROR (demangle_expression (dm
));
3116 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3120 RETURN_IF_ERROR (demangle_type (dm
));
3127 /* Demangles and emits an <expression>.
3129 <expression> ::= <unary operator-name> <expression>
3130 ::= <binary operator-name> <expression> <expression>
3132 ::= <scope-expression> */
3135 demangle_expression (dm
)
3138 char peek
= peek_char (dm
);
3140 DEMANGLE_TRACE ("expression", dm
);
3142 if (peek
== 'L' || peek
== 'T')
3143 RETURN_IF_ERROR (demangle_expr_primary (dm
));
3144 else if (peek
== 's' && peek_char_next (dm
) == 'r')
3145 RETURN_IF_ERROR (demangle_scope_expression (dm
));
3147 /* An operator expression. */
3150 status_t status
= STATUS_OK
;
3151 dyn_string_t operator_name
;
3153 /* We have an operator name. Since we want to output binary
3154 operations in infix notation, capture the operator name
3156 RETURN_IF_ERROR (result_push (dm
));
3157 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
3158 operator_name
= (dyn_string_t
) result_pop (dm
);
3160 /* If it's binary, do an operand first. */
3163 status
= result_add_char (dm
, '(');
3164 if (STATUS_NO_ERROR (status
))
3165 status
= demangle_expression (dm
);
3166 if (STATUS_NO_ERROR (status
))
3167 status
= result_add_char (dm
, ')');
3170 /* Emit the operator. */
3171 if (STATUS_NO_ERROR (status
))
3172 status
= result_add_string (dm
, operator_name
);
3173 dyn_string_delete (operator_name
);
3174 RETURN_IF_ERROR (status
);
3176 /* Emit its second (if binary) or only (if unary) operand. */
3177 RETURN_IF_ERROR (result_add_char (dm
, '('));
3178 RETURN_IF_ERROR (demangle_expression (dm
));
3179 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3181 /* The ternary operator takes a third operand. */
3184 RETURN_IF_ERROR (result_add (dm
, ":("));
3185 RETURN_IF_ERROR (demangle_expression (dm
));
3186 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3193 /* Demangles and emits a <scope-expression>.
3195 <scope-expression> ::= sr <qualifying type> <source-name>
3196 ::= sr <qualifying type> <encoding> */
3199 demangle_scope_expression (dm
)
3202 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3203 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3204 RETURN_IF_ERROR (demangle_type (dm
));
3205 RETURN_IF_ERROR (result_add (dm
, "::"));
3206 RETURN_IF_ERROR (demangle_encoding (dm
));
3210 /* Demangles and emits an <expr-primary>.
3212 <expr-primary> ::= <template-param>
3213 ::= L <type> <value number> E # literal
3214 ::= L <mangled-name> E # external name */
3217 demangle_expr_primary (dm
)
3220 char peek
= peek_char (dm
);
3222 DEMANGLE_TRACE ("expr-primary", dm
);
3225 RETURN_IF_ERROR (demangle_template_param (dm
));
3226 else if (peek
== 'L')
3228 /* Consume the `L'. */
3230 peek
= peek_char (dm
);
3233 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3235 RETURN_IF_ERROR (demangle_literal (dm
));
3237 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3240 return STATUS_ERROR
;
3245 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3246 if the substitution is the name of a template, zero otherwise.
3248 <substitution> ::= S <seq-id> _
3252 ::= Sa # ::std::allocator
3253 ::= Sb # ::std::basic_string
3254 ::= Ss # ::std::basic_string<char,
3255 ::std::char_traits<char>,
3256 ::std::allocator<char> >
3257 ::= Si # ::std::basic_istream<char,
3258 std::char_traits<char> >
3259 ::= So # ::std::basic_ostream<char,
3260 std::char_traits<char> >
3261 ::= Sd # ::std::basic_iostream<char,
3262 std::char_traits<char> >
3266 demangle_substitution (dm
, template_p
)
3274 DEMANGLE_TRACE ("substitution", dm
);
3276 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3278 /* Scan the substitution sequence index. A missing number denotes
3280 peek
= peek_char (dm
);
3283 /* If the following character is 0-9 or a capital letter, interpret
3284 the sequence up to the next underscore as a base-36 substitution
3286 else if (IS_DIGIT ((unsigned char) peek
)
3287 || (peek
>= 'A' && peek
<= 'Z'))
3288 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3291 const char *new_last_source_name
= NULL
;
3296 RETURN_IF_ERROR (result_add (dm
, "std"));
3300 RETURN_IF_ERROR (result_add (dm
, "std::allocator"));
3301 new_last_source_name
= "allocator";
3306 RETURN_IF_ERROR (result_add (dm
, "std::basic_string"));
3307 new_last_source_name
= "basic_string";
3314 RETURN_IF_ERROR (result_add (dm
, "std::string"));
3315 new_last_source_name
= "string";
3319 RETURN_IF_ERROR (result_add (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3320 new_last_source_name
= "basic_string";
3328 RETURN_IF_ERROR (result_add (dm
, "std::istream"));
3329 new_last_source_name
= "istream";
3333 RETURN_IF_ERROR (result_add (dm
, "std::basic_istream<char, std::char_traints<char> >"));
3334 new_last_source_name
= "basic_istream";
3342 RETURN_IF_ERROR (result_add (dm
, "std::ostream"));
3343 new_last_source_name
= "ostream";
3347 RETURN_IF_ERROR (result_add (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3348 new_last_source_name
= "basic_ostream";
3356 RETURN_IF_ERROR (result_add (dm
, "std::iostream"));
3357 new_last_source_name
= "iostream";
3361 RETURN_IF_ERROR (result_add (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3362 new_last_source_name
= "basic_iostream";
3368 return "Unrecognized <substitution>.";
3371 /* Consume the character we just processed. */
3374 if (new_last_source_name
!= NULL
)
3376 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3377 new_last_source_name
))
3378 return STATUS_ALLOCATION_FAILED
;
3384 /* Look up the substitution text. Since `S_' is the most recent
3385 substitution, `S0_' is the second-most-recent, etc., shift the
3386 numbering by one. */
3387 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3389 return "Substitution number out of range.";
3391 /* Emit the substitution text. */
3392 RETURN_IF_ERROR (result_add_string (dm
, text
));
3394 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3398 /* Demangles and emits a <local-name>.
3400 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3401 := Z <function encoding> E s [<discriminator>] */
3404 demangle_local_name (dm
)
3407 DEMANGLE_TRACE ("local-name", dm
);
3409 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3410 RETURN_IF_ERROR (demangle_encoding (dm
));
3411 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3412 RETURN_IF_ERROR (result_add (dm
, "::"));
3414 if (peek_char (dm
) == 's')
3416 /* Local character string literal. */
3417 RETURN_IF_ERROR (result_add (dm
, "string literal"));
3418 /* Consume the s. */
3420 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3425 /* Local name for some other entity. Demangle its name. */
3426 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3427 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3433 /* Optimonally demangles and emits a <discriminator>. If there is no
3434 <discriminator> at the current position in the mangled string, the
3435 descriminator is assumed to be zero. Emit the discriminator number
3436 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3437 discriminator is zero.
3439 <discriminator> ::= _ <number> */
3442 demangle_discriminator (dm
, suppress_first
)
3446 /* Output for <discriminator>s to the demangled name is completely
3447 suppressed if not in verbose mode. */
3449 if (peek_char (dm
) == '_')
3451 /* Consume the underscore. */
3454 RETURN_IF_ERROR (result_add (dm
, " [#"));
3455 /* Check if there's a number following the underscore. */
3456 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3459 /* Demangle the number. */
3460 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3462 /* Write the discriminator. The mangled number is two
3463 less than the discriminator ordinal, counting from
3465 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 1,
3466 (dyn_string_t
) dm
->result
));
3469 return STATUS_ERROR
;
3471 RETURN_IF_ERROR (result_add_char (dm
, ']'));
3473 else if (!suppress_first
)
3476 RETURN_IF_ERROR (result_add (dm
, " [#0]"));
3482 /* Demangle NAME into RESULT, which must be an initialized
3483 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3484 an error message, and the contents of RESULT are unchanged. */
3487 cp_demangle (name
, result
, style
)
3489 dyn_string_t result
;
3493 int length
= strlen (name
);
3495 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3497 demangling_t dm
= demangling_new (name
, style
);
3499 return STATUS_ALLOCATION_FAILED
;
3501 status
= result_push (dm
);
3502 if (status
!= STATUS_OK
)
3504 demangling_delete (dm
);
3508 status
= demangle_mangled_name (dm
);
3509 if (STATUS_NO_ERROR (status
))
3511 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3512 if (!dyn_string_copy (result
, demangled
))
3513 return STATUS_ALLOCATION_FAILED
;
3514 dyn_string_delete (demangled
);
3517 demangling_delete (dm
);
3521 /* It's evidently not a mangled C++ name. It could be the name
3522 of something with C linkage, though, so just copy NAME into
3524 if (!dyn_string_copy_cstr (result
, name
))
3525 return STATUS_ALLOCATION_FAILED
;
3532 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3533 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3534 an error message, and the contents of RESULT are unchanged. */
3538 cp_demangle_type (type_name
, result
)
3539 const char* type_name
;
3540 dyn_string_t result
;
3543 demangling_t dm
= demangling_new (type_name
);
3546 return STATUS_ALLOCATION_FAILED
;
3548 /* Demangle the type name. The demangled name is stored in dm. */
3549 status
= result_push (dm
);
3550 if (status
!= STATUS_OK
)
3552 demangling_delete (dm
);
3556 status
= demangle_type (dm
);
3558 if (STATUS_NO_ERROR (status
))
3560 /* The demangling succeeded. Pop the result out of dm and copy
3562 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3563 if (!dyn_string_copy (result
, demangled
))
3564 return STATUS_ALLOCATION_FAILED
;
3565 dyn_string_delete (demangled
);
3569 demangling_delete (dm
);
3574 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3576 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3577 demangling. MANGLED_NAME is a NUL-terminated character string
3578 containing the name to be demangled.
3580 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3581 *LENGTH bytes, into which the demangled name is stored. If
3582 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3583 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3584 is placed in a region of memory allocated with malloc.
3586 If LENGTH is non-NULL, the length of the buffer conaining the
3587 demangled name, is placed in *LENGTH.
3589 The return value is a pointer to the start of the NUL-terminated
3590 demangled name, or NULL if the demangling fails. The caller is
3591 responsible for deallocating this memory using free.
3593 *STATUS is set to one of the following values:
3594 0: The demangling operation succeeded.
3595 -1: A memory allocation failiure occurred.
3596 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3597 -3: One of the arguments is invalid.
3599 The demagling is performed using the C++ ABI mangling rules, with
3603 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3604 const char *mangled_name
;
3605 char *output_buffer
;
3609 struct dyn_string demangled_name
;
3615 if (mangled_name
== NULL
) {
3620 /* Did the caller provide a buffer for the demangled name? */
3621 if (output_buffer
== NULL
) {
3622 /* No; dyn_string will malloc a buffer for us. */
3623 if (!dyn_string_init (&demangled_name
, 0))
3630 /* Yes. Check that the length was provided. */
3631 if (length
== NULL
) {
3635 /* Install the buffer into a dyn_string. */
3636 demangled_name
.allocated
= *length
;
3637 demangled_name
.length
= 0;
3638 demangled_name
.s
= output_buffer
;
3641 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3642 /* MANGLED_NAME apprears to be a function or variable name.
3643 Demangle it accordingly. */
3644 result
= cp_demangle (mangled_name
, &demangled_name
, 0);
3646 /* Try to demangled MANGLED_NAME as the name of a type. */
3647 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3649 if (result
== STATUS_OK
)
3650 /* The demangling succeeded. */
3652 /* If LENGTH isn't NULL, store the allocated buffer length
3653 there; the buffer may have been realloced by dyn_string
3656 *length
= demangled_name
.allocated
;
3657 /* The operation was a success. */
3659 return dyn_string_buf (&demangled_name
);
3661 else if (result
== STATUS_ALLOCATION_FAILED
)
3662 /* A call to malloc or realloc failed during the demangling
3669 /* The demangling failed for another reason, most probably because
3670 MANGLED_NAME isn't a valid mangled name. */
3672 /* If the buffer containing the demangled name wasn't provided
3673 by the caller, free it. */
3674 if (output_buffer
== NULL
)
3675 free (dyn_string_buf (&demangled_name
));
3681 #else /* !IN_LIBGCC2 */
3683 /* Variant entry point for integration with the existing cplus-dem
3684 demangler. Attempts to demangle MANGLED. If the demangling
3685 succeeds, returns a buffer, allocated with malloc, containing the
3686 demangled name. The caller must deallocate the buffer using free.
3687 If the demangling failes, returns NULL. */
3690 cplus_demangle_v3 (mangled
)
3691 const char* mangled
;
3693 dyn_string_t demangled
;
3696 /* If this isn't a mangled name, don't pretend to demangle it. */
3697 if (strncmp (mangled
, "_Z", 2) != 0)
3700 /* Create a dyn_string to hold the demangled name. */
3701 demangled
= dyn_string_new (0);
3702 /* Attempt the demangling. */
3703 status
= cp_demangle ((char *) mangled
, demangled
, 0);
3705 if (STATUS_NO_ERROR (status
))
3706 /* Demangling succeeded. */
3708 /* Grab the demangled result from the dyn_string. It was
3709 allocated with malloc, so we can return it directly. */
3710 char *return_value
= dyn_string_release (demangled
);
3711 /* Hand back the demangled name. */
3712 return return_value
;
3714 else if (status
== STATUS_ALLOCATION_FAILED
)
3716 fprintf (stderr
, "Memory allocation failed.\n");
3720 /* Demangling failed. */
3722 dyn_string_delete (demangled
);
3727 /* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3728 conventions, but the output formatting is a little different.
3729 This instructs the C++ demangler not to emit pointer characters ("*"), and
3730 to use Java's namespace separator symbol ("." instead of "::"). It then
3731 does an additional pass over the demangled output to replace instances
3732 of JArray<TYPE> with TYPE[]. */
3735 java_demangle_v3 (mangled
)
3736 const char* mangled
;
3738 dyn_string_t demangled
;
3744 char *cplus_demangled
;
3747 /* Create a dyn_string to hold the demangled name. */
3748 demangled
= dyn_string_new (0);
3750 /* Attempt the demangling. */
3751 status
= cp_demangle ((char *) mangled
, demangled
, DMGL_JAVA
);
3753 if (STATUS_NO_ERROR (status
))
3754 /* Demangling succeeded. */
3756 /* Grab the demangled result from the dyn_string. */
3757 cplus_demangled
= dyn_string_release (demangled
);
3759 else if (status
== STATUS_ALLOCATION_FAILED
)
3761 fprintf (stderr
, "Memory allocation failed.\n");
3765 /* Demangling failed. */
3767 dyn_string_delete (demangled
);
3771 len
= strlen (cplus_demangled
);
3772 next
= cplus_demangled
;
3776 /* Replace occurances of JArray<TYPE> with TYPE[]. */
3779 char *open_str
= strstr (next
, "JArray<");
3780 char *close_str
= NULL
;
3782 close_str
= strchr (next
, '>');
3784 if (open_str
!= NULL
&& (close_str
== NULL
|| close_str
> open_str
))
3789 demangled
= dyn_string_new(len
);
3791 /* Copy prepending symbols, if any. */
3792 if (open_str
> next
)
3795 dyn_string_append_cstr (demangled
, next
);
3797 next
= open_str
+ 7;
3799 else if (close_str
!= NULL
)
3803 /* Copy prepending type symbol, if any. Squash any spurious
3805 if (close_str
> next
&& next
[0] != ' ')
3808 dyn_string_append_cstr (demangled
, next
);
3810 dyn_string_append_cstr (demangled
, "[]");
3811 next
= close_str
+ 1;
3815 /* There are no more arrays. Copy the rest of the symbol, or
3816 simply return the original symbol if no changes were made. */
3817 if (next
== cplus_demangled
)
3818 return cplus_demangled
;
3820 dyn_string_append_cstr (demangled
, next
);
3825 free (cplus_demangled
);
3827 return_value
= dyn_string_release (demangled
);
3828 return return_value
;
3831 #endif /* IN_LIBGCC2 */
3834 /* Demangle NAME in the G++ V3 ABI demangling style, and return either
3835 zero, indicating that some error occurred, or a demangling_t
3836 holding the results. */
3838 demangle_v3_with_details (name
)
3844 if (strncmp (name
, "_Z", 2))
3847 dm
= demangling_new (name
, DMGL_GNU_V3
);
3850 fprintf (stderr
, "Memory allocation failed.\n");
3854 status
= result_push (dm
);
3855 if (! STATUS_NO_ERROR (status
))
3857 demangling_delete (dm
);
3858 fprintf (stderr
, "%s\n", status
);
3862 status
= demangle_mangled_name (dm
);
3863 if (STATUS_NO_ERROR (status
))
3866 demangling_delete (dm
);
3871 /* Return non-zero iff NAME is the mangled form of a constructor name
3872 in the G++ V3 ABI demangling style. Specifically, return:
3873 - '1' if NAME is a complete object constructor,
3874 - '2' if NAME is a base object constructor, or
3875 - '3' if NAME is a complete object allocating constructor. */
3876 enum gnu_v3_ctor_kinds
3877 is_gnu_v3_mangled_ctor (name
)
3880 demangling_t dm
= demangle_v3_with_details (name
);
3884 enum gnu_v3_ctor_kinds result
= dm
->is_constructor
;
3885 demangling_delete (dm
);
3893 /* Return non-zero iff NAME is the mangled form of a destructor name
3894 in the G++ V3 ABI demangling style. Specifically, return:
3895 - '0' if NAME is a deleting destructor,
3896 - '1' if NAME is a complete object destructor, or
3897 - '2' if NAME is a base object destructor. */
3898 enum gnu_v3_dtor_kinds
3899 is_gnu_v3_mangled_dtor (name
)
3902 demangling_t dm
= demangle_v3_with_details (name
);
3906 enum gnu_v3_dtor_kinds result
= dm
->is_destructor
;
3907 demangling_delete (dm
);
3915 #ifdef STANDALONE_DEMANGLER
3919 static void print_usage
3920 PARAMS ((FILE* fp
, int exit_value
));
3922 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3923 #define is_mangled_char(CHAR) \
3924 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3925 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3927 /* The name of this program, as invoked. */
3928 const char* program_name
;
3930 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3933 print_usage (fp
, exit_value
)
3937 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3938 fprintf (fp
, "Options:\n");
3939 fprintf (fp
, " -h,--help Display this message.\n");
3940 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3941 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3942 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3947 /* Option specification for getopt_long. */
3948 static struct option long_options
[] =
3950 { "help", no_argument
, NULL
, 'h' },
3951 { "strict", no_argument
, NULL
, 's' },
3952 { "verbose", no_argument
, NULL
, 'v' },
3953 { NULL
, no_argument
, NULL
, 0 },
3956 /* Main entry for a demangling filter executable. It will demangle
3957 its command line arguments, if any. If none are provided, it will
3958 filter stdin to stdout, replacing any recognized mangled C++ names
3959 with their demangled equivalents. */
3970 /* Use the program name of this program, as invoked. */
3971 program_name
= argv
[0];
3973 /* Parse options. */
3976 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3979 case '?': /* Unrecognized option. */
3980 print_usage (stderr
, 1);
3984 print_usage (stdout
, 0);
3996 while (opt_char
!= -1);
3999 /* No command line arguments were provided. Filter stdin. */
4001 dyn_string_t mangled
= dyn_string_new (3);
4002 dyn_string_t demangled
= dyn_string_new (0);
4005 /* Read all of input. */
4006 while (!feof (stdin
))
4008 char c
= getchar ();
4010 /* The first character of a mangled name is an underscore. */
4015 /* It's not a mangled name. Print the character and go
4022 /* The second character of a mangled name is a capital `Z'. */
4027 /* It's not a mangled name. Print the previous
4028 underscore, the `Z', and go on. */
4034 /* Start keeping track of the candidate mangled name. */
4035 dyn_string_append_char (mangled
, '_');
4036 dyn_string_append_char (mangled
, 'Z');
4038 /* Pile characters into mangled until we hit one that can't
4039 occur in a mangled name. */
4041 while (!feof (stdin
) && is_mangled_char (c
))
4043 dyn_string_append_char (mangled
, c
);
4049 /* Attempt to demangle the name. */
4050 status
= cp_demangle (dyn_string_buf (mangled
), demangled
, 0);
4052 /* If the demangling succeeded, great! Print out the
4053 demangled version. */
4054 if (STATUS_NO_ERROR (status
))
4055 fputs (dyn_string_buf (demangled
), stdout
);
4056 /* Abort on allocation failures. */
4057 else if (status
== STATUS_ALLOCATION_FAILED
)
4059 fprintf (stderr
, "Memory allocation failed.\n");
4062 /* Otherwise, it might not have been a mangled name. Just
4063 print out the original text. */
4065 fputs (dyn_string_buf (mangled
), stdout
);
4067 /* If we haven't hit EOF yet, we've read one character that
4068 can't occur in a mangled name, so print it out. */
4072 /* Clear the candidate mangled name, to start afresh next
4073 time we hit a `_Z'. */
4074 dyn_string_clear (mangled
);
4077 dyn_string_delete (mangled
);
4078 dyn_string_delete (demangled
);
4081 /* Demangle command line arguments. */
4083 dyn_string_t result
= dyn_string_new (0);
4085 /* Loop over command line arguments. */
4086 for (i
= optind
; i
< argc
; ++i
)
4088 /* Attempt to demangle. */
4089 status
= cp_demangle (argv
[i
], result
, 0);
4091 /* If it worked, print the demangled name. */
4092 if (STATUS_NO_ERROR (status
))
4093 printf ("%s\n", dyn_string_buf (result
));
4094 /* Abort on allocaiton failures. */
4095 else if (status
== STATUS_ALLOCATION_FAILED
)
4097 fprintf (stderr
, "Memory allocation failed.\n");
4100 /* If not, print the error message to stderr instead. */
4102 fprintf (stderr
, "%s\n", status
);
4104 dyn_string_delete (result
);
4110 #endif /* STANDALONE_DEMANGLER */