1 /* Demangler for IA64 / g++ V3 ABI.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This file is part of the libiberty library, which is part of GCC.
7 This file 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 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 /* This file implements demangling of C++ names mangled according to
32 the IA64 / g++ V3 ABI. Use the cp_demangle function to
33 demangle a mangled name, or compile with the preprocessor macro
34 STANDALONE_DEMANGLER defined to create a demangling filter
35 executable (functionally similar to c++filt, but includes this
42 #include <sys/types.h>
57 #include "libiberty.h"
58 #include "dyn-string.h"
61 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
62 and other debugging output, will be generated. */
63 #ifdef CP_DEMANGLE_DEBUG
64 #define DEMANGLE_TRACE(PRODUCTION, DM) \
65 fprintf (stderr, " -> %-24s at position %3d\n", \
66 (PRODUCTION), current_position (DM));
68 #define DEMANGLE_TRACE(PRODUCTION, DM)
71 /* Don't include <ctype.h>, to prevent additional unresolved symbols
72 from being dragged into the C++ runtime library. */
73 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
74 #define IS_ALPHA(CHAR) \
75 (((CHAR) >= 'a' && (CHAR) <= 'z') \
76 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
78 /* The prefix prepended by GCC to an identifier represnting the
79 anonymous namespace. */
80 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
82 /* Character(s) to use for namespace separation in demangled output */
83 #define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
85 /* If flag_verbose is zero, some simplifications will be made to the
86 output to make it easier to read and supress details that are
87 generally not of interest to the average C++ programmer.
88 Otherwise, the demangled representation will attempt to convey as
89 much information as the mangled form. */
90 static int flag_verbose
;
92 /* If flag_strict is non-zero, demangle strictly according to the
93 specification -- don't demangle special g++ manglings. */
94 static int flag_strict
;
96 /* String_list_t is an extended form of dyn_string_t which provides a
97 link field and a caret position for additions to the string. A
98 string_list_t may safely be cast to and used as a dyn_string_t. */
100 struct string_list_def
102 /* The dyn_string; must be first. */
103 struct dyn_string string
;
105 /* The position at which additional text is added to this string
106 (using the result_add* macros). This value is an offset from the
107 end of the string, not the beginning (and should be
111 /* The next string in the list. */
112 struct string_list_def
*next
;
115 typedef struct string_list_def
*string_list_t
;
117 /* Data structure representing a potential substitution. */
119 struct substitution_def
121 /* The demangled text of the substitution. */
124 /* Whether this substitution represents a template item. */
128 /* Data structure representing a template argument list. */
130 struct template_arg_list_def
132 /* The next (lower) template argument list in the stack of currently
133 active template arguments. */
134 struct template_arg_list_def
*next
;
136 /* The first element in the list of template arguments in
137 left-to-right order. */
138 string_list_t first_argument
;
140 /* The last element in the arguments lists. */
141 string_list_t last_argument
;
144 typedef struct template_arg_list_def
*template_arg_list_t
;
146 /* Data structure to maintain the state of the current demangling. */
148 struct demangling_def
150 /* The full mangled name being mangled. */
153 /* Pointer into name at the current position. */
156 /* Stack for strings containing demangled result generated so far.
157 Text is emitted to the topmost (first) string. */
158 string_list_t result
;
160 /* The number of presently available substitutions. */
161 int num_substitutions
;
163 /* The allocated size of the substitutions array. */
164 int substitutions_allocated
;
166 /* An array of available substitutions. The number of elements in
167 the array is given by num_substitions, and the allocated array
168 size in substitutions_size.
170 The most recent substition is at the end, so
172 - `S_' corresponds to substititutions[num_substitutions - 1]
173 - `S0_' corresponds to substititutions[num_substitutions - 2]
176 struct substitution_def
*substitutions
;
178 /* The stack of template argument lists. */
179 template_arg_list_t template_arg_lists
;
181 /* The most recently demangled source-name. */
182 dyn_string_t last_source_name
;
184 /* Language style to use for demangled output. */
187 /* Set to non-zero iff this name is a constructor. The actual value
188 indicates what sort of constructor this is; see demangle.h. */
189 enum gnu_v3_ctor_kinds is_constructor
;
191 /* Set to non-zero iff this name is a destructor. The actual value
192 indicates what sort of destructor this is; see demangle.h. */
193 enum gnu_v3_dtor_kinds is_destructor
;
197 typedef struct demangling_def
*demangling_t
;
199 /* This type is the standard return code from most functions. Values
200 other than STATUS_OK contain descriptive messages. */
201 typedef const char *status_t
;
203 /* Special values that can be used as a status_t. */
204 #define STATUS_OK NULL
205 #define STATUS_ERROR "Error."
206 #define STATUS_UNIMPLEMENTED "Unimplemented."
207 #define STATUS_INTERNAL_ERROR "Internal error."
209 /* This status code indicates a failure in malloc or realloc. */
210 static const char *const status_allocation_failed
= "Allocation failed.";
211 #define STATUS_ALLOCATION_FAILED status_allocation_failed
213 /* Non-zero if STATUS indicates that no error has occurred. */
214 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
216 /* Evaluate EXPR, which must produce a status_t. If the status code
217 indicates an error, return from the current function with that
219 #define RETURN_IF_ERROR(EXPR) \
223 if (!STATUS_NO_ERROR (s)) \
228 static status_t int_to_dyn_string
229 PARAMS ((int, dyn_string_t
));
230 static string_list_t string_list_new
232 static void string_list_delete
233 PARAMS ((string_list_t
));
234 static status_t result_add_separated_char
235 PARAMS ((demangling_t
, int));
236 static status_t result_push
237 PARAMS ((demangling_t
));
238 static string_list_t result_pop
239 PARAMS ((demangling_t
));
240 static int substitution_start
241 PARAMS ((demangling_t
));
242 static status_t substitution_add
243 PARAMS ((demangling_t
, int, int));
244 static dyn_string_t substitution_get
245 PARAMS ((demangling_t
, int, int *));
246 #ifdef CP_DEMANGLE_DEBUG
247 static void substitutions_print
248 PARAMS ((demangling_t
, FILE *));
250 static template_arg_list_t template_arg_list_new
252 static void template_arg_list_delete
253 PARAMS ((template_arg_list_t
));
254 static void template_arg_list_add_arg
255 PARAMS ((template_arg_list_t
, string_list_t
));
256 static string_list_t template_arg_list_get_arg
257 PARAMS ((template_arg_list_t
, int));
258 static void push_template_arg_list
259 PARAMS ((demangling_t
, template_arg_list_t
));
260 static void pop_to_template_arg_list
261 PARAMS ((demangling_t
, template_arg_list_t
));
262 #ifdef CP_DEMANGLE_DEBUG
263 static void template_arg_list_print
264 PARAMS ((template_arg_list_t
, FILE *));
266 static template_arg_list_t current_template_arg_list
267 PARAMS ((demangling_t
));
268 static demangling_t demangling_new
269 PARAMS ((const char *, int));
270 static void demangling_delete
271 PARAMS ((demangling_t
));
273 /* The last character of DS. Warning: DS is evaluated twice. */
274 #define dyn_string_last_char(DS) \
275 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
277 /* Append a space character (` ') to DS if it does not already end
278 with one. Evaluates to 1 on success, or 0 on allocation failure. */
279 #define dyn_string_append_space(DS) \
280 ((dyn_string_length (DS) > 0 \
281 && dyn_string_last_char (DS) != ' ') \
282 ? dyn_string_append_char ((DS), ' ') \
285 /* Returns the index of the current position in the mangled name. */
286 #define current_position(DM) ((DM)->next - (DM)->name)
288 /* Returns the character at the current position of the mangled name. */
289 #define peek_char(DM) (*((DM)->next))
291 /* Returns the character one past the current position of the mangled
293 #define peek_char_next(DM) \
294 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
296 /* Returns the character at the current position, and advances the
297 current position to the next character. */
298 #define next_char(DM) (*((DM)->next)++)
300 /* Returns non-zero if the current position is the end of the mangled
301 name, i.e. one past the last character. */
302 #define end_of_name_p(DM) (peek_char (DM) == '\0')
304 /* Advances the current position by one character. */
305 #define advance_char(DM) (++(DM)->next)
307 /* Returns the string containing the current demangled result. */
308 #define result_string(DM) (&(DM)->result->string)
310 /* Returns the position at which new text is inserted into the
312 #define result_caret_pos(DM) \
313 (result_length (DM) + \
314 ((string_list_t) result_string (DM))->caret_position)
316 /* Adds a dyn_string_t to the demangled result. */
317 #define result_add_string(DM, STRING) \
318 (dyn_string_insert (&(DM)->result->string, \
319 result_caret_pos (DM), (STRING)) \
320 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
322 /* Adds NUL-terminated string CSTR to the demangled result. */
323 #define result_add(DM, CSTR) \
324 (dyn_string_insert_cstr (&(DM)->result->string, \
325 result_caret_pos (DM), (CSTR)) \
326 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
328 /* Adds character CHAR to the demangled result. */
329 #define result_add_char(DM, CHAR) \
330 (dyn_string_insert_char (&(DM)->result->string, \
331 result_caret_pos (DM), (CHAR)) \
332 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
334 /* Inserts a dyn_string_t to the demangled result at position POS. */
335 #define result_insert_string(DM, POS, STRING) \
336 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
337 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
339 /* Inserts NUL-terminated string CSTR to the demangled result at
341 #define result_insert(DM, POS, CSTR) \
342 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
343 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
345 /* Inserts character CHAR to the demangled result at position POS. */
346 #define result_insert_char(DM, POS, CHAR) \
347 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
348 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
350 /* The length of the current demangled result. */
351 #define result_length(DM) \
352 dyn_string_length (&(DM)->result->string)
354 /* Appends a (less-than, greater-than) character to the result in DM
355 to (open, close) a template argument or parameter list. Appends a
356 space first if necessary to prevent spurious elision of angle
357 brackets with the previous character. */
358 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
359 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
361 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
362 success. On failure, deletes DS and returns an error code. */
365 int_to_dyn_string (value
, ds
)
372 /* Handle zero up front. */
375 if (!dyn_string_append_char (ds
, '0'))
376 return STATUS_ALLOCATION_FAILED
;
380 /* For negative numbers, emit a minus sign. */
383 if (!dyn_string_append_char (ds
, '-'))
384 return STATUS_ALLOCATION_FAILED
;
388 /* Find the power of 10 of the first digit. */
396 /* Write the digits. */
399 int digit
= value
/ mask
;
401 if (!dyn_string_append_char (ds
, '0' + digit
))
402 return STATUS_ALLOCATION_FAILED
;
404 value
-= digit
* mask
;
411 /* Creates a new string list node. The contents of the string are
412 empty, but the initial buffer allocation is LENGTH. The string
413 list node should be deleted with string_list_delete. Returns NULL
414 if allocation fails. */
417 string_list_new (length
)
420 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
421 s
->caret_position
= 0;
424 if (!dyn_string_init ((dyn_string_t
) s
, length
))
429 /* Deletes the entire string list starting at NODE. */
432 string_list_delete (node
)
437 string_list_t next
= node
->next
;
438 dyn_string_delete ((dyn_string_t
) node
);
443 /* Appends CHARACTER to the demangled result. If the current trailing
444 character of the result is CHARACTER, a space is inserted first. */
447 result_add_separated_char (dm
, character
)
451 char *result
= dyn_string_buf (result_string (dm
));
452 int caret_pos
= result_caret_pos (dm
);
454 /* Add a space if the last character is already the character we
456 if (caret_pos
> 0 && result
[caret_pos
- 1] == character
)
457 RETURN_IF_ERROR (result_add_char (dm
, ' '));
458 /* Add the character. */
459 RETURN_IF_ERROR (result_add_char (dm
, character
));
464 /* Allocates and pushes a new string onto the demangled results stack
465 for DM. Subsequent demangling with DM will emit to the new string.
466 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
467 allocation failure. */
473 string_list_t new_string
= string_list_new (0);
474 if (new_string
== NULL
)
475 /* Allocation failed. */
476 return STATUS_ALLOCATION_FAILED
;
478 /* Link the new string to the front of the list of result strings. */
479 new_string
->next
= (string_list_t
) dm
->result
;
480 dm
->result
= new_string
;
484 /* Removes and returns the topmost element on the demangled results
485 stack for DM. The caller assumes ownership for the returned
492 string_list_t top
= dm
->result
;
493 dm
->result
= top
->next
;
497 /* Returns the current value of the caret for the result string. The
498 value is an offet from the end of the result string. */
501 result_get_caret (dm
)
504 return ((string_list_t
) result_string (dm
))->caret_position
;
507 /* Sets the value of the caret for the result string, counted as an
508 offet from the end of the result string. */
511 result_set_caret (dm
, position
)
515 ((string_list_t
) result_string (dm
))->caret_position
= position
;
518 /* Shifts the position of the next addition to the result by
519 POSITION_OFFSET. A negative value shifts the caret to the left. */
522 result_shift_caret (dm
, position_offset
)
526 ((string_list_t
) result_string (dm
))->caret_position
+= position_offset
;
529 /* Returns non-zero if the character that comes right before the place
530 where text will be added to the result is a space. In this case,
531 the caller should supress adding another space. */
534 result_previous_char_is_space (dm
)
537 char *result
= dyn_string_buf (result_string (dm
));
538 int pos
= result_caret_pos (dm
);
539 return pos
> 0 && result
[pos
- 1] == ' ';
542 /* Returns the start position of a fragment of the demangled result
543 that will be a substitution candidate. Should be called at the
544 start of productions that can add substitutions. */
547 substitution_start (dm
)
550 return result_caret_pos (dm
);
553 /* Adds the suffix of the current demangled result of DM starting at
554 START_POSITION as a potential substitution. If TEMPLATE_P is
555 non-zero, this potential substitution is a template-id. */
558 substitution_add (dm
, start_position
, template_p
)
563 dyn_string_t result
= result_string (dm
);
564 dyn_string_t substitution
= dyn_string_new (0);
567 if (substitution
== NULL
)
568 return STATUS_ALLOCATION_FAILED
;
570 /* Extract the substring of the current demangling result that
571 represents the subsitution candidate. */
572 if (!dyn_string_substring (substitution
,
573 result
, start_position
, result_caret_pos (dm
)))
575 dyn_string_delete (substitution
);
576 return STATUS_ALLOCATION_FAILED
;
579 /* If there's no room for the new entry, grow the array. */
580 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
582 size_t new_array_size
;
583 if (dm
->substitutions_allocated
> 0)
584 dm
->substitutions_allocated
*= 2;
586 dm
->substitutions_allocated
= 2;
588 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
590 dm
->substitutions
= (struct substitution_def
*)
591 realloc (dm
->substitutions
, new_array_size
);
592 if (dm
->substitutions
== NULL
)
593 /* Realloc failed. */
595 dyn_string_delete (substitution
);
596 return STATUS_ALLOCATION_FAILED
;
600 /* Add the substitution to the array. */
601 i
= dm
->num_substitutions
++;
602 dm
->substitutions
[i
].text
= substitution
;
603 dm
->substitutions
[i
].template_p
= template_p
;
605 #ifdef CP_DEMANGLE_DEBUG
606 substitutions_print (dm
, stderr
);
612 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
613 non-zero if the substitution is a template-id, zero otherwise.
614 N is numbered from zero. DM retains ownership of the returned
615 string. If N is negative, or equal to or greater than the current
616 number of substitution candidates, returns NULL. */
619 substitution_get (dm
, n
, template_p
)
624 struct substitution_def
*sub
;
626 /* Make sure N is in the valid range. */
627 if (n
< 0 || n
>= dm
->num_substitutions
)
630 sub
= &(dm
->substitutions
[n
]);
631 *template_p
= sub
->template_p
;
635 #ifdef CP_DEMANGLE_DEBUG
636 /* Debugging routine to print the current substitutions to FP. */
639 substitutions_print (dm
, fp
)
644 int num
= dm
->num_substitutions
;
646 fprintf (fp
, "SUBSTITUTIONS:\n");
647 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
650 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
653 fprintf (fp
, " S_ ");
655 fprintf (fp
, " S%d_", seq_id
);
656 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
660 #endif /* CP_DEMANGLE_DEBUG */
662 /* Creates a new template argument list. Returns NULL if allocation
665 static template_arg_list_t
666 template_arg_list_new ()
668 template_arg_list_t new_list
=
669 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
670 if (new_list
== NULL
)
672 /* Initialize the new list to have no arguments. */
673 new_list
->first_argument
= NULL
;
674 new_list
->last_argument
= NULL
;
675 /* Return the new list. */
679 /* Deletes a template argument list and the template arguments it
683 template_arg_list_delete (list
)
684 template_arg_list_t list
;
686 /* If there are any arguments on LIST, delete them. */
687 if (list
->first_argument
!= NULL
)
688 string_list_delete (list
->first_argument
);
693 /* Adds ARG to the template argument list ARG_LIST. */
696 template_arg_list_add_arg (arg_list
, arg
)
697 template_arg_list_t arg_list
;
700 if (arg_list
->first_argument
== NULL
)
701 /* If there were no arguments before, ARG is the first one. */
702 arg_list
->first_argument
= arg
;
704 /* Make ARG the last argument on the list. */
705 arg_list
->last_argument
->next
= arg
;
706 /* Make ARG the last on the list. */
707 arg_list
->last_argument
= arg
;
711 /* Returns the template arugment at position INDEX in template
712 argument list ARG_LIST. */
715 template_arg_list_get_arg (arg_list
, index
)
716 template_arg_list_t arg_list
;
719 string_list_t arg
= arg_list
->first_argument
;
720 /* Scan down the list of arguments to find the one at position
726 /* Ran out of arguments before INDEX hit zero. That's an
730 /* Return the argument at position INDEX. */
734 /* Pushes ARG_LIST onto the top of the template argument list stack. */
737 push_template_arg_list (dm
, arg_list
)
739 template_arg_list_t arg_list
;
741 arg_list
->next
= dm
->template_arg_lists
;
742 dm
->template_arg_lists
= arg_list
;
743 #ifdef CP_DEMANGLE_DEBUG
744 fprintf (stderr
, " ** pushing template arg list\n");
745 template_arg_list_print (arg_list
, stderr
);
749 /* Pops and deletes elements on the template argument list stack until
750 arg_list is the topmost element. If arg_list is NULL, all elements
751 are popped and deleted. */
754 pop_to_template_arg_list (dm
, arg_list
)
756 template_arg_list_t arg_list
;
758 while (dm
->template_arg_lists
!= arg_list
)
760 template_arg_list_t top
= dm
->template_arg_lists
;
761 /* Disconnect the topmost element from the list. */
762 dm
->template_arg_lists
= top
->next
;
763 /* Delete the popped element. */
764 template_arg_list_delete (top
);
765 #ifdef CP_DEMANGLE_DEBUG
766 fprintf (stderr
, " ** removing template arg list\n");
771 #ifdef CP_DEMANGLE_DEBUG
773 /* Prints the contents of ARG_LIST to FP. */
776 template_arg_list_print (arg_list
, fp
)
777 template_arg_list_t arg_list
;
783 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
784 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
787 fprintf (fp
, " T_ : ");
789 fprintf (fp
, " T%d_ : ", index
);
791 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
795 #endif /* CP_DEMANGLE_DEBUG */
797 /* Returns the topmost element on the stack of template argument
798 lists. If there is no list of template arguments, returns NULL. */
800 static template_arg_list_t
801 current_template_arg_list (dm
)
804 return dm
->template_arg_lists
;
807 /* Allocates a demangling_t object for demangling mangled NAME. A new
808 result must be pushed before the returned object can be used.
809 Returns NULL if allocation fails. */
812 demangling_new (name
, style
)
817 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
824 dm
->num_substitutions
= 0;
825 dm
->substitutions_allocated
= 10;
826 dm
->template_arg_lists
= NULL
;
827 dm
->last_source_name
= dyn_string_new (0);
828 if (dm
->last_source_name
== NULL
)
830 dm
->substitutions
= (struct substitution_def
*)
831 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
832 if (dm
->substitutions
== NULL
)
834 dyn_string_delete (dm
->last_source_name
);
838 dm
->is_constructor
= (enum gnu_v3_ctor_kinds
) 0;
839 dm
->is_destructor
= (enum gnu_v3_dtor_kinds
) 0;
844 /* Deallocates a demangling_t object and all memory associated with
848 demangling_delete (dm
)
852 template_arg_list_t arg_list
= dm
->template_arg_lists
;
854 /* Delete the stack of template argument lists. */
855 while (arg_list
!= NULL
)
857 template_arg_list_t next
= arg_list
->next
;
858 template_arg_list_delete (arg_list
);
861 /* Delete the list of substitutions. */
862 for (i
= dm
->num_substitutions
; --i
>= 0; )
863 dyn_string_delete (dm
->substitutions
[i
].text
);
864 free (dm
->substitutions
);
865 /* Delete the demangled result. */
866 string_list_delete (dm
->result
);
867 /* Delete the stored identifier name. */
868 dyn_string_delete (dm
->last_source_name
);
869 /* Delete the context object itself. */
873 /* These functions demangle an alternative of the corresponding
874 production in the mangling spec. The first argument of each is a
875 demangling context structure for the current demangling
876 operation. Most emit demangled text directly to the topmost result
877 string on the result string stack in the demangling context
880 static status_t demangle_char
881 PARAMS ((demangling_t
, int));
882 static status_t demangle_mangled_name
883 PARAMS ((demangling_t
));
884 static status_t demangle_encoding
885 PARAMS ((demangling_t
));
886 static status_t demangle_name
887 PARAMS ((demangling_t
, int *));
888 static status_t demangle_nested_name
889 PARAMS ((demangling_t
, int *));
890 static status_t demangle_prefix
891 PARAMS ((demangling_t
, int *));
892 static status_t demangle_unqualified_name
893 PARAMS ((demangling_t
, int *));
894 static status_t demangle_source_name
895 PARAMS ((demangling_t
));
896 static status_t demangle_number
897 PARAMS ((demangling_t
, int *, int, int));
898 static status_t demangle_number_literally
899 PARAMS ((demangling_t
, dyn_string_t
, int, int));
900 static status_t demangle_identifier
901 PARAMS ((demangling_t
, int, dyn_string_t
));
902 static status_t demangle_operator_name
903 PARAMS ((demangling_t
, int, int *, int *));
904 static status_t demangle_nv_offset
905 PARAMS ((demangling_t
));
906 static status_t demangle_v_offset
907 PARAMS ((demangling_t
));
908 static status_t demangle_call_offset
909 PARAMS ((demangling_t
));
910 static status_t demangle_special_name
911 PARAMS ((demangling_t
));
912 static status_t demangle_ctor_dtor_name
913 PARAMS ((demangling_t
));
914 static status_t demangle_type_ptr
915 PARAMS ((demangling_t
, int *, int));
916 static status_t demangle_type
917 PARAMS ((demangling_t
));
918 static status_t demangle_CV_qualifiers
919 PARAMS ((demangling_t
, dyn_string_t
));
920 static status_t demangle_builtin_type
921 PARAMS ((demangling_t
));
922 static status_t demangle_function_type
923 PARAMS ((demangling_t
, int *));
924 static status_t demangle_bare_function_type
925 PARAMS ((demangling_t
, int *));
926 static status_t demangle_class_enum_type
927 PARAMS ((demangling_t
, int *));
928 static status_t demangle_array_type
929 PARAMS ((demangling_t
, int *));
930 static status_t demangle_template_param
931 PARAMS ((demangling_t
));
932 static status_t demangle_template_args
933 PARAMS ((demangling_t
));
934 static status_t demangle_literal
935 PARAMS ((demangling_t
));
936 static status_t demangle_template_arg
937 PARAMS ((demangling_t
));
938 static status_t demangle_expression
939 PARAMS ((demangling_t
));
940 static status_t demangle_scope_expression
941 PARAMS ((demangling_t
));
942 static status_t demangle_expr_primary
943 PARAMS ((demangling_t
));
944 static status_t demangle_substitution
945 PARAMS ((demangling_t
, int *));
946 static status_t demangle_local_name
947 PARAMS ((demangling_t
));
948 static status_t demangle_discriminator
949 PARAMS ((demangling_t
, int));
950 static status_t cp_demangle
951 PARAMS ((const char *, dyn_string_t
, int));
952 static status_t cp_demangle_type
953 PARAMS ((const char*, dyn_string_t
));
955 /* When passed to demangle_bare_function_type, indicates that the
956 function's return type is not encoded before its parameter types. */
957 #define BFT_NO_RETURN_TYPE NULL
959 /* Check that the next character is C. If so, consume it. If not,
963 demangle_char (dm
, c
)
967 static char *error_message
= NULL
;
969 if (peek_char (dm
) == c
)
976 if (error_message
== NULL
)
977 error_message
= (char *) strdup ("Expected ?");
978 error_message
[9] = c
;
979 return error_message
;
983 /* Demangles and emits a <mangled-name>.
985 <mangled-name> ::= _Z <encoding> */
988 demangle_mangled_name (dm
)
991 DEMANGLE_TRACE ("mangled-name", dm
);
992 RETURN_IF_ERROR (demangle_char (dm
, '_'));
993 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
994 RETURN_IF_ERROR (demangle_encoding (dm
));
998 /* Demangles and emits an <encoding>.
1000 <encoding> ::= <function name> <bare-function-type>
1002 ::= <special-name> */
1005 demangle_encoding (dm
)
1008 int encode_return_type
;
1010 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1011 char peek
= peek_char (dm
);
1013 DEMANGLE_TRACE ("encoding", dm
);
1015 /* Remember where the name starts. If it turns out to be a template
1016 function, we'll have to insert the return type here. */
1017 start_position
= result_caret_pos (dm
);
1019 if (peek
== 'G' || peek
== 'T')
1020 RETURN_IF_ERROR (demangle_special_name (dm
));
1023 /* Now demangle the name. */
1024 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
1026 /* If there's anything left, the name was a function name, with
1027 maybe its return type, and its parameter types, following. */
1028 if (!end_of_name_p (dm
)
1029 && peek_char (dm
) != 'E')
1031 if (encode_return_type
)
1032 /* Template functions have their return type encoded. The
1033 return type should be inserted at start_position. */
1035 (demangle_bare_function_type (dm
, &start_position
));
1037 /* Non-template functions don't have their return type
1040 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
1044 /* Pop off template argument lists that were built during the
1045 mangling of this name, to restore the old template context. */
1046 pop_to_template_arg_list (dm
, old_arg_list
);
1051 /* Demangles and emits a <name>.
1053 <name> ::= <unscoped-name>
1054 ::= <unscoped-template-name> <template-args>
1058 <unscoped-name> ::= <unqualified-name>
1059 ::= St <unqualified-name> # ::std::
1061 <unscoped-template-name>
1063 ::= <substitution> */
1066 demangle_name (dm
, encode_return_type
)
1068 int *encode_return_type
;
1070 int start
= substitution_start (dm
);
1071 char peek
= peek_char (dm
);
1072 int is_std_substitution
= 0;
1074 /* Generally, the return type is encoded if the function is a
1075 template-id, and suppressed otherwise. There are a few cases,
1076 though, in which the return type is not encoded even for a
1077 templated function. In these cases, this flag is set. */
1078 int suppress_return_type
= 0;
1080 DEMANGLE_TRACE ("name", dm
);
1085 /* This is a <nested-name>. */
1086 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1090 RETURN_IF_ERROR (demangle_local_name (dm
));
1091 *encode_return_type
= 0;
1095 /* The `St' substitution allows a name nested in std:: to appear
1096 without being enclosed in a nested name. */
1097 if (peek_char_next (dm
) == 't')
1099 (void) next_char (dm
);
1100 (void) next_char (dm
);
1101 RETURN_IF_ERROR (result_add (dm
, "std::"));
1103 (demangle_unqualified_name (dm
, &suppress_return_type
));
1104 is_std_substitution
= 1;
1107 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1108 /* Check if a template argument list immediately follows.
1109 If so, then we just demangled an <unqualified-template-name>. */
1110 if (peek_char (dm
) == 'I')
1112 /* A template name of the form std::<unqualified-name> is a
1113 substitution candidate. */
1114 if (is_std_substitution
)
1115 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1116 /* Demangle the <template-args> here. */
1117 RETURN_IF_ERROR (demangle_template_args (dm
));
1118 *encode_return_type
= !suppress_return_type
;
1121 *encode_return_type
= 0;
1126 /* This is an <unscoped-name> or <unscoped-template-name>. */
1127 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1129 /* If the <unqualified-name> is followed by template args, this
1130 is an <unscoped-template-name>. */
1131 if (peek_char (dm
) == 'I')
1133 /* Add a substitution for the unqualified template name. */
1134 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1136 RETURN_IF_ERROR (demangle_template_args (dm
));
1137 *encode_return_type
= !suppress_return_type
;
1140 *encode_return_type
= 0;
1148 /* Demangles and emits a <nested-name>.
1150 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E */
1153 demangle_nested_name (dm
, encode_return_type
)
1155 int *encode_return_type
;
1159 DEMANGLE_TRACE ("nested-name", dm
);
1161 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1163 peek
= peek_char (dm
);
1164 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1166 dyn_string_t cv_qualifiers
;
1169 /* Snarf up CV qualifiers. */
1170 cv_qualifiers
= dyn_string_new (24);
1171 if (cv_qualifiers
== NULL
)
1172 return STATUS_ALLOCATION_FAILED
;
1173 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1175 /* Emit them, preceded by a space. */
1176 status
= result_add_char (dm
, ' ');
1177 if (STATUS_NO_ERROR (status
))
1178 status
= result_add_string (dm
, cv_qualifiers
);
1179 /* The CV qualifiers that occur in a <nested-name> will be
1180 qualifiers for member functions. These are placed at the end
1181 of the function. Therefore, shift the caret to the left by
1182 the length of the qualifiers, so other text is inserted
1183 before them and they stay at the end. */
1184 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
) - 1);
1186 dyn_string_delete (cv_qualifiers
);
1187 RETURN_IF_ERROR (status
);
1190 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1191 /* No need to demangle the final <unqualified-name>; demangle_prefix
1193 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1198 /* Demangles and emits a <prefix>.
1200 <prefix> ::= <prefix> <unqualified-name>
1201 ::= <template-prefix> <template-args>
1205 <template-prefix> ::= <prefix>
1206 ::= <substitution> */
1209 demangle_prefix (dm
, encode_return_type
)
1211 int *encode_return_type
;
1213 int start
= substitution_start (dm
);
1216 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1217 After <template-args>, it is set to non-zero; after everything
1218 else it is set to zero. */
1220 /* Generally, the return type is encoded if the function is a
1221 template-id, and suppressed otherwise. There are a few cases,
1222 though, in which the return type is not encoded even for a
1223 templated function. In these cases, this flag is set. */
1224 int suppress_return_type
= 0;
1226 DEMANGLE_TRACE ("prefix", dm
);
1232 if (end_of_name_p (dm
))
1233 return "Unexpected end of name in <compound-name>.";
1235 peek
= peek_char (dm
);
1237 /* We'll initialize suppress_return_type to false, and set it to true
1238 if we end up demangling a constructor name. However, make
1239 sure we're not actually about to demangle template arguments
1240 -- if so, this is the <template-args> following a
1241 <template-prefix>, so we'll want the previous flag value
1244 suppress_return_type
= 0;
1246 if (IS_DIGIT ((unsigned char) peek
)
1247 || (peek
>= 'a' && peek
<= 'z')
1248 || peek
== 'C' || peek
== 'D'
1251 /* We have another level of scope qualification. */
1253 RETURN_IF_ERROR (result_add (dm
, NAMESPACE_SEPARATOR
));
1258 /* The substitution determines whether this is a
1260 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1263 /* It's just a name. */
1265 (demangle_unqualified_name (dm
, &suppress_return_type
));
1266 *encode_return_type
= 0;
1269 else if (peek
== 'Z')
1270 RETURN_IF_ERROR (demangle_local_name (dm
));
1271 else if (peek
== 'I')
1273 RETURN_IF_ERROR (demangle_template_args (dm
));
1275 /* Now we want to indicate to the caller that we've
1276 demangled template arguments, thus the prefix was a
1277 <template-prefix>. That's so that the caller knows to
1278 demangle the function's return type, if this turns out to
1279 be a function name. But, if it's a member template
1280 constructor or a templated conversion operator, report it
1281 as untemplated. Those never get encoded return types. */
1282 *encode_return_type
= !suppress_return_type
;
1284 else if (peek
== 'E')
1288 return "Unexpected character in <compound-name>.";
1291 && peek_char (dm
) != 'E')
1292 /* Add a new substitution for the prefix thus far. */
1293 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1297 /* Demangles and emits an <unqualified-name>. If this
1298 <unqualified-name> is for a special function type that should never
1299 have its return type encoded (particularly, a constructor or
1300 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1303 <unqualified-name> ::= <operator-name>
1305 ::= <source-name> */
1308 demangle_unqualified_name (dm
, suppress_return_type
)
1310 int *suppress_return_type
;
1312 char peek
= peek_char (dm
);
1314 DEMANGLE_TRACE ("unqualified-name", dm
);
1316 /* By default, don't force suppression of the return type (though
1317 non-template functions still don't get a return type encoded). */
1318 *suppress_return_type
= 0;
1320 if (IS_DIGIT ((unsigned char) peek
))
1321 RETURN_IF_ERROR (demangle_source_name (dm
));
1322 else if (peek
>= 'a' && peek
<= 'z')
1326 /* Conversion operators never have a return type encoded. */
1327 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1328 *suppress_return_type
= 1;
1330 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
, NULL
));
1332 else if (peek
== 'C' || peek
== 'D')
1334 /* Constructors never have a return type encoded. */
1336 *suppress_return_type
= 1;
1338 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1341 return "Unexpected character in <unqualified-name>.";
1346 /* Demangles and emits <source-name>.
1348 <source-name> ::= <length number> <identifier> */
1351 demangle_source_name (dm
)
1356 DEMANGLE_TRACE ("source-name", dm
);
1358 /* Decode the length of the identifier. */
1359 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1361 return "Zero length in <source-name>.";
1363 /* Now the identifier itself. It's placed into last_source_name,
1364 where it can be used to build a constructor or destructor name. */
1365 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1366 dm
->last_source_name
));
1369 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
1374 /* Demangles a number, either a <number> or a <positive-number> at the
1375 current position, consuming all consecutive digit characters. Sets
1376 *VALUE to the resulting numberand returns STATUS_OK. The number is
1377 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1378 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1380 <number> ::= [n] <positive-number>
1382 <positive-number> ::= <decimal integer> */
1385 demangle_number (dm
, value
, base
, is_signed
)
1391 dyn_string_t number
= dyn_string_new (10);
1393 DEMANGLE_TRACE ("number", dm
);
1396 return STATUS_ALLOCATION_FAILED
;
1398 demangle_number_literally (dm
, number
, base
, is_signed
);
1399 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1400 dyn_string_delete (number
);
1405 /* Demangles a number at the current position. The digits (and minus
1406 sign, if present) that make up the number are appended to STR.
1407 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1408 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1409 accepted. Does not consume a trailing underscore or other
1410 terminating character. */
1413 demangle_number_literally (dm
, str
, base
, is_signed
)
1419 DEMANGLE_TRACE ("number*", dm
);
1421 if (base
!= 10 && base
!= 36)
1422 return STATUS_INTERNAL_ERROR
;
1424 /* An `n' denotes a negative number. */
1425 if (is_signed
&& peek_char (dm
) == 'n')
1427 /* Skip past the n. */
1429 /* The normal way to write a negative number is with a minus
1431 if (!dyn_string_append_char (str
, '-'))
1432 return STATUS_ALLOCATION_FAILED
;
1435 /* Loop until we hit a non-digit. */
1438 char peek
= peek_char (dm
);
1439 if (IS_DIGIT ((unsigned char) peek
)
1440 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1442 /* Accumulate digits. */
1443 if (!dyn_string_append_char (str
, next_char (dm
)))
1444 return STATUS_ALLOCATION_FAILED
;
1447 /* Not a digit? All done. */
1454 /* Demangles an identifier at the current position of LENGTH
1455 characters and places it in IDENTIFIER. */
1458 demangle_identifier (dm
, length
, identifier
)
1461 dyn_string_t identifier
;
1463 DEMANGLE_TRACE ("identifier", dm
);
1465 dyn_string_clear (identifier
);
1466 if (!dyn_string_resize (identifier
, length
))
1467 return STATUS_ALLOCATION_FAILED
;
1469 while (length
-- > 0)
1472 if (end_of_name_p (dm
))
1473 return "Unexpected end of name in <identifier>.";
1474 ch
= next_char (dm
);
1476 /* Handle extended Unicode characters. We encode them as __U{hex}_,
1477 where {hex} omits leading 0's. For instance, '$' is encoded as
1480 && peek_char (dm
) == '_'
1481 && peek_char_next (dm
) == 'U')
1485 advance_char (dm
); advance_char (dm
); length
-= 2;
1486 while (length
-- > 0)
1488 ch
= next_char (dm
);
1493 if (ch
!= '_' || length
< 0)
1494 return STATUS_ERROR
;
1497 /* __U_ just means __U. */
1498 if (!dyn_string_append_cstr (identifier
, "__U"))
1499 return STATUS_ALLOCATION_FAILED
;
1505 ch
= strtol (buf
, 0, 16);
1509 if (!dyn_string_append_char (identifier
, ch
))
1510 return STATUS_ALLOCATION_FAILED
;
1513 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1514 followed by the source file name and some random characters.
1515 Unless we're in strict mode, decipher these names appropriately. */
1518 char *name
= dyn_string_buf (identifier
);
1519 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1521 /* Compare the first, fixed part. */
1522 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1524 name
+= prefix_length
;
1525 /* The next character might be a period, an underscore, or
1526 dollar sign, depending on the target architecture's
1527 assembler's capabilities. After that comes an `N'. */
1528 if ((*name
== '.' || *name
== '_' || *name
== '$')
1529 && *(name
+ 1) == 'N')
1530 /* This looks like the anonymous namespace identifier.
1531 Replace it with something comprehensible. */
1532 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1539 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1540 the short form is emitted; otherwise the full source form
1541 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1542 operands that the operator takes. If TYPE_ARG is non-NULL,
1543 *TYPE_ARG is set to 1 if the first argument is a type and 0
1594 ::= st # sizeof (a type)
1595 ::= sz # sizeof (an expression)
1596 ::= cv <type> # cast
1597 ::= v [0-9] <source-name> # vendor extended operator */
1600 demangle_operator_name (dm
, short_name
, num_args
, type_arg
)
1606 struct operator_code
1608 /* The mangled code for this operator. */
1609 const char *const code
;
1610 /* The source name of this operator. */
1611 const char *const name
;
1612 /* The number of arguments this operator takes. */
1616 static const struct operator_code operators
[] =
1627 { "da", " delete[]", 1 },
1629 { "dl", " delete" , 1 },
1637 { "lS", "<<=" , 2 },
1646 { "na", " new[]" , 1 },
1650 { "nw", " new" , 1 },
1656 { "pm", "->*" , 2 },
1662 { "rS", ">>=" , 2 },
1665 { "sz", "sizeof" , 1 }
1668 const int num_operators
=
1669 sizeof (operators
) / sizeof (struct operator_code
);
1671 int c0
= next_char (dm
);
1672 int c1
= next_char (dm
);
1673 const struct operator_code
* p1
= operators
;
1674 const struct operator_code
* p2
= operators
+ num_operators
;
1676 DEMANGLE_TRACE ("operator-name", dm
);
1678 /* Assume the first argument is not a type. */
1682 /* Is this a vendor-extended operator? */
1683 if (c0
== 'v' && IS_DIGIT (c1
))
1685 RETURN_IF_ERROR (result_add (dm
, "operator "));
1686 RETURN_IF_ERROR (demangle_source_name (dm
));
1691 /* Is this a conversion operator? */
1692 if (c0
== 'c' && c1
== 'v')
1694 RETURN_IF_ERROR (result_add (dm
, "operator "));
1695 /* Demangle the converted-to type. */
1696 RETURN_IF_ERROR (demangle_type (dm
));
1701 /* Is it the sizeof variant that takes a type? */
1702 if (c0
== 's' && c1
== 't')
1704 RETURN_IF_ERROR (result_add (dm
, " sizeof"));
1711 /* Perform a binary search for the operator code. */
1714 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1715 char match0
= p
->code
[0];
1716 char match1
= p
->code
[1];
1718 if (c0
== match0
&& c1
== match1
)
1722 RETURN_IF_ERROR (result_add (dm
, "operator"));
1723 RETURN_IF_ERROR (result_add (dm
, p
->name
));
1724 *num_args
= p
->num_args
;
1730 /* Couldn't find it. */
1731 return "Unknown code in <operator-name>.";
1734 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1741 /* Demangles and omits an <nv-offset>.
1743 <nv-offset> ::= <offset number> # non-virtual base override */
1746 demangle_nv_offset (dm
)
1749 dyn_string_t number
;
1750 status_t status
= STATUS_OK
;
1752 DEMANGLE_TRACE ("h-offset", dm
);
1754 /* Demangle the offset. */
1755 number
= dyn_string_new (4);
1757 return STATUS_ALLOCATION_FAILED
;
1758 demangle_number_literally (dm
, number
, 10, 1);
1760 /* Don't display the offset unless in verbose mode. */
1763 status
= result_add (dm
, " [nv:");
1764 if (STATUS_NO_ERROR (status
))
1765 status
= result_add_string (dm
, number
);
1766 if (STATUS_NO_ERROR (status
))
1767 status
= result_add_char (dm
, ']');
1771 dyn_string_delete (number
);
1772 RETURN_IF_ERROR (status
);
1776 /* Demangles and emits a <v-offset>.
1778 <v-offset> ::= <offset number> _ <virtual offset number>
1779 # virtual base override, with vcall offset */
1782 demangle_v_offset (dm
)
1785 dyn_string_t number
;
1786 status_t status
= STATUS_OK
;
1788 DEMANGLE_TRACE ("v-offset", dm
);
1790 /* Demangle the offset. */
1791 number
= dyn_string_new (4);
1793 return STATUS_ALLOCATION_FAILED
;
1794 demangle_number_literally (dm
, number
, 10, 1);
1796 /* Don't display the offset unless in verbose mode. */
1799 status
= result_add (dm
, " [v:");
1800 if (STATUS_NO_ERROR (status
))
1801 status
= result_add_string (dm
, number
);
1802 if (STATUS_NO_ERROR (status
))
1803 result_add_char (dm
, ',');
1805 dyn_string_delete (number
);
1806 RETURN_IF_ERROR (status
);
1808 /* Demangle the separator. */
1809 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1811 /* Demangle the vcall offset. */
1812 number
= dyn_string_new (4);
1814 return STATUS_ALLOCATION_FAILED
;
1815 demangle_number_literally (dm
, number
, 10, 1);
1817 /* Don't display the vcall offset unless in verbose mode. */
1820 status
= result_add_string (dm
, number
);
1821 if (STATUS_NO_ERROR (status
))
1822 status
= result_add_char (dm
, ']');
1824 dyn_string_delete (number
);
1825 RETURN_IF_ERROR (status
);
1830 /* Demangles and emits a <call-offset>.
1832 <call-offset> ::= h <nv-offset> _
1833 ::= v <v-offset> _ */
1836 demangle_call_offset (dm
)
1839 DEMANGLE_TRACE ("call-offset", dm
);
1841 switch (peek_char (dm
))
1845 /* Demangle the offset. */
1846 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1847 /* Demangle the separator. */
1848 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1853 /* Demangle the offset. */
1854 RETURN_IF_ERROR (demangle_v_offset (dm
));
1855 /* Demangle the separator. */
1856 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1860 return "Unrecognized <call-offset>.";
1866 /* Demangles and emits a <special-name>.
1868 <special-name> ::= GV <object name> # Guard variable
1869 ::= TV <type> # virtual table
1871 ::= TI <type> # typeinfo structure
1872 ::= TS <type> # typeinfo name
1874 Other relevant productions include thunks:
1876 <special-name> ::= T <call-offset> <base encoding>
1877 # base is the nominal target function of thunk
1879 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1880 # base is the nominal target function of thunk
1881 # first call-offset is 'this' adjustment
1882 # second call-offset is result adjustment
1886 <call-offset> ::= h <nv-offset> _
1889 Also demangles the special g++ manglings,
1891 <special-name> ::= TC <type> <offset number> _ <base type>
1892 # construction vtable
1893 ::= TF <type> # typeinfo function (old ABI only)
1894 ::= TJ <type> # java Class structure */
1897 demangle_special_name (dm
)
1900 dyn_string_t number
;
1902 char peek
= peek_char (dm
);
1904 DEMANGLE_TRACE ("special-name", dm
);
1908 /* Consume the G. */
1910 switch (peek_char (dm
))
1913 /* A guard variable name. */
1915 RETURN_IF_ERROR (result_add (dm
, "guard variable for "));
1916 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1920 /* A reference temporary. */
1922 RETURN_IF_ERROR (result_add (dm
, "reference temporary for "));
1923 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1927 return "Unrecognized <special-name>.";
1930 else if (peek
== 'T')
1932 status_t status
= STATUS_OK
;
1934 /* Other C++ implementation miscellania. Consume the T. */
1937 switch (peek_char (dm
))
1940 /* Virtual table. */
1942 RETURN_IF_ERROR (result_add (dm
, "vtable for "));
1943 RETURN_IF_ERROR (demangle_type (dm
));
1947 /* VTT structure. */
1949 RETURN_IF_ERROR (result_add (dm
, "VTT for "));
1950 RETURN_IF_ERROR (demangle_type (dm
));
1954 /* Typeinfo structure. */
1956 RETURN_IF_ERROR (result_add (dm
, "typeinfo for "));
1957 RETURN_IF_ERROR (demangle_type (dm
));
1961 /* Typeinfo function. Used only in old ABI with new mangling. */
1963 RETURN_IF_ERROR (result_add (dm
, "typeinfo fn for "));
1964 RETURN_IF_ERROR (demangle_type (dm
));
1968 /* Character string containing type name, used in typeinfo. */
1970 RETURN_IF_ERROR (result_add (dm
, "typeinfo name for "));
1971 RETURN_IF_ERROR (demangle_type (dm
));
1975 /* The java Class variable corresponding to a C++ class. */
1977 RETURN_IF_ERROR (result_add (dm
, "java Class for "));
1978 RETURN_IF_ERROR (demangle_type (dm
));
1982 /* Non-virtual thunk. */
1984 RETURN_IF_ERROR (result_add (dm
, "non-virtual thunk"));
1985 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1986 /* Demangle the separator. */
1987 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1988 /* Demangle and emit the target name and function type. */
1989 RETURN_IF_ERROR (result_add (dm
, " to "));
1990 RETURN_IF_ERROR (demangle_encoding (dm
));
1994 /* Virtual thunk. */
1996 RETURN_IF_ERROR (result_add (dm
, "virtual thunk"));
1997 RETURN_IF_ERROR (demangle_v_offset (dm
));
1998 /* Demangle the separator. */
1999 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2000 /* Demangle and emit the target function. */
2001 RETURN_IF_ERROR (result_add (dm
, " to "));
2002 RETURN_IF_ERROR (demangle_encoding (dm
));
2006 /* Covariant return thunk. */
2008 RETURN_IF_ERROR (result_add (dm
, "covariant return thunk"));
2009 RETURN_IF_ERROR (demangle_call_offset (dm
));
2010 RETURN_IF_ERROR (demangle_call_offset (dm
));
2011 /* Demangle and emit the target function. */
2012 RETURN_IF_ERROR (result_add (dm
, " to "));
2013 RETURN_IF_ERROR (demangle_encoding (dm
));
2017 /* TC is a special g++ mangling for a construction vtable. */
2020 dyn_string_t derived_type
;
2023 RETURN_IF_ERROR (result_add (dm
, "construction vtable for "));
2025 /* Demangle the derived type off to the side. */
2026 RETURN_IF_ERROR (result_push (dm
));
2027 RETURN_IF_ERROR (demangle_type (dm
));
2028 derived_type
= (dyn_string_t
) result_pop (dm
);
2030 /* Demangle the offset. */
2031 number
= dyn_string_new (4);
2034 dyn_string_delete (derived_type
);
2035 return STATUS_ALLOCATION_FAILED
;
2037 demangle_number_literally (dm
, number
, 10, 1);
2038 /* Demangle the underscore separator. */
2039 status
= demangle_char (dm
, '_');
2041 /* Demangle the base type. */
2042 if (STATUS_NO_ERROR (status
))
2043 status
= demangle_type (dm
);
2045 /* Emit the derived type. */
2046 if (STATUS_NO_ERROR (status
))
2047 status
= result_add (dm
, "-in-");
2048 if (STATUS_NO_ERROR (status
))
2049 status
= result_add_string (dm
, derived_type
);
2050 dyn_string_delete (derived_type
);
2052 /* Don't display the offset unless in verbose mode. */
2055 status
= result_add_char (dm
, ' ');
2056 if (STATUS_NO_ERROR (status
))
2057 result_add_string (dm
, number
);
2059 dyn_string_delete (number
);
2060 RETURN_IF_ERROR (status
);
2063 /* If flag_strict, fall through. */
2066 return "Unrecognized <special-name>.";
2070 return STATUS_ERROR
;
2075 /* Demangles and emits a <ctor-dtor-name>.
2078 ::= C1 # complete object (in-charge) ctor
2079 ::= C2 # base object (not-in-charge) ctor
2080 ::= C3 # complete object (in-charge) allocating ctor
2081 ::= D0 # deleting (in-charge) dtor
2082 ::= D1 # complete object (in-charge) dtor
2083 ::= D2 # base object (not-in-charge) dtor */
2086 demangle_ctor_dtor_name (dm
)
2089 static const char *const ctor_flavors
[] =
2095 static const char *const dtor_flavors
[] =
2097 "in-charge deleting",
2103 char peek
= peek_char (dm
);
2105 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
2109 /* A constructor name. Consume the C. */
2111 flavor
= next_char (dm
);
2112 if (flavor
< '1' || flavor
> '3')
2113 return "Unrecognized constructor.";
2114 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2117 case '1': dm
->is_constructor
= gnu_v3_complete_object_ctor
;
2119 case '2': dm
->is_constructor
= gnu_v3_base_object_ctor
;
2121 case '3': dm
->is_constructor
= gnu_v3_complete_object_allocating_ctor
;
2124 /* Print the flavor of the constructor if in verbose mode. */
2127 RETURN_IF_ERROR (result_add (dm
, "["));
2128 RETURN_IF_ERROR (result_add (dm
, ctor_flavors
[flavor
- '1']));
2129 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2132 else if (peek
== 'D')
2134 /* A destructor name. Consume the D. */
2136 flavor
= next_char (dm
);
2137 if (flavor
< '0' || flavor
> '2')
2138 return "Unrecognized destructor.";
2139 RETURN_IF_ERROR (result_add_char (dm
, '~'));
2140 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2143 case '0': dm
->is_destructor
= gnu_v3_deleting_dtor
;
2145 case '1': dm
->is_destructor
= gnu_v3_complete_object_dtor
;
2147 case '2': dm
->is_destructor
= gnu_v3_base_object_dtor
;
2150 /* Print the flavor of the destructor if in verbose mode. */
2153 RETURN_IF_ERROR (result_add (dm
, " ["));
2154 RETURN_IF_ERROR (result_add (dm
, dtor_flavors
[flavor
- '0']));
2155 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2159 return STATUS_ERROR
;
2164 /* Handle pointer, reference, and pointer-to-member cases for
2165 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2166 build a pointer/reference type. We snarf all these, plus the
2167 following <type>, all at once since we need to know whether we have
2168 a pointer to data or pointer to function to construct the right
2169 output syntax. C++'s pointer syntax is hairy.
2171 This function adds substitution candidates for every nested
2172 pointer/reference type it processes, including the outermost, final
2173 type, assuming the substitution starts at SUBSTITUTION_START in the
2174 demangling result. For example, if this function demangles
2175 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2176 `Foo**', in that order.
2178 *INSERT_POS is a quantity used internally, when this function calls
2179 itself recursively, to figure out where to insert pointer
2180 punctuation on the way up. On entry to this function, INSERT_POS
2181 should point to a temporary value, but that value need not be
2186 ::= <pointer-to-member-type>
2188 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2191 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2194 int substitution_start
;
2197 int is_substitution_candidate
= 1;
2199 DEMANGLE_TRACE ("type*", dm
);
2201 /* Scan forward, collecting pointers and references into symbols,
2202 until we hit something else. Then emit the type. */
2203 switch (peek_char (dm
))
2206 /* A pointer. Snarf the `P'. */
2208 /* Demangle the underlying type. */
2209 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2210 substitution_start
));
2211 /* Insert an asterisk where we're told to; it doesn't
2212 necessarily go at the end. If we're doing Java style output,
2213 there is no pointer symbol. */
2214 if (dm
->style
!= DMGL_JAVA
)
2215 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2216 /* The next (outermost) pointer or reference character should go
2222 /* A reference. Snarf the `R'. */
2224 /* Demangle the underlying type. */
2225 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2226 substitution_start
));
2227 /* Insert an ampersand where we're told to; it doesn't
2228 necessarily go at the end. */
2229 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2230 /* The next (outermost) pointer or reference character should go
2237 /* A pointer-to-member. */
2238 dyn_string_t class_type
;
2240 int reset_caret
= 0;
2241 int old_caret_position
;
2246 /* Capture the type of which this is a pointer-to-member. */
2247 RETURN_IF_ERROR (result_push (dm
));
2248 RETURN_IF_ERROR (demangle_type (dm
));
2249 class_type
= (dyn_string_t
) result_pop (dm
);
2251 peek
= peek_char (dm
);
2252 old_caret_position
= result_get_caret (dm
);
2253 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
2255 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2258 if (cv_qualifiers
== NULL
)
2259 return STATUS_ALLOCATION_FAILED
;
2261 /* Decode all adjacent CV qualifiers. */
2262 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2264 /* Emit them, and shift the caret left so that the
2265 underlying type will be emitted before the
2267 status
= result_add_string (dm
, cv_qualifiers
);
2268 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2270 dyn_string_delete (cv_qualifiers
);
2271 RETURN_IF_ERROR (status
);
2272 /* Prepend a blank. */
2273 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2274 result_shift_caret (dm
, -1);
2276 peek
= peek_char (dm
);
2281 /* A pointer-to-member function. We want output along the
2282 lines of `void (C::*) (int, int)'. Demangle the function
2283 type, which would in this case give `void () (int, int)'
2284 and set *insert_pos to the spot between the first
2286 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2287 else if (peek
== 'A')
2288 /* A pointer-to-member array variable. We want output that
2289 looks like `int (Klass::*) [10]'. Demangle the array type
2290 as `int () [10]', and set *insert_pos to the spot between
2292 status
= demangle_array_type (dm
, insert_pos
);
2295 /* A pointer-to-member variable. Demangle the type of the
2296 pointed-to member. */
2297 status
= demangle_type (dm
);
2298 /* Make it pretty. */
2299 if (STATUS_NO_ERROR (status
)
2300 && !result_previous_char_is_space (dm
))
2301 status
= result_add_char (dm
, ' ');
2302 /* The pointer-to-member notation (e.g. `C::*') follows the
2304 *insert_pos
= result_caret_pos (dm
);
2307 /* Build the pointer-to-member notation. */
2308 if (STATUS_NO_ERROR (status
))
2309 status
= result_insert (dm
, *insert_pos
, "::*");
2310 if (STATUS_NO_ERROR (status
))
2311 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2312 /* There may be additional levels of (pointer or reference)
2313 indirection in this type. If so, the `*' and `&' should be
2314 added after the pointer-to-member notation (e.g. `C::*&' for
2315 a reference to a pointer-to-member of class C). */
2316 *insert_pos
+= dyn_string_length (class_type
) + 3;
2319 dyn_string_delete (class_type
);
2322 result_set_caret (dm
, old_caret_position
);
2324 RETURN_IF_ERROR (status
);
2329 /* Ooh, tricky, a pointer-to-function. When we demangle the
2330 function type, the return type should go at the very
2332 *insert_pos
= result_caret_pos (dm
);
2333 /* The parentheses indicate this is a function pointer or
2335 RETURN_IF_ERROR (result_add (dm
, "()"));
2336 /* Now demangle the function type. The return type will be
2337 inserted before the `()', and the argument list will go after
2339 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2340 /* We should now have something along the lines of
2341 `void () (int, int)'. The pointer or reference characters
2342 have to inside the first set of parentheses. *insert_pos has
2343 already been updated to point past the end of the return
2344 type. Move it one character over so it points inside the
2350 /* An array pointer or reference. demangle_array_type will figure
2351 out where the asterisks and ampersands go. */
2352 RETURN_IF_ERROR (demangle_array_type (dm
, insert_pos
));
2358 /* Qualified base type. Pick up the qualifiers. */
2360 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2362 if (cv_qualifiers
== NULL
)
2363 return STATUS_ALLOCATION_FAILED
;
2365 /* Pick up all adjacent CV qualifiers. */
2366 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2368 /* Demangle the underlying type. */
2369 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2371 /* Insert the qualifiers where we're told to. */
2372 if (STATUS_NO_ERROR (status
))
2374 status
= result_insert_char (dm
, *insert_pos
, ' ');
2376 if (STATUS_NO_ERROR (status
))
2377 status
= result_insert_string (dm
, *insert_pos
, cv_qualifiers
);
2380 /* The next character should go after the qualifiers. */
2381 *insert_pos
+= dyn_string_length (cv_qualifiers
);
2383 dyn_string_delete (cv_qualifiers
);
2384 RETURN_IF_ERROR (status
);
2389 /* No more pointer or reference tokens; this is therefore a
2390 pointer to data. Finish up by demangling the underlying
2392 RETURN_IF_ERROR (demangle_type (dm
));
2393 /* The pointer or reference characters follow the underlying
2394 type, as in `int*&'. */
2395 *insert_pos
= result_caret_pos (dm
);
2396 /* Because of the production <type> ::= <substitution>,
2397 demangle_type will already have added the underlying type as
2398 a substitution candidate. Don't do it again. */
2399 is_substitution_candidate
= 0;
2403 if (is_substitution_candidate
)
2404 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2409 /* Demangles and emits a <type>.
2411 <type> ::= <builtin-type>
2413 ::= <class-enum-type>
2415 ::= <pointer-to-member-type>
2416 ::= <template-param>
2417 ::= <template-template-param> <template-args>
2418 ::= <CV-qualifiers> <type>
2419 ::= P <type> # pointer-to
2420 ::= R <type> # reference-to
2421 ::= C <type> # complex pair (C 2000)
2422 ::= G <type> # imaginary (C 2000)
2423 ::= U <source-name> <type> # vendor extended type qualifier
2424 ::= <substitution> */
2430 int start
= substitution_start (dm
);
2431 char peek
= peek_char (dm
);
2433 int encode_return_type
= 0;
2434 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2437 /* A <type> can be a <substitution>; therefore, this <type> is a
2438 substitution candidate unless a special condition holds (see
2440 int is_substitution_candidate
= 1;
2442 DEMANGLE_TRACE ("type", dm
);
2444 /* A <class-enum-type> can start with a digit (a <source-name>), an
2445 N (a <nested-name>), or a Z (a <local-name>). */
2446 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2447 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2448 /* Lower-case letters begin <builtin-type>s, except for `r', which
2449 denotes restrict. */
2450 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2452 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2453 /* Built-in types are not substitution candidates. */
2454 is_substitution_candidate
= 0;
2462 /* CV-qualifiers (including restrict). We have to demangle
2463 them off to the side, since C++ syntax puts them in a funny
2464 place for qualified pointer and reference types. */
2467 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2468 int old_caret_position
= result_get_caret (dm
);
2470 if (cv_qualifiers
== NULL
)
2471 return STATUS_ALLOCATION_FAILED
;
2473 /* Decode all adjacent CV qualifiers. */
2474 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2476 /* If the underlying type is a pointer or reference type, we
2477 need to call demangle_type_ptr to find out where to put
2479 peek
= peek_char (dm
);
2480 if (peek
== 'P' || peek
== 'R' || peek
== 'M')
2482 status
= demangle_type_ptr (dm
, &insert_pos
,
2483 substitution_start (dm
));
2484 if (STATUS_NO_ERROR (status
))
2486 status
= result_insert_char (dm
, insert_pos
, ' ');
2487 if (STATUS_NO_ERROR (status
))
2488 status
= result_insert_string (dm
, insert_pos
+ 1,
2491 dyn_string_delete (cv_qualifiers
);
2492 RETURN_IF_ERROR (status
);
2496 /* Emit the qualifiers, and shift the caret left so that
2497 the underlying type will be emitted first. */
2498 status
= result_add_string (dm
, cv_qualifiers
);
2499 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2501 dyn_string_delete (cv_qualifiers
);
2502 RETURN_IF_ERROR (status
);
2503 /* Also prepend a blank, if needed. */
2504 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2505 result_shift_caret (dm
, -1);
2507 /* Demangle the underlying type. It will be emitted before
2508 the CV qualifiers, since we moved the caret. */
2509 RETURN_IF_ERROR (demangle_type (dm
));
2511 /* Put the caret back where it was previously. */
2512 result_set_caret (dm
, old_caret_position
);
2518 /* The return type should go at the current position. */
2519 insert_pos
= result_caret_pos (dm
);
2520 /* Put in parentheses to indicate that this is a function. */
2521 RETURN_IF_ERROR (result_add (dm
, "()"));
2522 /* Demangle the function type. The return type will be
2523 inserted before the '()', and the argument list will go
2525 RETURN_IF_ERROR (demangle_function_type (dm
, &insert_pos
));
2529 RETURN_IF_ERROR (demangle_array_type (dm
, NULL
));
2533 /* It's either a <template-param> or a
2534 <template-template-param>. In either case, demangle the
2536 RETURN_IF_ERROR (demangle_template_param (dm
));
2538 /* Check for a template argument list; if one is found, it's a
2539 <template-template-param> ::= <template-param>
2540 ::= <substitution> */
2541 if (peek_char (dm
) == 'I')
2543 /* Add a substitution candidate. The template parameter
2544 `T' token is a substitution candidate by itself,
2545 without the template argument list. */
2546 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2548 /* Now demangle the template argument list. */
2549 RETURN_IF_ERROR (demangle_template_args (dm
));
2550 /* The entire type, including the template template
2551 parameter and its argument list, will be added as a
2552 substitution candidate below. */
2558 /* First check if this is a special substitution. If it is,
2559 this is a <class-enum-type>. Special substitutions have a
2560 letter following the `S'; other substitutions have a digit
2562 peek_next
= peek_char_next (dm
);
2563 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2565 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2567 /* The substituted name may have been a template name.
2568 Check if template arguments follow, and if so, demangle
2570 if (peek_char (dm
) == 'I')
2571 RETURN_IF_ERROR (demangle_template_args (dm
));
2573 /* A substitution token is not itself a substitution
2574 candidate. (However, if the substituted template is
2575 instantiated, the resulting type is.) */
2576 is_substitution_candidate
= 0;
2580 /* Now some trickiness. We have a special substitution
2581 here. Often, the special substitution provides the
2582 name of a template that's subsequently instantiated,
2583 for instance `SaIcE' => std::allocator<char>. In these
2584 cases we need to add a substitution candidate for the
2585 entire <class-enum-type> and thus don't want to clear
2586 the is_substitution_candidate flag.
2588 However, it's possible that what we have here is a
2589 substitution token representing an entire type, such as
2590 `Ss' => std::string. In this case, we mustn't add a
2591 new substitution candidate for this substitution token.
2592 To detect this case, remember where the start of the
2593 substitution token is. */
2594 const char *next
= dm
->next
;
2595 /* Now demangle the <class-enum-type>. */
2597 (demangle_class_enum_type (dm
, &encode_return_type
));
2598 /* If all that was just demangled is the two-character
2599 special substitution token, supress the addition of a
2600 new candidate for it. */
2601 if (dm
->next
== next
+ 2)
2602 is_substitution_candidate
= 0;
2610 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2611 /* demangle_type_ptr adds all applicable substitution
2613 is_substitution_candidate
= 0;
2617 /* A C99 complex type. */
2618 RETURN_IF_ERROR (result_add (dm
, "complex "));
2620 RETURN_IF_ERROR (demangle_type (dm
));
2624 /* A C99 imaginary type. */
2625 RETURN_IF_ERROR (result_add (dm
, "imaginary "));
2627 RETURN_IF_ERROR (demangle_type (dm
));
2631 /* Vendor-extended type qualifier. */
2633 RETURN_IF_ERROR (demangle_source_name (dm
));
2634 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2635 RETURN_IF_ERROR (demangle_type (dm
));
2639 return "Unexpected character in <type>.";
2642 if (is_substitution_candidate
)
2643 /* Add a new substitution for the type. If this type was a
2644 <template-param>, pass its index since from the point of
2645 substitutions; a <template-param> token is a substitution
2646 candidate distinct from the type that is substituted for it. */
2647 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2649 /* Pop off template argument lists added during mangling of this
2651 pop_to_template_arg_list (dm
, old_arg_list
);
2656 /* C++ source names of builtin types, indexed by the mangled code
2657 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2658 static const char *const builtin_type_names
[26] =
2660 "signed char", /* a */
2664 "long double", /* e */
2666 "__float128", /* g */
2667 "unsigned char", /* h */
2672 "unsigned long", /* m */
2674 "unsigned __int128", /* o */
2679 "unsigned short", /* t */
2683 "long long", /* x */
2684 "unsigned long long", /* y */
2688 /* Java source names of builtin types. Types that arn't valid in Java
2689 are also included here - we don't fail if someone attempts to demangle a
2690 C++ symbol in Java style. */
2691 static const char *const java_builtin_type_names
[26] =
2693 "signed char", /* a */
2694 "boolean", /* C++ "bool" */ /* b */
2695 "byte", /* C++ "char" */ /* c */
2697 "long double", /* e */
2699 "__float128", /* g */
2700 "unsigned char", /* h */
2705 "unsigned long", /* m */
2707 "unsigned __int128", /* o */
2712 "unsigned short", /* t */
2715 "char", /* C++ "wchar_t" */ /* w */
2716 "long", /* C++ "long long" */ /* x */
2717 "unsigned long long", /* y */
2721 /* Demangles and emits a <builtin-type>.
2723 <builtin-type> ::= v # void
2728 ::= h # unsigned char
2730 ::= t # unsigned short
2732 ::= j # unsigned int
2734 ::= m # unsigned long
2735 ::= x # long long, __int64
2736 ::= y # unsigned long long, __int64
2738 ::= o # unsigned __int128
2741 ::= e # long double, __float80
2744 ::= u <source-name> # vendor extended type */
2747 demangle_builtin_type (dm
)
2751 char code
= peek_char (dm
);
2753 DEMANGLE_TRACE ("builtin-type", dm
);
2758 RETURN_IF_ERROR (demangle_source_name (dm
));
2761 else if (code
>= 'a' && code
<= 'z')
2763 const char *type_name
;
2764 /* Java uses different names for some built-in types. */
2765 if (dm
->style
== DMGL_JAVA
)
2766 type_name
= java_builtin_type_names
[code
- 'a'];
2768 type_name
= builtin_type_names
[code
- 'a'];
2769 if (type_name
== NULL
)
2770 return "Unrecognized <builtin-type> code.";
2772 RETURN_IF_ERROR (result_add (dm
, type_name
));
2777 return "Non-alphabetic <builtin-type> code.";
2780 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2781 restrict) at the current position. The qualifiers are appended to
2782 QUALIFIERS. Returns STATUS_OK. */
2785 demangle_CV_qualifiers (dm
, qualifiers
)
2787 dyn_string_t qualifiers
;
2789 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2793 switch (peek_char (dm
))
2796 if (!dyn_string_append_space (qualifiers
))
2797 return STATUS_ALLOCATION_FAILED
;
2798 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2799 return STATUS_ALLOCATION_FAILED
;
2803 if (!dyn_string_append_space (qualifiers
))
2804 return STATUS_ALLOCATION_FAILED
;
2805 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2806 return STATUS_ALLOCATION_FAILED
;
2810 if (!dyn_string_append_space (qualifiers
))
2811 return STATUS_ALLOCATION_FAILED
;
2812 if (!dyn_string_append_cstr (qualifiers
, "const"))
2813 return STATUS_ALLOCATION_FAILED
;
2824 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2825 position in the result string of the start of the function
2826 identifier, at which the function's return type will be inserted;
2827 *FUNCTION_NAME_POS is updated to position past the end of the
2828 function's return type.
2830 <function-type> ::= F [Y] <bare-function-type> E */
2833 demangle_function_type (dm
, function_name_pos
)
2835 int *function_name_pos
;
2837 DEMANGLE_TRACE ("function-type", dm
);
2838 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2839 if (peek_char (dm
) == 'Y')
2841 /* Indicate this function has C linkage if in verbose mode. */
2843 RETURN_IF_ERROR (result_add (dm
, " [extern \"C\"] "));
2846 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2847 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2851 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2852 position in the result string at which the function return type
2853 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2854 function's return type is assumed not to be encoded.
2856 <bare-function-type> ::= <signature type>+ */
2859 demangle_bare_function_type (dm
, return_type_pos
)
2861 int *return_type_pos
;
2863 /* Sequence is the index of the current function parameter, counting
2864 from zero. The value -1 denotes the return type. */
2866 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2868 DEMANGLE_TRACE ("bare-function-type", dm
);
2870 RETURN_IF_ERROR (result_add_char (dm
, '('));
2871 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2874 /* We're decoding the function's return type. */
2876 dyn_string_t return_type
;
2877 status_t status
= STATUS_OK
;
2879 /* Decode the return type off to the side. */
2880 RETURN_IF_ERROR (result_push (dm
));
2881 RETURN_IF_ERROR (demangle_type (dm
));
2882 return_type
= (dyn_string_t
) result_pop (dm
);
2884 /* Add a space to the end of the type. Insert the return
2885 type where we've been asked to. */
2886 if (!dyn_string_append_space (return_type
))
2887 status
= STATUS_ALLOCATION_FAILED
;
2888 if (STATUS_NO_ERROR (status
))
2890 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2892 status
= STATUS_ALLOCATION_FAILED
;
2894 *return_type_pos
+= dyn_string_length (return_type
);
2897 dyn_string_delete (return_type
);
2898 RETURN_IF_ERROR (status
);
2902 /* Skip `void' parameter types. One should only occur as
2903 the only type in a parameter list; in that case, we want
2904 to print `foo ()' instead of `foo (void)'. */
2905 if (peek_char (dm
) == 'v')
2906 /* Consume the v. */
2910 /* Separate parameter types by commas. */
2912 RETURN_IF_ERROR (result_add (dm
, ", "));
2913 /* Demangle the type. */
2914 RETURN_IF_ERROR (demangle_type (dm
));
2920 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2922 /* We should have demangled at least one parameter type (which would
2923 be void, for a function that takes no parameters), plus the
2924 return type, if we were supposed to demangle that. */
2926 return "Missing function return type.";
2927 else if (sequence
== 0)
2928 return "Missing function parameter.";
2933 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2934 non-zero if the type is a template-id, zero otherwise.
2936 <class-enum-type> ::= <name> */
2939 demangle_class_enum_type (dm
, encode_return_type
)
2941 int *encode_return_type
;
2943 DEMANGLE_TRACE ("class-enum-type", dm
);
2945 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2949 /* Demangles and emits an <array-type>.
2951 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2952 pointer or reference to an array, except that asterisk and
2953 ampersand punctuation is omitted (since it's not know at this
2954 point). *PTR_INSERT_POS is set to the position in the demangled
2955 name at which this punctuation should be inserted. For example,
2956 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2957 between the parentheses.
2959 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2960 pointer- or reference-qualified. Then, for example, `A10_i' is
2961 demangled simply as `int[10]'.
2963 <array-type> ::= A [<dimension number>] _ <element type>
2964 ::= A <dimension expression> _ <element type> */
2967 demangle_array_type (dm
, ptr_insert_pos
)
2969 int *ptr_insert_pos
;
2971 status_t status
= STATUS_OK
;
2972 dyn_string_t array_size
= NULL
;
2975 DEMANGLE_TRACE ("array-type", dm
);
2977 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2979 /* Demangle the array size into array_size. */
2980 peek
= peek_char (dm
);
2982 /* Array bound is omitted. This is a C99-style VLA. */
2984 else if (IS_DIGIT (peek_char (dm
)))
2986 /* It looks like a constant array bound. */
2987 array_size
= dyn_string_new (10);
2988 if (array_size
== NULL
)
2989 return STATUS_ALLOCATION_FAILED
;
2990 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2994 /* Anything is must be an expression for a nont-constant array
2995 bound. This happens if the array type occurs in a template
2996 and the array bound references a template parameter. */
2997 RETURN_IF_ERROR (result_push (dm
));
2998 RETURN_IF_ERROR (demangle_expression (dm
));
2999 array_size
= (dyn_string_t
) result_pop (dm
);
3001 /* array_size may have been allocated by now, so we can't use
3002 RETURN_IF_ERROR until it's been deallocated. */
3004 /* Demangle the base type of the array. */
3005 if (STATUS_NO_ERROR (status
))
3006 status
= demangle_char (dm
, '_');
3007 if (STATUS_NO_ERROR (status
))
3008 status
= demangle_type (dm
);
3010 if (ptr_insert_pos
!= NULL
)
3012 /* This array is actually part of an pointer- or
3013 reference-to-array type. Format appropriately, except we
3014 don't know which and how much punctuation to use. */
3015 if (STATUS_NO_ERROR (status
))
3016 status
= result_add (dm
, " () ");
3017 /* Let the caller know where to insert the punctuation. */
3018 *ptr_insert_pos
= result_caret_pos (dm
) - 2;
3021 /* Emit the array dimension syntax. */
3022 if (STATUS_NO_ERROR (status
))
3023 status
= result_add_char (dm
, '[');
3024 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
3025 status
= result_add_string (dm
, array_size
);
3026 if (STATUS_NO_ERROR (status
))
3027 status
= result_add_char (dm
, ']');
3028 if (array_size
!= NULL
)
3029 dyn_string_delete (array_size
);
3031 RETURN_IF_ERROR (status
);
3036 /* Demangles and emits a <template-param>.
3038 <template-param> ::= T_ # first template parameter
3039 ::= T <parameter-2 number> _ */
3042 demangle_template_param (dm
)
3046 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
3049 DEMANGLE_TRACE ("template-param", dm
);
3051 /* Make sure there is a template argmust list in which to look up
3052 this parameter reference. */
3053 if (current_arg_list
== NULL
)
3054 return "Template parameter outside of template.";
3056 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
3057 if (peek_char (dm
) == '_')
3061 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
3064 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3066 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
3068 /* parm_number exceeded the number of arguments in the current
3069 template argument list. */
3070 return "Template parameter number out of bounds.";
3071 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
3076 /* Demangles and emits a <template-args>.
3078 <template-args> ::= I <template-arg>+ E */
3081 demangle_template_args (dm
)
3085 dyn_string_t old_last_source_name
;
3086 template_arg_list_t arg_list
= template_arg_list_new ();
3088 if (arg_list
== NULL
)
3089 return STATUS_ALLOCATION_FAILED
;
3091 /* Preserve the most recently demangled source name. */
3092 old_last_source_name
= dm
->last_source_name
;
3093 dm
->last_source_name
= dyn_string_new (0);
3095 DEMANGLE_TRACE ("template-args", dm
);
3097 if (dm
->last_source_name
== NULL
)
3098 return STATUS_ALLOCATION_FAILED
;
3100 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
3101 RETURN_IF_ERROR (result_open_template_list (dm
));
3109 RETURN_IF_ERROR (result_add (dm
, ", "));
3111 /* Capture the template arg. */
3112 RETURN_IF_ERROR (result_push (dm
));
3113 RETURN_IF_ERROR (demangle_template_arg (dm
));
3114 arg
= result_pop (dm
);
3116 /* Emit it in the demangled name. */
3117 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
3119 /* Save it for use in expanding <template-param>s. */
3120 template_arg_list_add_arg (arg_list
, arg
);
3122 while (peek_char (dm
) != 'E');
3123 /* Append the '>'. */
3124 RETURN_IF_ERROR (result_close_template_list (dm
));
3126 /* Consume the 'E'. */
3129 /* Restore the most recent demangled source name. */
3130 dyn_string_delete (dm
->last_source_name
);
3131 dm
->last_source_name
= old_last_source_name
;
3133 /* Push the list onto the top of the stack of template argument
3134 lists, so that arguments from it are used from now on when
3135 expanding <template-param>s. */
3136 push_template_arg_list (dm
, arg_list
);
3141 /* This function, which does not correspond to a production in the
3142 mangling spec, handles the `literal' production for both
3143 <template-arg> and <expr-primary>. It does not expect or consume
3144 the initial `L' or final `E'. The demangling is given by:
3146 <literal> ::= <type> </value/ number>
3148 and the emitted output is `(type)number'. */
3151 demangle_literal (dm
)
3154 char peek
= peek_char (dm
);
3155 dyn_string_t value_string
;
3158 DEMANGLE_TRACE ("literal", dm
);
3160 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
3162 /* If not in verbose mode and this is a builtin type, see if we
3163 can produce simpler numerical output. In particular, for
3164 integer types shorter than `long', just write the number
3165 without type information; for bools, write `true' or `false'.
3166 Other refinements could be made here too. */
3168 /* This constant string is used to map from <builtin-type> codes
3169 (26 letters of the alphabet) to codes that determine how the
3170 value will be displayed. The codes are:
3174 A space means the value will be represented using cast
3176 static const char *const code_map
= "ibi iii ll ii i ";
3178 char code
= code_map
[peek
- 'a'];
3179 /* FIXME: Implement demangling of floats and doubles. */
3181 return STATUS_UNIMPLEMENTED
;
3184 /* It's a boolean. */
3187 /* Consume the b. */
3189 /* Look at the next character. It should be 0 or 1,
3190 corresponding to false or true, respectively. */
3191 value
= peek_char (dm
);
3193 RETURN_IF_ERROR (result_add (dm
, "false"));
3194 else if (value
== '1')
3195 RETURN_IF_ERROR (result_add (dm
, "true"));
3197 return "Unrecognized bool constant.";
3198 /* Consume the 0 or 1. */
3202 else if (code
== 'i' || code
== 'l')
3204 /* It's an integer or long. */
3206 /* Consume the type character. */
3209 /* Demangle the number and write it out. */
3210 value_string
= dyn_string_new (0);
3211 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3212 if (STATUS_NO_ERROR (status
))
3213 status
= result_add_string (dm
, value_string
);
3214 /* For long integers, append an l. */
3215 if (code
== 'l' && STATUS_NO_ERROR (status
))
3216 status
= result_add_char (dm
, code
);
3217 dyn_string_delete (value_string
);
3219 RETURN_IF_ERROR (status
);
3222 /* ...else code == ' ', so fall through to represent this
3223 literal's type explicitly using cast syntax. */
3226 RETURN_IF_ERROR (result_add_char (dm
, '('));
3227 RETURN_IF_ERROR (demangle_type (dm
));
3228 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3230 value_string
= dyn_string_new (0);
3231 if (value_string
== NULL
)
3232 return STATUS_ALLOCATION_FAILED
;
3234 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3235 if (STATUS_NO_ERROR (status
))
3236 status
= result_add_string (dm
, value_string
);
3237 dyn_string_delete (value_string
);
3238 RETURN_IF_ERROR (status
);
3243 /* Demangles and emits a <template-arg>.
3245 <template-arg> ::= <type> # type
3246 ::= L <type> <value number> E # literal
3247 ::= LZ <encoding> E # external name
3248 ::= X <expression> E # expression */
3251 demangle_template_arg (dm
)
3254 DEMANGLE_TRACE ("template-arg", dm
);
3256 switch (peek_char (dm
))
3261 if (peek_char (dm
) == 'Z')
3263 /* External name. */
3265 /* FIXME: Standard is contradictory here. */
3266 RETURN_IF_ERROR (demangle_encoding (dm
));
3269 RETURN_IF_ERROR (demangle_literal (dm
));
3270 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3276 RETURN_IF_ERROR (demangle_expression (dm
));
3277 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3281 RETURN_IF_ERROR (demangle_type (dm
));
3288 /* Demangles and emits an <expression>.
3290 <expression> ::= <unary operator-name> <expression>
3291 ::= <binary operator-name> <expression> <expression>
3293 ::= <scope-expression> */
3296 demangle_expression (dm
)
3299 char peek
= peek_char (dm
);
3301 DEMANGLE_TRACE ("expression", dm
);
3303 if (peek
== 'L' || peek
== 'T')
3304 RETURN_IF_ERROR (demangle_expr_primary (dm
));
3305 else if (peek
== 's' && peek_char_next (dm
) == 'r')
3306 RETURN_IF_ERROR (demangle_scope_expression (dm
));
3308 /* An operator expression. */
3312 status_t status
= STATUS_OK
;
3313 dyn_string_t operator_name
;
3315 /* We have an operator name. Since we want to output binary
3316 operations in infix notation, capture the operator name
3318 RETURN_IF_ERROR (result_push (dm
));
3319 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
,
3321 operator_name
= (dyn_string_t
) result_pop (dm
);
3323 /* If it's binary, do an operand first. */
3326 status
= result_add_char (dm
, '(');
3327 if (STATUS_NO_ERROR (status
))
3328 status
= demangle_expression (dm
);
3329 if (STATUS_NO_ERROR (status
))
3330 status
= result_add_char (dm
, ')');
3333 /* Emit the operator. */
3334 if (STATUS_NO_ERROR (status
))
3335 status
= result_add_string (dm
, operator_name
);
3336 dyn_string_delete (operator_name
);
3337 RETURN_IF_ERROR (status
);
3339 /* Emit its second (if binary) or only (if unary) operand. */
3340 RETURN_IF_ERROR (result_add_char (dm
, '('));
3342 RETURN_IF_ERROR (demangle_type (dm
));
3344 RETURN_IF_ERROR (demangle_expression (dm
));
3345 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3347 /* The ternary operator takes a third operand. */
3350 RETURN_IF_ERROR (result_add (dm
, ":("));
3351 RETURN_IF_ERROR (demangle_expression (dm
));
3352 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3359 /* Demangles and emits a <scope-expression>.
3361 <scope-expression> ::= sr <qualifying type> <source-name>
3362 ::= sr <qualifying type> <encoding> */
3365 demangle_scope_expression (dm
)
3368 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3369 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3370 RETURN_IF_ERROR (demangle_type (dm
));
3371 RETURN_IF_ERROR (result_add (dm
, "::"));
3372 RETURN_IF_ERROR (demangle_encoding (dm
));
3376 /* Demangles and emits an <expr-primary>.
3378 <expr-primary> ::= <template-param>
3379 ::= L <type> <value number> E # literal
3380 ::= L <mangled-name> E # external name */
3383 demangle_expr_primary (dm
)
3386 char peek
= peek_char (dm
);
3388 DEMANGLE_TRACE ("expr-primary", dm
);
3391 RETURN_IF_ERROR (demangle_template_param (dm
));
3392 else if (peek
== 'L')
3394 /* Consume the `L'. */
3396 peek
= peek_char (dm
);
3399 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3401 RETURN_IF_ERROR (demangle_literal (dm
));
3403 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3406 return STATUS_ERROR
;
3411 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3412 if the substitution is the name of a template, zero otherwise.
3414 <substitution> ::= S <seq-id> _
3418 ::= Sa # ::std::allocator
3419 ::= Sb # ::std::basic_string
3420 ::= Ss # ::std::basic_string<char,
3421 ::std::char_traits<char>,
3422 ::std::allocator<char> >
3423 ::= Si # ::std::basic_istream<char,
3424 std::char_traits<char> >
3425 ::= So # ::std::basic_ostream<char,
3426 std::char_traits<char> >
3427 ::= Sd # ::std::basic_iostream<char,
3428 std::char_traits<char> >
3432 demangle_substitution (dm
, template_p
)
3440 DEMANGLE_TRACE ("substitution", dm
);
3442 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3444 /* Scan the substitution sequence index. A missing number denotes
3446 peek
= peek_char (dm
);
3449 /* If the following character is 0-9 or a capital letter, interpret
3450 the sequence up to the next underscore as a base-36 substitution
3452 else if (IS_DIGIT ((unsigned char) peek
)
3453 || (peek
>= 'A' && peek
<= 'Z'))
3454 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3457 const char *new_last_source_name
= NULL
;
3462 RETURN_IF_ERROR (result_add (dm
, "std"));
3466 RETURN_IF_ERROR (result_add (dm
, "std::allocator"));
3467 new_last_source_name
= "allocator";
3472 RETURN_IF_ERROR (result_add (dm
, "std::basic_string"));
3473 new_last_source_name
= "basic_string";
3480 RETURN_IF_ERROR (result_add (dm
, "std::string"));
3481 new_last_source_name
= "string";
3485 RETURN_IF_ERROR (result_add (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3486 new_last_source_name
= "basic_string";
3494 RETURN_IF_ERROR (result_add (dm
, "std::istream"));
3495 new_last_source_name
= "istream";
3499 RETURN_IF_ERROR (result_add (dm
, "std::basic_istream<char, std::char_traits<char> >"));
3500 new_last_source_name
= "basic_istream";
3508 RETURN_IF_ERROR (result_add (dm
, "std::ostream"));
3509 new_last_source_name
= "ostream";
3513 RETURN_IF_ERROR (result_add (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3514 new_last_source_name
= "basic_ostream";
3522 RETURN_IF_ERROR (result_add (dm
, "std::iostream"));
3523 new_last_source_name
= "iostream";
3527 RETURN_IF_ERROR (result_add (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3528 new_last_source_name
= "basic_iostream";
3534 return "Unrecognized <substitution>.";
3537 /* Consume the character we just processed. */
3540 if (new_last_source_name
!= NULL
)
3542 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3543 new_last_source_name
))
3544 return STATUS_ALLOCATION_FAILED
;
3550 /* Look up the substitution text. Since `S_' is the most recent
3551 substitution, `S0_' is the second-most-recent, etc., shift the
3552 numbering by one. */
3553 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3555 return "Substitution number out of range.";
3557 /* Emit the substitution text. */
3558 RETURN_IF_ERROR (result_add_string (dm
, text
));
3560 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3564 /* Demangles and emits a <local-name>.
3566 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3567 := Z <function encoding> E s [<discriminator>] */
3570 demangle_local_name (dm
)
3573 int old_caret_position
= result_get_caret (dm
);
3575 DEMANGLE_TRACE ("local-name", dm
);
3577 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3578 RETURN_IF_ERROR (demangle_encoding (dm
));
3580 /* Restore the caret to avoid being confused by any qualifiers we
3581 may have found during the encoding. */
3582 result_set_caret (dm
, old_caret_position
);
3584 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3585 RETURN_IF_ERROR (result_add (dm
, "::"));
3587 if (peek_char (dm
) == 's')
3589 /* Local character string literal. */
3590 RETURN_IF_ERROR (result_add (dm
, "string literal"));
3591 /* Consume the s. */
3593 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3598 /* Local name for some other entity. Demangle its name. */
3599 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3600 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3606 /* Optimonally demangles and emits a <discriminator>. If there is no
3607 <discriminator> at the current position in the mangled string, the
3608 descriminator is assumed to be zero. Emit the discriminator number
3609 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3610 discriminator is zero.
3612 <discriminator> ::= _ <number> */
3615 demangle_discriminator (dm
, suppress_first
)
3619 /* Output for <discriminator>s to the demangled name is completely
3620 suppressed if not in verbose mode. */
3622 if (peek_char (dm
) == '_')
3624 /* Consume the underscore. */
3627 RETURN_IF_ERROR (result_add (dm
, " [#"));
3628 /* Check if there's a number following the underscore. */
3629 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3632 /* Demangle the number. */
3633 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3635 /* Write the discriminator. The mangled number is two
3636 less than the discriminator ordinal, counting from
3638 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 1,
3639 (dyn_string_t
) dm
->result
));
3642 return STATUS_ERROR
;
3644 RETURN_IF_ERROR (result_add_char (dm
, ']'));
3646 else if (!suppress_first
)
3649 RETURN_IF_ERROR (result_add (dm
, " [#0]"));
3655 /* Demangle NAME into RESULT, which must be an initialized
3656 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3657 an error message, and the contents of RESULT are unchanged. */
3660 cp_demangle (name
, result
, style
)
3662 dyn_string_t result
;
3666 int length
= strlen (name
);
3668 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3670 demangling_t dm
= demangling_new (name
, style
);
3672 return STATUS_ALLOCATION_FAILED
;
3674 status
= result_push (dm
);
3675 if (status
!= STATUS_OK
)
3677 demangling_delete (dm
);
3681 status
= demangle_mangled_name (dm
);
3682 if (STATUS_NO_ERROR (status
))
3684 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3685 if (!dyn_string_copy (result
, demangled
))
3686 return STATUS_ALLOCATION_FAILED
;
3687 dyn_string_delete (demangled
);
3690 demangling_delete (dm
);
3694 /* It's evidently not a mangled C++ name. It could be the name
3695 of something with C linkage, though, so just copy NAME into
3697 if (!dyn_string_copy_cstr (result
, name
))
3698 return STATUS_ALLOCATION_FAILED
;
3705 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3706 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3707 an error message, and the contents of RESULT are unchanged. */
3710 cp_demangle_type (type_name
, result
)
3711 const char* type_name
;
3712 dyn_string_t result
;
3715 demangling_t dm
= demangling_new (type_name
, DMGL_GNU_V3
);
3718 return STATUS_ALLOCATION_FAILED
;
3720 /* Demangle the type name. The demangled name is stored in dm. */
3721 status
= result_push (dm
);
3722 if (status
!= STATUS_OK
)
3724 demangling_delete (dm
);
3728 status
= demangle_type (dm
);
3730 if (STATUS_NO_ERROR (status
))
3732 /* The demangling succeeded. Pop the result out of dm and copy
3734 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3735 if (!dyn_string_copy (result
, demangled
))
3736 return STATUS_ALLOCATION_FAILED
;
3737 dyn_string_delete (demangled
);
3741 demangling_delete (dm
);
3746 #if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
3747 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3749 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3750 demangling. MANGLED_NAME is a NUL-terminated character string
3751 containing the name to be demangled.
3753 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3754 *LENGTH bytes, into which the demangled name is stored. If
3755 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3756 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3757 is placed in a region of memory allocated with malloc.
3759 If LENGTH is non-NULL, the length of the buffer conaining the
3760 demangled name, is placed in *LENGTH.
3762 The return value is a pointer to the start of the NUL-terminated
3763 demangled name, or NULL if the demangling fails. The caller is
3764 responsible for deallocating this memory using free.
3766 *STATUS is set to one of the following values:
3767 0: The demangling operation succeeded.
3768 -1: A memory allocation failiure occurred.
3769 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3770 -3: One of the arguments is invalid.
3772 The demagling is performed using the C++ ABI mangling rules, with
3776 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3777 const char *mangled_name
;
3778 char *output_buffer
;
3782 struct dyn_string demangled_name
;
3788 if (mangled_name
== NULL
) {
3793 /* Did the caller provide a buffer for the demangled name? */
3794 if (output_buffer
== NULL
) {
3795 /* No; dyn_string will malloc a buffer for us. */
3796 if (!dyn_string_init (&demangled_name
, 0))
3803 /* Yes. Check that the length was provided. */
3804 if (length
== NULL
) {
3808 /* Install the buffer into a dyn_string. */
3809 demangled_name
.allocated
= *length
;
3810 demangled_name
.length
= 0;
3811 demangled_name
.s
= output_buffer
;
3814 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3815 /* MANGLED_NAME apprears to be a function or variable name.
3816 Demangle it accordingly. */
3817 result
= cp_demangle (mangled_name
, &demangled_name
, 0);
3819 /* Try to demangled MANGLED_NAME as the name of a type. */
3820 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3822 if (result
== STATUS_OK
)
3823 /* The demangling succeeded. */
3825 /* If LENGTH isn't NULL, store the allocated buffer length
3826 there; the buffer may have been realloced by dyn_string
3829 *length
= demangled_name
.allocated
;
3830 /* The operation was a success. */
3832 return dyn_string_buf (&demangled_name
);
3834 else if (result
== STATUS_ALLOCATION_FAILED
)
3835 /* A call to malloc or realloc failed during the demangling
3842 /* The demangling failed for another reason, most probably because
3843 MANGLED_NAME isn't a valid mangled name. */
3845 /* If the buffer containing the demangled name wasn't provided
3846 by the caller, free it. */
3847 if (output_buffer
== NULL
)
3848 free (dyn_string_buf (&demangled_name
));
3854 #else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
3856 /* Variant entry point for integration with the existing cplus-dem
3857 demangler. Attempts to demangle MANGLED. If the demangling
3858 succeeds, returns a buffer, allocated with malloc, containing the
3859 demangled name. The caller must deallocate the buffer using free.
3860 If the demangling failes, returns NULL. */
3863 cplus_demangle_v3 (mangled
, options
)
3864 const char* mangled
;
3867 dyn_string_t demangled
;
3869 int type
= !!(options
& DMGL_TYPES
);
3871 if (mangled
[0] == '_' && mangled
[1] == 'Z')
3872 /* It is not a type. */
3876 /* It is a type. Stop if we don't want to demangle types. */
3881 flag_verbose
= !!(options
& DMGL_VERBOSE
);
3883 /* Create a dyn_string to hold the demangled name. */
3884 demangled
= dyn_string_new (0);
3885 /* Attempt the demangling. */
3887 /* Appears to be a function or variable name. */
3888 status
= cp_demangle (mangled
, demangled
, 0);
3890 /* Try to demangle it as the name of a type. */
3891 status
= cp_demangle_type (mangled
, demangled
);
3893 if (STATUS_NO_ERROR (status
))
3894 /* Demangling succeeded. */
3896 /* Grab the demangled result from the dyn_string. It was
3897 allocated with malloc, so we can return it directly. */
3898 char *return_value
= dyn_string_release (demangled
);
3899 /* Hand back the demangled name. */
3900 return return_value
;
3902 else if (status
== STATUS_ALLOCATION_FAILED
)
3904 fprintf (stderr
, "Memory allocation failed.\n");
3908 /* Demangling failed. */
3910 dyn_string_delete (demangled
);
3915 /* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3916 conventions, but the output formatting is a little different.
3917 This instructs the C++ demangler not to emit pointer characters ("*"), and
3918 to use Java's namespace separator symbol ("." instead of "::"). It then
3919 does an additional pass over the demangled output to replace instances
3920 of JArray<TYPE> with TYPE[]. */
3923 java_demangle_v3 (mangled
)
3924 const char* mangled
;
3926 dyn_string_t demangled
;
3932 char *cplus_demangled
;
3935 /* Create a dyn_string to hold the demangled name. */
3936 demangled
= dyn_string_new (0);
3938 /* Attempt the demangling. */
3939 status
= cp_demangle ((char *) mangled
, demangled
, DMGL_JAVA
);
3941 if (STATUS_NO_ERROR (status
))
3942 /* Demangling succeeded. */
3944 /* Grab the demangled result from the dyn_string. */
3945 cplus_demangled
= dyn_string_release (demangled
);
3947 else if (status
== STATUS_ALLOCATION_FAILED
)
3949 fprintf (stderr
, "Memory allocation failed.\n");
3953 /* Demangling failed. */
3955 dyn_string_delete (demangled
);
3959 len
= strlen (cplus_demangled
);
3960 next
= cplus_demangled
;
3964 /* Replace occurances of JArray<TYPE> with TYPE[]. */
3967 char *open_str
= strstr (next
, "JArray<");
3968 char *close_str
= NULL
;
3970 close_str
= strchr (next
, '>');
3972 if (open_str
!= NULL
&& (close_str
== NULL
|| close_str
> open_str
))
3977 demangled
= dyn_string_new(len
);
3979 /* Copy prepending symbols, if any. */
3980 if (open_str
> next
)
3983 dyn_string_append_cstr (demangled
, next
);
3985 next
= open_str
+ 7;
3987 else if (close_str
!= NULL
)
3991 /* Copy prepending type symbol, if any. Squash any spurious
3993 if (close_str
> next
&& next
[0] != ' ')
3996 dyn_string_append_cstr (demangled
, next
);
3998 dyn_string_append_cstr (demangled
, "[]");
3999 next
= close_str
+ 1;
4003 /* There are no more arrays. Copy the rest of the symbol, or
4004 simply return the original symbol if no changes were made. */
4005 if (next
== cplus_demangled
)
4006 return cplus_demangled
;
4008 dyn_string_append_cstr (demangled
, next
);
4013 free (cplus_demangled
);
4016 return_value
= dyn_string_release (demangled
);
4018 return_value
= NULL
;
4020 return return_value
;
4023 #endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
4026 #ifndef IN_GLIBCPP_V3
4027 /* Demangle NAME in the G++ V3 ABI demangling style, and return either
4028 zero, indicating that some error occurred, or a demangling_t
4029 holding the results. */
4031 demangle_v3_with_details (name
)
4037 if (strncmp (name
, "_Z", 2))
4040 dm
= demangling_new (name
, DMGL_GNU_V3
);
4043 fprintf (stderr
, "Memory allocation failed.\n");
4047 status
= result_push (dm
);
4048 if (! STATUS_NO_ERROR (status
))
4050 demangling_delete (dm
);
4051 fprintf (stderr
, "%s\n", status
);
4055 status
= demangle_mangled_name (dm
);
4056 if (STATUS_NO_ERROR (status
))
4059 demangling_delete (dm
);
4064 /* Return non-zero iff NAME is the mangled form of a constructor name
4065 in the G++ V3 ABI demangling style. Specifically, return:
4066 - '1' if NAME is a complete object constructor,
4067 - '2' if NAME is a base object constructor, or
4068 - '3' if NAME is a complete object allocating constructor. */
4069 enum gnu_v3_ctor_kinds
4070 is_gnu_v3_mangled_ctor (name
)
4073 demangling_t dm
= demangle_v3_with_details (name
);
4077 enum gnu_v3_ctor_kinds result
= dm
->is_constructor
;
4078 demangling_delete (dm
);
4082 return (enum gnu_v3_ctor_kinds
) 0;
4086 /* Return non-zero iff NAME is the mangled form of a destructor name
4087 in the G++ V3 ABI demangling style. Specifically, return:
4088 - '0' if NAME is a deleting destructor,
4089 - '1' if NAME is a complete object destructor, or
4090 - '2' if NAME is a base object destructor. */
4091 enum gnu_v3_dtor_kinds
4092 is_gnu_v3_mangled_dtor (name
)
4095 demangling_t dm
= demangle_v3_with_details (name
);
4099 enum gnu_v3_dtor_kinds result
= dm
->is_destructor
;
4100 demangling_delete (dm
);
4104 return (enum gnu_v3_dtor_kinds
) 0;
4106 #endif /* IN_GLIBCPP_V3 */
4109 #ifdef STANDALONE_DEMANGLER
4113 static void print_usage
4114 PARAMS ((FILE* fp
, int exit_value
));
4116 /* Non-zero if CHAR is a character than can occur in a mangled name. */
4117 #define is_mangled_char(CHAR) \
4118 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
4119 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
4121 /* The name of this program, as invoked. */
4122 const char* program_name
;
4124 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
4127 print_usage (fp
, exit_value
)
4131 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
4132 fprintf (fp
, "Options:\n");
4133 fprintf (fp
, " -h,--help Display this message.\n");
4134 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
4135 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
4136 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
4141 /* Option specification for getopt_long. */
4142 static const struct option long_options
[] =
4144 { "help", no_argument
, NULL
, 'h' },
4145 { "strict", no_argument
, NULL
, 's' },
4146 { "verbose", no_argument
, NULL
, 'v' },
4147 { NULL
, no_argument
, NULL
, 0 },
4150 /* Main entry for a demangling filter executable. It will demangle
4151 its command line arguments, if any. If none are provided, it will
4152 filter stdin to stdout, replacing any recognized mangled C++ names
4153 with their demangled equivalents. */
4164 /* Use the program name of this program, as invoked. */
4165 program_name
= argv
[0];
4167 /* Parse options. */
4170 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
4173 case '?': /* Unrecognized option. */
4174 print_usage (stderr
, 1);
4178 print_usage (stdout
, 0);
4190 while (opt_char
!= -1);
4193 /* No command line arguments were provided. Filter stdin. */
4195 dyn_string_t mangled
= dyn_string_new (3);
4196 dyn_string_t demangled
= dyn_string_new (0);
4199 /* Read all of input. */
4200 while (!feof (stdin
))
4202 char c
= getchar ();
4204 /* The first character of a mangled name is an underscore. */
4209 /* It's not a mangled name. Print the character and go
4216 /* The second character of a mangled name is a capital `Z'. */
4221 /* It's not a mangled name. Print the previous
4222 underscore, the `Z', and go on. */
4228 /* Start keeping track of the candidate mangled name. */
4229 dyn_string_append_char (mangled
, '_');
4230 dyn_string_append_char (mangled
, 'Z');
4232 /* Pile characters into mangled until we hit one that can't
4233 occur in a mangled name. */
4235 while (!feof (stdin
) && is_mangled_char (c
))
4237 dyn_string_append_char (mangled
, c
);
4243 /* Attempt to demangle the name. */
4244 status
= cp_demangle (dyn_string_buf (mangled
), demangled
, 0);
4246 /* If the demangling succeeded, great! Print out the
4247 demangled version. */
4248 if (STATUS_NO_ERROR (status
))
4249 fputs (dyn_string_buf (demangled
), stdout
);
4250 /* Abort on allocation failures. */
4251 else if (status
== STATUS_ALLOCATION_FAILED
)
4253 fprintf (stderr
, "Memory allocation failed.\n");
4256 /* Otherwise, it might not have been a mangled name. Just
4257 print out the original text. */
4259 fputs (dyn_string_buf (mangled
), stdout
);
4261 /* If we haven't hit EOF yet, we've read one character that
4262 can't occur in a mangled name, so print it out. */
4266 /* Clear the candidate mangled name, to start afresh next
4267 time we hit a `_Z'. */
4268 dyn_string_clear (mangled
);
4271 dyn_string_delete (mangled
);
4272 dyn_string_delete (demangled
);
4275 /* Demangle command line arguments. */
4277 dyn_string_t result
= dyn_string_new (0);
4279 /* Loop over command line arguments. */
4280 for (i
= optind
; i
< argc
; ++i
)
4282 /* Attempt to demangle. */
4283 status
= cp_demangle (argv
[i
], result
, 0);
4285 /* If it worked, print the demangled name. */
4286 if (STATUS_NO_ERROR (status
))
4287 printf ("%s\n", dyn_string_buf (result
));
4288 /* Abort on allocaiton failures. */
4289 else if (status
== STATUS_ALLOCATION_FAILED
)
4291 fprintf (stderr
, "Memory allocation failed.\n");
4294 /* If not, print the error message to stderr instead. */
4296 fprintf (stderr
, "%s\n", status
);
4298 dyn_string_delete (result
);
4304 #endif /* STANDALONE_DEMANGLER */