1 /* Demangler for IA64 / g++ standard C++ ABI.
2 Copyright (C) 2000 CodeSourcery LLC.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 /* This file implements demangling of C++ names mangled according to
21 the IA64 / g++ standard C++ ABI. Use the cp_demangle function to
22 demangle a mangled name, or compile with the preprocessor macro
23 STANDALONE_DEMANGLER defined to create a demangling filter
24 executable (functionally similar to c++filt, but includes this
31 #include <sys/types.h>
44 #include "libiberty.h"
45 #include "dyn-string.h"
48 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
49 and other debugging output, will be generated. */
50 #ifdef CP_DEMANGLE_DEBUG
51 #define DEMANGLE_TRACE(PRODUCTION, DM) \
52 fprintf (stderr, " -> %-24s at position %3d\n", \
53 (PRODUCTION), current_position (DM));
55 #define DEMANGLE_TRACE(PRODUCTION, DM)
58 /* Don't include <ctype.h>, to prevent additional unresolved symbols
59 from being dragged into the C++ runtime library. */
60 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
61 #define IS_ALPHA(CHAR) \
62 (((CHAR) >= 'a' && (CHAR) <= 'z') \
63 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
65 /* If flag_verbose is zero, some simplifications will be made to the
66 output to make it easier to read and supress details that are
67 generally not of interest to the average C++ programmer.
68 Otherwise, the demangled representation will attempt to convey as
69 much information as the mangled form. */
70 static int flag_verbose
;
72 /* If flag_strict is non-zero, demangle strictly according to the
73 specification -- don't demangle special g++ manglings. */
74 static int flag_strict
;
76 /* String_list_t is an extended form of dyn_string_t which provides a link
77 field. A string_list_t may safely be cast to and used as a
80 struct string_list_def
82 struct dyn_string string
;
83 struct string_list_def
*next
;
86 typedef struct string_list_def
*string_list_t
;
88 /* Data structure representing a potential substitution. */
90 struct substitution_def
92 /* The demangled text of the substitution. */
95 /* The template parameter that this represents, indexed from zero.
96 If this is not a template paramter number, the value is
98 int template_parm_number
;
100 /* Whether this substitution represents a template item. */
104 #define NOT_TEMPLATE_PARM (-1)
106 /* Data structure representing a template argument list. */
108 struct template_arg_list_def
110 /* The next (lower) template argument list in the stack of currently
111 active template arguments. */
112 struct template_arg_list_def
*next
;
114 /* The first element in the list of template arguments in
115 left-to-right order. */
116 string_list_t first_argument
;
118 /* The last element in the arguments lists. */
119 string_list_t last_argument
;
122 typedef struct template_arg_list_def
*template_arg_list_t
;
124 /* Data structure to maintain the state of the current demangling. */
126 struct demangling_def
128 /* The full mangled name being mangled. */
131 /* Pointer into name at the current position. */
134 /* Stack for strings containing demangled result generated so far.
135 Text is emitted to the topmost (first) string. */
136 string_list_t result
;
138 /* The number of presently available substitutions. */
139 int num_substitutions
;
141 /* The allocated size of the substitutions array. */
142 int substitutions_allocated
;
144 /* An array of available substitutions. The number of elements in
145 the array is given by num_substitions, and the allocated array
146 size in substitutions_size.
148 The most recent substition is at the end, so
150 - `S_' corresponds to substititutions[num_substitutions - 1]
151 - `S0_' corresponds to substititutions[num_substitutions - 2]
154 struct substitution_def
*substitutions
;
156 /* The stack of template argument lists. */
157 template_arg_list_t template_arg_lists
;
159 /* The most recently demangled source-name. */
160 dyn_string_t last_source_name
;
163 typedef struct demangling_def
*demangling_t
;
165 /* This type is the standard return code from most functions. Values
166 other than STATUS_OK contain descriptive messages. */
167 typedef const char *status_t
;
169 /* Special values that can be used as a status_t. */
170 #define STATUS_OK NULL
171 #define STATUS_ERROR "Error."
172 #define STATUS_UNIMPLEMENTED "Unimplemented."
173 #define STATUS_INTERNAL_ERROR "Internal error."
175 /* This status code indicates a failure in malloc or realloc. */
176 static const char* const status_allocation_failed
= "Allocation failed.";
177 #define STATUS_ALLOCATION_FAILED status_allocation_failed
179 /* Non-zero if STATUS indicates that no error has occurred. */
180 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
182 /* Evaluate EXPR, which must produce a status_t. If the status code
183 indicates an error, return from the current function with that
185 #define RETURN_IF_ERROR(EXPR) \
189 if (!STATUS_NO_ERROR (s)) \
194 static status_t int_to_dyn_string
195 PARAMS ((int, dyn_string_t
));
196 static string_list_t string_list_new
198 static void string_list_delete
199 PARAMS ((string_list_t
));
200 static status_t result_add_separated_char
201 PARAMS ((demangling_t
, int));
202 static status_t result_push
203 PARAMS ((demangling_t
));
204 static string_list_t result_pop
205 PARAMS ((demangling_t
));
206 static int substitution_start
207 PARAMS ((demangling_t
));
208 static status_t substitution_add
209 PARAMS ((demangling_t
, int, int, int));
210 static dyn_string_t substitution_get
211 PARAMS ((demangling_t
, int, int *));
212 #ifdef CP_DEMANGLE_DEBUG
213 static void substitutions_print
214 PARAMS ((demangling_t
, FILE *));
216 static template_arg_list_t template_arg_list_new
218 static void template_arg_list_delete
219 PARAMS ((template_arg_list_t
));
220 static void template_arg_list_add_arg
221 PARAMS ((template_arg_list_t
, string_list_t
));
222 static string_list_t template_arg_list_get_arg
223 PARAMS ((template_arg_list_t
, int));
224 static void push_template_arg_list
225 PARAMS ((demangling_t
, template_arg_list_t
));
226 static void pop_to_template_arg_list
227 PARAMS ((demangling_t
, template_arg_list_t
));
228 #ifdef CP_DEMANGLE_DEBUG
229 static void template_arg_list_print
230 PARAMS ((template_arg_list_t
, FILE *));
232 static template_arg_list_t current_template_arg_list
233 PARAMS ((demangling_t
));
234 static demangling_t demangling_new
235 PARAMS ((const char *));
236 static void demangling_delete
237 PARAMS ((demangling_t
));
239 /* The last character of DS. Warning: DS is evaluated twice. */
240 #define dyn_string_last_char(DS) \
241 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
243 /* Append a space character (` ') to DS if it does not already end
244 with one. Evaluates to 1 on success, or 0 on allocation failure. */
245 #define dyn_string_append_space(DS) \
246 ((dyn_string_length (DS) > 0 \
247 && dyn_string_last_char (DS) != ' ') \
248 ? dyn_string_append_char ((DS), ' ') \
251 /* Returns the index of the current position in the mangled name. */
252 #define current_position(DM) ((DM)->next - (DM)->name)
254 /* Returns the character at the current position of the mangled name. */
255 #define peek_char(DM) (*((DM)->next))
257 /* Returns the character one past the current position of the mangled
259 #define peek_char_next(DM) \
260 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
262 /* Returns the character at the current position, and advances the
263 current position to the next character. */
264 #define next_char(DM) (*((DM)->next)++)
266 /* Returns non-zero if the current position is the end of the mangled
267 name, i.e. one past the last character. */
268 #define end_of_name_p(DM) (peek_char (DM) == '\0')
270 /* Advances the current position by one character. */
271 #define advance_char(DM) (++(DM)->next)
273 /* Returns the string containing the current demangled result. */
274 #define result_string(DM) (&(DM)->result->string)
276 /* Appends a dyn_string_t to the demangled result. */
277 #define result_append_string(DM, STRING) \
278 (dyn_string_append (&(DM)->result->string, (STRING)) \
279 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
281 /* Appends NUL-terminated string CSTR to the demangled result. */
282 #define result_append(DM, CSTR) \
283 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
284 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
286 /* Appends character CHAR to the demangled result. */
287 #define result_append_char(DM, CHAR) \
288 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \
289 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
291 /* The length of the current demangled result. */
292 #define result_length(DM) \
293 dyn_string_length (&(DM)->result->string)
295 /* Appends a space to the demangled result if the last character is
297 #define result_append_space(DM) \
298 (dyn_string_append_space (&(DM)->result->string) \
299 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
301 /* Appends a (less-than, greater-than) character to the result in DM
302 to (open, close) a template argument or parameter list. Appends a
303 space first if necessary to prevent spurious elision of angle
304 brackets with the previous character. */
305 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
306 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
308 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
309 success. On failure, deletes DS and returns an error code. */
312 int_to_dyn_string (value
, ds
)
319 /* Handle zero up front. */
322 if (!dyn_string_append_char (ds
, '0'))
323 return STATUS_ALLOCATION_FAILED
;
327 /* For negative numbers, emit a minus sign. */
330 if (!dyn_string_append_char (ds
, '-'))
331 return STATUS_ALLOCATION_FAILED
;
335 /* Find the power of 10 of the first digit. */
343 /* Write the digits. */
346 int digit
= value
/ mask
;
348 if (!dyn_string_append_char (ds
, '0' + digit
))
349 return STATUS_ALLOCATION_FAILED
;
351 value
-= digit
* mask
;
358 /* Creates a new string list node. The contents of the string are
359 empty, but the initial buffer allocation is LENGTH. The string
360 list node should be deleted with string_list_delete. Returns NULL
361 if allocation fails. */
364 string_list_new (length
)
367 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
370 if (!dyn_string_init ((dyn_string_t
) s
, length
))
375 /* Deletes the entire string list starting at NODE. */
378 string_list_delete (node
)
383 string_list_t next
= node
->next
;
389 /* Appends CHARACTER to the demangled result. If the current trailing
390 character of the result is CHARACTER, a space is inserted first. */
393 result_add_separated_char (dm
, character
)
397 dyn_string_t s
= &dm
->result
->string
;
399 /* Add a space if the last character is already a closing angle
400 bracket, so that a nested template arg list doesn't look like
401 it's closed with a right-shift operator. */
402 if (dyn_string_last_char (s
) == character
)
404 if (!dyn_string_append_char (s
, ' '))
405 return STATUS_ALLOCATION_FAILED
;
408 /* Add closing angle brackets. */
409 if (!dyn_string_append_char (s
, character
))
410 return STATUS_ALLOCATION_FAILED
;
415 /* Allocates and pushes a new string onto the demangled results stack
416 for DM. Subsequent demangling with DM will emit to the new string.
417 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
418 allocation failure. */
424 string_list_t new_string
= string_list_new (0);
425 if (new_string
== NULL
)
426 /* Allocation failed. */
427 return STATUS_ALLOCATION_FAILED
;
429 /* Link the new string to the front of the list of result strings. */
430 new_string
->next
= (string_list_t
) dm
->result
;
431 dm
->result
= new_string
;
435 /* Removes and returns the topmost element on the demangled results
436 stack for DM. The caller assumes ownership for the returned
443 string_list_t top
= dm
->result
;
444 dm
->result
= top
->next
;
448 /* Returns the start position of a fragment of the demangled result
449 that will be a substitution candidate. Should be called at the
450 start of productions that can add substitutions. */
453 substitution_start (dm
)
456 return result_length (dm
);
459 /* Adds the suffix of the current demangled result of DM starting at
460 START_POSITION as a potential substitution. If TEMPLATE_P is
461 non-zero, this potential substitution is a template-id.
463 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
464 is for that particular <template-param>, and is distinct from other
465 otherwise-identical types and other <template-param>s with
466 different indices. */
469 substitution_add (dm
, start_position
, template_p
, template_parm_number
)
473 int template_parm_number
;
475 dyn_string_t result
= result_string (dm
);
476 dyn_string_t substitution
= dyn_string_new (0);
479 if (substitution
== NULL
)
480 return STATUS_ALLOCATION_FAILED
;
482 /* Extract the substring of the current demangling result that
483 represents the subsitution candidate. */
484 if (!dyn_string_substring (substitution
,
485 result
, start_position
, result_length (dm
)))
487 dyn_string_delete (substitution
);
488 return STATUS_ALLOCATION_FAILED
;
491 /* If there's no room for the new entry, grow the array. */
492 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
494 size_t new_array_size
;
495 if (dm
->substitutions_allocated
> 0)
496 dm
->substitutions_allocated
*= 2;
498 dm
->substitutions_allocated
= 2;
500 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
502 dm
->substitutions
= (struct substitution_def
*)
503 realloc (dm
->substitutions
, new_array_size
);
504 if (dm
->substitutions
== NULL
)
505 /* Realloc failed. */
507 dyn_string_delete (substitution
);
508 return STATUS_ALLOCATION_FAILED
;
512 /* Add the substitution to the array. */
513 i
= dm
->num_substitutions
++;
514 dm
->substitutions
[i
].text
= substitution
;
515 dm
->substitutions
[i
].template_p
= template_p
;
516 dm
->substitutions
[i
].template_parm_number
= template_parm_number
;
518 #ifdef CP_DEMANGLE_DEBUG
519 substitutions_print (dm
, stderr
);
525 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
526 non-zero if the substitution is a template-id, zero otherwise.
527 N is numbered from zero. DM retains ownership of the returned
528 string. If N is negative, or equal to or greater than the current
529 number of substitution candidates, returns NULL. */
532 substitution_get (dm
, n
, template_p
)
537 struct substitution_def
*sub
;
539 /* Make sure N is in the valid range. */
540 if (n
< 0 || n
>= dm
->num_substitutions
)
543 sub
= &(dm
->substitutions
[n
]);
544 *template_p
= sub
->template_p
;
548 #ifdef CP_DEMANGLE_DEBUG
549 /* Debugging routine to print the current substitutions to FP. */
552 substitutions_print (dm
, fp
)
557 int num
= dm
->num_substitutions
;
559 fprintf (fp
, "SUBSTITUTIONS:\n");
560 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
563 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
566 fprintf (fp
, " S_ ");
568 fprintf (fp
, " S%d_", seq_id
);
569 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
573 #endif /* CP_DEMANGLE_DEBUG */
575 /* Creates a new template argument list. Returns NULL if allocation
578 static template_arg_list_t
579 template_arg_list_new ()
581 template_arg_list_t new_list
=
582 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
583 if (new_list
== NULL
)
585 /* Initialize the new list to have no arguments. */
586 new_list
->first_argument
= NULL
;
587 new_list
->last_argument
= NULL
;
588 /* Return the new list. */
592 /* Deletes a template argument list and the template arguments it
596 template_arg_list_delete (list
)
597 template_arg_list_t list
;
599 /* If there are any arguments on LIST, delete them. */
600 if (list
->first_argument
!= NULL
)
601 string_list_delete (list
->first_argument
);
606 /* Adds ARG to the template argument list ARG_LIST. */
609 template_arg_list_add_arg (arg_list
, arg
)
610 template_arg_list_t arg_list
;
613 if (arg_list
->first_argument
== NULL
)
614 /* If there were no arguments before, ARG is the first one. */
615 arg_list
->first_argument
= arg
;
617 /* Make ARG the last argument on the list. */
618 arg_list
->last_argument
->next
= arg
;
619 /* Make ARG the last on the list. */
620 arg_list
->last_argument
= arg
;
624 /* Returns the template arugment at position INDEX in template
625 argument list ARG_LIST. */
628 template_arg_list_get_arg (arg_list
, index
)
629 template_arg_list_t arg_list
;
632 string_list_t arg
= arg_list
->first_argument
;
633 /* Scan down the list of arguments to find the one at position
639 /* Ran out of arguments before INDEX hit zero. That's an
643 /* Return the argument at position INDEX. */
647 /* Pushes ARG_LIST onto the top of the template argument list stack. */
650 push_template_arg_list (dm
, arg_list
)
652 template_arg_list_t arg_list
;
654 arg_list
->next
= dm
->template_arg_lists
;
655 dm
->template_arg_lists
= arg_list
;
656 #ifdef CP_DEMANGLE_DEBUG
657 fprintf (stderr
, " ** pushing template arg list\n");
658 template_arg_list_print (arg_list
, stderr
);
662 /* Pops and deletes elements on the template argument list stack until
663 arg_list is the topmost element. If arg_list is NULL, all elements
664 are popped and deleted. */
667 pop_to_template_arg_list (dm
, arg_list
)
669 template_arg_list_t arg_list
;
671 while (dm
->template_arg_lists
!= arg_list
)
673 template_arg_list_t top
= dm
->template_arg_lists
;
674 /* Disconnect the topmost element from the list. */
675 dm
->template_arg_lists
= top
->next
;
676 /* Delete the popped element. */
677 template_arg_list_delete (top
);
678 #ifdef CP_DEMANGLE_DEBUG
679 fprintf (stderr
, " ** removing template arg list\n");
684 #ifdef CP_DEMANGLE_DEBUG
686 /* Prints the contents of ARG_LIST to FP. */
689 template_arg_list_print (arg_list
, fp
)
690 template_arg_list_t arg_list
;
696 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
697 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
700 fprintf (fp
, " T_ : ");
702 fprintf (fp
, " T%d_ : ", index
);
704 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
708 #endif /* CP_DEMANGLE_DEBUG */
710 /* Returns the topmost element on the stack of template argument
711 lists. If there is no list of template arguments, returns NULL. */
713 static template_arg_list_t
714 current_template_arg_list (dm
)
717 return dm
->template_arg_lists
;
720 /* Allocates a demangling_t object for demangling mangled NAME. A new
721 result must be pushed before the returned object can be used.
722 Returns NULL if allocation fails. */
725 demangling_new (name
)
729 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
736 dm
->num_substitutions
= 0;
737 dm
->substitutions_allocated
= 10;
738 dm
->template_arg_lists
= NULL
;
739 dm
->last_source_name
= dyn_string_new (0);
740 if (dm
->last_source_name
== NULL
)
742 dm
->substitutions
= (struct substitution_def
*)
743 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
744 if (dm
->substitutions
== NULL
)
746 dyn_string_delete (dm
->last_source_name
);
753 /* Deallocates a demangling_t object and all memory associated with
757 demangling_delete (dm
)
761 template_arg_list_t arg_list
= dm
->template_arg_lists
;
763 /* Delete the stack of template argument lists. */
764 while (arg_list
!= NULL
)
766 template_arg_list_t next
= arg_list
->next
;
767 template_arg_list_delete (arg_list
);
770 /* Delete the list of substitutions. */
771 for (i
= dm
->num_substitutions
; --i
>= 0; )
772 dyn_string_delete (dm
->substitutions
[i
].text
);
773 free (dm
->substitutions
);
774 /* Delete the demangled result. */
775 string_list_delete (dm
->result
);
776 /* Delete the stored identifier name. */
777 dyn_string_delete (dm
->last_source_name
);
778 /* Delete the context object itself. */
782 /* These functions demangle an alternative of the corresponding
783 production in the mangling spec. The first argument of each is a
784 demangling context structure for the current demangling
785 operation. Most emit demangled text directly to the topmost result
786 string on the result string stack in the demangling context
789 static status_t demangle_char
790 PARAMS ((demangling_t
, int));
791 static status_t demangle_mangled_name
792 PARAMS ((demangling_t
));
793 static status_t demangle_encoding
794 PARAMS ((demangling_t
));
795 static status_t demangle_name
796 PARAMS ((demangling_t
, int *));
797 static status_t demangle_nested_name
798 PARAMS ((demangling_t
, int *));
799 static status_t demangle_prefix
800 PARAMS ((demangling_t
, int *));
801 static status_t demangle_unqualified_name
802 PARAMS ((demangling_t
));
803 static status_t demangle_source_name
804 PARAMS ((demangling_t
));
805 static status_t demangle_number
806 PARAMS ((demangling_t
, int *, int, int));
807 static status_t demangle_number_literally
808 PARAMS ((demangling_t
, dyn_string_t
, int, int));
809 static status_t demangle_identifier
810 PARAMS ((demangling_t
, int, dyn_string_t
));
811 static status_t demangle_operator_name
812 PARAMS ((demangling_t
, int, int *));
813 static status_t demangle_special_name
814 PARAMS ((demangling_t
));
815 static status_t demangle_ctor_dtor_name
816 PARAMS ((demangling_t
));
817 static status_t demangle_type_ptr
818 PARAMS ((demangling_t
));
819 static status_t demangle_type
820 PARAMS ((demangling_t
));
821 static status_t demangle_CV_qualifiers
822 PARAMS ((demangling_t
, dyn_string_t
));
823 static status_t demangle_builtin_type
824 PARAMS ((demangling_t
));
825 static status_t demangle_function_type
826 PARAMS ((demangling_t
, int));
827 static status_t demangle_bare_function_type
828 PARAMS ((demangling_t
, int));
829 static status_t demangle_class_enum_type
830 PARAMS ((demangling_t
, int *));
831 static status_t demangle_array_type
832 PARAMS ((demangling_t
));
833 static status_t demangle_template_param
834 PARAMS ((demangling_t
, int *));
835 static status_t demangle_template_args
836 PARAMS ((demangling_t
));
837 static status_t demangle_literal
838 PARAMS ((demangling_t
));
839 static status_t demangle_template_arg
840 PARAMS ((demangling_t
));
841 static status_t demangle_expression
842 PARAMS ((demangling_t
));
843 static status_t demangle_scope_expression
844 PARAMS ((demangling_t
));
845 static status_t demangle_expr_primary
846 PARAMS ((demangling_t
));
847 static status_t demangle_substitution
848 PARAMS ((demangling_t
, int *));
849 static status_t demangle_local_name
850 PARAMS ((demangling_t
));
851 static status_t demangle_discriminator
852 PARAMS ((demangling_t
, int));
853 static status_t cp_demangle
854 PARAMS ((const char *, dyn_string_t
));
856 static status_t cp_demangle_type
857 PARAMS ((const char*, dyn_string_t
));
860 /* When passed to demangle_bare_function_type, indicates that the
861 function's return type is not encoded before its parameter types. */
862 #define BFT_NO_RETURN_TYPE -1
864 /* Check that the next character is C. If so, consume it. If not,
868 demangle_char (dm
, c
)
872 static char *error_message
= NULL
;
874 if (peek_char (dm
) == c
)
881 if (error_message
== NULL
)
882 error_message
= strdup ("Expected ?");
883 error_message
[9] = c
;
884 return error_message
;
888 /* Demangles and emits a <mangled-name>.
890 <mangled-name> ::= _Z <encoding> */
893 demangle_mangled_name (dm
)
896 DEMANGLE_TRACE ("mangled-name", dm
);
897 RETURN_IF_ERROR (demangle_char (dm
, '_'));
898 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
899 RETURN_IF_ERROR (demangle_encoding (dm
));
903 /* Demangles and emits an <encoding>.
905 <encoding> ::= <function name> <bare-function-type>
907 ::= <special-name> */
910 demangle_encoding (dm
)
915 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
916 char peek
= peek_char (dm
);
918 DEMANGLE_TRACE ("encoding", dm
);
920 /* Remember where the name starts. If it turns out to be a template
921 function, we'll have to insert the return type here. */
922 start_position
= result_length (dm
);
924 if (peek
== 'G' || peek
== 'T')
925 RETURN_IF_ERROR (demangle_special_name (dm
));
928 /* Now demangle the name. */
929 RETURN_IF_ERROR (demangle_name (dm
, &template_p
));
931 /* If there's anything left, the name was a function name, with
932 maybe its return type, and its parameters types, following. */
933 if (!end_of_name_p (dm
)
934 && peek_char (dm
) != 'E')
937 /* Template functions have their return type encoded. The
938 return type should be inserted at start_position. */
940 (demangle_bare_function_type (dm
, start_position
));
942 /* Non-template functions don't have their return type
945 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
949 /* Pop off template argument lists that were built during the
950 mangling of this name, to restore the old template context. */
951 pop_to_template_arg_list (dm
, old_arg_list
);
956 /* Demangles and emits a <name>.
958 <name> ::= <unscoped-name>
959 ::= <unscoped-template-name> <template-args>
963 <unscoped-name> ::= <unqualified-name>
964 ::= St <unqualified-name> # ::std::
966 <unscoped-template-name>
968 ::= <substitution> */
971 demangle_name (dm
, template_p
)
975 int start
= substitution_start (dm
);
976 char peek
= peek_char (dm
);
978 DEMANGLE_TRACE ("name", dm
);
983 /* This is a <nested-name>. */
984 RETURN_IF_ERROR (demangle_nested_name (dm
, template_p
));
988 RETURN_IF_ERROR (demangle_local_name (dm
));
993 /* The `St' substitution allows a name nested in std:: to appear
994 without being enclosed in a nested name. */
995 if (peek_char_next (dm
) == 't')
997 (void) next_char (dm
);
998 (void) next_char (dm
);
999 RETURN_IF_ERROR (result_append (dm
, "std::"));
1000 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1004 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
));
1006 /* Check if a template argument list immediately follows.
1007 If so, then we just demangled an <unqualified-template-name>. */
1008 if (peek_char (dm
) == 'I')
1010 /* The template name is a substitution candidate, unless it
1011 was already a back-substitution. */
1013 RETURN_IF_ERROR (substitution_add (dm
, start
, 0,
1014 NOT_TEMPLATE_PARM
));
1015 RETURN_IF_ERROR (demangle_template_args (dm
));
1024 /* This is an <unscoped-name> or <unscoped-template-name>. */
1025 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1027 /* If the <unqualified-name> is followed by template args, this
1028 is an <unscoped-template-name>. */
1029 if (peek_char (dm
) == 'I')
1031 /* Add a substitution for the unqualified template name. */
1032 RETURN_IF_ERROR (substitution_add (dm
, start
, 0,
1033 NOT_TEMPLATE_PARM
));
1035 RETURN_IF_ERROR (demangle_template_args (dm
));
1047 /* Demangles and emits a <nested-name>.
1049 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1052 demangle_nested_name (dm
, template_p
)
1058 DEMANGLE_TRACE ("nested-name", dm
);
1060 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1062 peek
= peek_char (dm
);
1063 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1067 /* Snarf up and emit CV qualifiers. */
1068 dyn_string_t cv_qualifiers
= dyn_string_new (24);
1069 if (cv_qualifiers
== NULL
)
1070 return STATUS_ALLOCATION_FAILED
;
1072 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1073 status
= result_append_string (dm
, cv_qualifiers
);
1074 dyn_string_delete (cv_qualifiers
);
1075 RETURN_IF_ERROR (status
);
1076 RETURN_IF_ERROR (result_append_space (dm
));
1079 RETURN_IF_ERROR (demangle_prefix (dm
, template_p
));
1080 /* No need to demangle the final <unqualified-name>; demangle_prefix
1082 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1087 /* Demangles and emits a <prefix>.
1089 <prefix> ::= <prefix> <unqualified-name>
1090 ::= <template-prefix> <template-args>
1094 <template-prefix> ::= <prefix>
1095 ::= <substitution> */
1098 demangle_prefix (dm
, template_p
)
1102 int start
= substitution_start (dm
);
1105 /* This flag is set to non-zero if the most recent (rightmost)
1106 element in the prefix was a constructor. */
1107 int last_was_ctor
= 0;
1109 /* TEMPLATE_P is updated as we decend the nesting chain. After
1110 <template-args>, it is set to non-zero; after everything else it
1113 DEMANGLE_TRACE ("prefix", dm
);
1119 if (end_of_name_p (dm
))
1120 return "Unexpected end of name in <compound-name>.";
1122 peek
= peek_char (dm
);
1124 /* We'll initialize last_was_ctor to false, and set it to true
1125 if we end up demangling a constructor name. However, make
1126 sure we're not actually about to demangle template arguments
1127 -- if so, this is the <template-args> following a
1128 <template-prefix>, so we'll want the previous flag value
1133 if (IS_DIGIT ((unsigned char) peek
)
1134 || (peek
>= 'a' && peek
<= 'z')
1135 || peek
== 'C' || peek
== 'D'
1138 /* We have another level of scope qualification. */
1140 RETURN_IF_ERROR (result_append (dm
, "::"));
1145 /* The substitution determines whether this is a
1147 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
));
1150 /* It's just a name. */
1151 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1155 /* If this element was a constructor name, make a note of
1160 else if (peek
== 'Z')
1161 RETURN_IF_ERROR (demangle_local_name (dm
));
1162 else if (peek
== 'I')
1164 RETURN_IF_ERROR (demangle_template_args (dm
));
1166 /* Now we want to indicate to the caller that we've
1167 demangled template arguments, thus the prefix was a
1168 <template-prefix>. That's so that the caller knows to
1169 demangle the function's return type, if this turns out to
1170 be a function name. */
1174 /* But, if it's a member template constructor, report it
1175 as untemplated. We don't ever want to demangle the
1176 return type of a constructor. */
1179 else if (peek
== 'E')
1183 return "Unexpected character in <compound-name>.";
1186 && peek_char (dm
) != 'E')
1187 /* Add a new substitution for the prefix thus far. */
1188 RETURN_IF_ERROR (substitution_add (dm
, start
, *template_p
,
1189 NOT_TEMPLATE_PARM
));
1193 /* Demangles and emits an <unqualified-name>. If the
1194 <unqualified-name> is a function and the first element in the
1195 argument list should be taken to be its return type,
1196 ENCODE_RETURN_TYPE is non-zero.
1198 <unqualified-name> ::= <operator-name>
1200 ::= <source-name> */
1203 demangle_unqualified_name (dm
)
1206 char peek
= peek_char (dm
);
1208 DEMANGLE_TRACE ("unqualified-name", dm
);
1210 if (IS_DIGIT ((unsigned char) peek
))
1211 RETURN_IF_ERROR (demangle_source_name (dm
));
1212 else if (peek
>= 'a' && peek
<= 'z')
1215 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1217 else if (peek
== 'C' || peek
== 'D')
1218 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1220 return "Unexpected character in <unqualified-name>.";
1225 /* Demangles and emits <source-name>.
1227 <source-name> ::= <length number> <identifier> */
1230 demangle_source_name (dm
)
1235 DEMANGLE_TRACE ("source-name", dm
);
1237 /* Decode the length of the identifier. */
1238 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1240 return "Zero length in <source-name>.";
1242 /* Now the identifier itself. It's placed into last_source_name,
1243 where it can be used to build a constructor or destructor name. */
1244 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1245 dm
->last_source_name
));
1248 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1253 /* Demangles a number, either a <number> or a <positive-number> at the
1254 current position, consuming all consecutive digit characters. Sets
1255 *VALUE to the resulting numberand returns STATUS_OK. The number is
1256 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1257 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1259 <number> ::= [n] <positive-number>
1261 <positive-number> ::= <decimal integer> */
1264 demangle_number (dm
, value
, base
, is_signed
)
1270 dyn_string_t number
= dyn_string_new (10);
1272 DEMANGLE_TRACE ("number", dm
);
1275 return STATUS_ALLOCATION_FAILED
;
1277 demangle_number_literally (dm
, number
, base
, is_signed
);
1278 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1279 dyn_string_delete (number
);
1284 /* Demangles a number at the current position. The digits (and minus
1285 sign, if present) that make up the number are appended to STR.
1286 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1287 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1288 accepted. Does not consume a trailing underscore or other
1289 terminating character. */
1292 demangle_number_literally (dm
, str
, base
, is_signed
)
1298 DEMANGLE_TRACE ("number*", dm
);
1300 if (base
!= 10 && base
!= 36)
1301 return STATUS_INTERNAL_ERROR
;
1303 /* An `n' denotes a negative number. */
1304 if (is_signed
&& peek_char (dm
) == 'n')
1306 /* Skip past the n. */
1308 /* The normal way to write a negative number is with a minus
1310 if (!dyn_string_append_char (str
, '-'))
1311 return STATUS_ALLOCATION_FAILED
;
1314 /* Loop until we hit a non-digit. */
1317 char peek
= peek_char (dm
);
1318 if (IS_DIGIT ((unsigned char) peek
)
1319 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1321 /* Accumulate digits. */
1322 if (!dyn_string_append_char (str
, next_char (dm
)))
1323 return STATUS_ALLOCATION_FAILED
;
1326 /* Not a digit? All done. */
1333 /* Demangles an identifier at the current position of LENGTH
1334 characters and places it in IDENTIFIER. */
1337 demangle_identifier (dm
, length
, identifier
)
1340 dyn_string_t identifier
;
1342 DEMANGLE_TRACE ("identifier", dm
);
1344 dyn_string_clear (identifier
);
1345 if (!dyn_string_resize (identifier
, length
))
1346 return STATUS_ALLOCATION_FAILED
;
1348 while (length
-- > 0)
1350 if (end_of_name_p (dm
))
1351 return "Unexpected end of name in <identifier>.";
1352 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1353 return STATUS_ALLOCATION_FAILED
;
1359 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1360 the short form is emitted; otherwise the full source form
1361 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1362 operands that the operator takes.
1413 ::= cv <type> # cast
1414 ::= vx <source-name> # vendor extended operator */
1417 demangle_operator_name (dm
, short_name
, num_args
)
1422 struct operator_code
1424 /* The mangled code for this operator. */
1426 /* The source name of this operator. */
1428 /* The number of arguments this operator takes. */
1432 static const struct operator_code operators
[] =
1443 { "da", " delete[]", 1 },
1445 { "dl", " delete" , 1 },
1453 { "lS", "<<=" , 2 },
1462 { "na", " new[]" , 1 },
1466 { "nw", " new" , 1 },
1472 { "pm", "->*" , 2 },
1478 { "rS", ">>=" , 2 },
1481 { "sz", " sizeof" , 1 }
1484 const int num_operators
=
1485 sizeof (operators
) / sizeof (struct operator_code
);
1487 int c0
= next_char (dm
);
1488 int c1
= next_char (dm
);
1489 const struct operator_code
* p1
= operators
;
1490 const struct operator_code
* p2
= operators
+ num_operators
;
1492 DEMANGLE_TRACE ("operator-name", dm
);
1494 /* Is this a vendor extended operator? */
1495 if (c0
== 'v' && c1
== 'x')
1497 RETURN_IF_ERROR (result_append (dm
, "operator"));
1498 RETURN_IF_ERROR (demangle_source_name (dm
));
1503 /* Is this a conversion operator? */
1504 if (c0
== 'c' && c1
== 'v')
1506 RETURN_IF_ERROR (result_append (dm
, "operator "));
1507 /* Demangle the converted-to type. */
1508 RETURN_IF_ERROR (demangle_type (dm
));
1513 /* Perform a binary search for the operator code. */
1516 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1517 char match0
= p
->code
[0];
1518 char match1
= p
->code
[1];
1520 if (c0
== match0
&& c1
== match1
)
1524 RETURN_IF_ERROR (result_append (dm
, "operator"));
1525 RETURN_IF_ERROR (result_append (dm
, p
->name
));
1526 *num_args
= p
->num_args
;
1532 /* Couldn't find it. */
1533 return "Unknown code in <operator-name>.";
1536 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1543 /* Demangles and emits a <special-name>.
1545 <special-name> ::= GV <object name> # Guard variable
1546 ::= Th[n] <offset number> _ <base name> <base encoding>
1547 # non-virtual base override thunk
1548 ::= Tv[n] <offset number> _ <vcall offset number>
1550 # virtual base override thunk
1551 ::= TV <type> # virtual table
1553 ::= TI <type> # typeinfo structure
1554 ::= TS <type> # typeinfo name
1556 Also demangles the special g++ manglings,
1558 <special-name> ::= CT <type> <offset number> _ <base type>
1559 # construction vtable
1560 ::= TF <type> # typeinfo function (old ABI only)
1561 ::= TJ <type> # java Class structure */
1564 demangle_special_name (dm
)
1567 dyn_string_t number
;
1569 char peek
= peek_char (dm
);
1571 DEMANGLE_TRACE ("special-name", dm
);
1575 /* A guard variable name. Consume the G. */
1577 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1578 RETURN_IF_ERROR (result_append (dm
, "guard variable for "));
1579 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1581 else if (peek
== 'T')
1583 status_t status
= STATUS_OK
;
1585 /* Other C++ implementation miscellania. Consume the T. */
1588 switch (peek_char (dm
))
1591 /* Virtual table. */
1593 RETURN_IF_ERROR (result_append (dm
, "vtable for "));
1594 RETURN_IF_ERROR (demangle_type (dm
));
1598 /* VTT structure. */
1600 RETURN_IF_ERROR (result_append (dm
, "VTT for "));
1601 RETURN_IF_ERROR (demangle_type (dm
));
1605 /* Typeinfo structure. */
1607 RETURN_IF_ERROR (result_append (dm
, "typeinfo for "));
1608 RETURN_IF_ERROR (demangle_type (dm
));
1612 /* Typeinfo function. Used only in old ABI with new mangling. */
1614 RETURN_IF_ERROR (result_append (dm
, "typeinfo fn for "));
1615 RETURN_IF_ERROR (demangle_type (dm
));
1619 /* Character string containing type name, used in typeinfo. */
1621 RETURN_IF_ERROR (result_append (dm
, "typeinfo name for "));
1622 RETURN_IF_ERROR (demangle_type (dm
));
1626 /* The java Class variable corresponding to a C++ class. */
1628 RETURN_IF_ERROR (result_append (dm
, "java Class for "));
1629 RETURN_IF_ERROR (demangle_type (dm
));
1633 /* Non-virtual thunk. */
1635 RETURN_IF_ERROR (result_append (dm
, "non-virtual thunk"));
1636 /* Demangle and emit the offset. */
1637 number
= dyn_string_new (4);
1639 return STATUS_ALLOCATION_FAILED
;
1640 demangle_number_literally (dm
, number
, 10, 1);
1641 /* Don't display the offset unless in verbose mode. */
1644 status
= result_append_char (dm
, ' ');
1645 if (STATUS_NO_ERROR (status
))
1646 status
= result_append_string (dm
, number
);
1648 dyn_string_delete (number
);
1649 RETURN_IF_ERROR (status
);
1650 /* Demangle the separator. */
1651 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1652 /* Demangle and emit the target name and function type. */
1653 RETURN_IF_ERROR (result_append (dm
, " to "));
1654 RETURN_IF_ERROR (demangle_encoding (dm
));
1658 /* Virtual thunk. */
1660 RETURN_IF_ERROR (result_append (dm
, "virtual thunk "));
1661 /* Demangle and emit the offset. */
1662 number
= dyn_string_new (4);
1664 return STATUS_ALLOCATION_FAILED
;
1665 demangle_number_literally (dm
, number
, 10, 1);
1666 /* Don't display the offset unless in verbose mode. */
1669 status
= result_append_string (dm
, number
);
1670 if (STATUS_NO_ERROR (status
))
1671 result_append_char (dm
, ' ');
1673 dyn_string_delete (number
);
1674 RETURN_IF_ERROR (status
);
1675 /* Demangle the separator. */
1676 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1677 /* Demangle and emit the vcall offset. */
1678 number
= dyn_string_new (4);
1680 return STATUS_ALLOCATION_FAILED
;
1681 demangle_number_literally (dm
, number
, 10, 1);
1682 /* Don't display the vcall offset unless in verbose mode. */
1685 status
= result_append_string (dm
, number
);
1686 if (STATUS_NO_ERROR (status
))
1687 status
= result_append_char (dm
, ' ');
1689 dyn_string_delete (number
);
1690 RETURN_IF_ERROR (status
);
1691 /* Demangle the separator. */
1692 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1693 /* Demangle and emit the target function. */
1694 RETURN_IF_ERROR (result_append (dm
, "to "));
1695 RETURN_IF_ERROR (demangle_encoding (dm
));
1699 /* TC is a special g++ mangling for a construction vtable. */
1702 dyn_string_t derived_type
;
1705 RETURN_IF_ERROR (result_append (dm
, "construction vtable for "));
1707 /* Demangle the derived type off to the side. */
1708 RETURN_IF_ERROR (result_push (dm
));
1709 RETURN_IF_ERROR (demangle_type (dm
));
1710 derived_type
= (dyn_string_t
) result_pop (dm
);
1712 /* Demangle the offset. */
1713 number
= dyn_string_new (4);
1716 dyn_string_delete (derived_type
);
1717 return STATUS_ALLOCATION_FAILED
;
1719 demangle_number_literally (dm
, number
, 10, 1);
1720 /* Demangle the underscore separator. */
1721 status
= demangle_char (dm
, '_');
1723 /* Demangle the base type. */
1724 if (STATUS_NO_ERROR (status
))
1725 status
= demangle_type (dm
);
1727 /* Emit the derived type. */
1728 if (STATUS_NO_ERROR (status
))
1729 status
= result_append (dm
, "-in-");
1730 if (STATUS_NO_ERROR (status
))
1731 status
= result_append_string (dm
, derived_type
);
1732 dyn_string_delete (derived_type
);
1734 /* Don't display the offset unless in verbose mode. */
1737 status
= result_append_char (dm
, ' ');
1738 if (STATUS_NO_ERROR (status
))
1739 result_append_string (dm
, number
);
1741 dyn_string_delete (number
);
1742 RETURN_IF_ERROR (status
);
1745 /* If flag_strict, fall through. */
1748 return "Unrecognized <special-name>.";
1752 return STATUS_ERROR
;
1757 /* Demangles and emits a <ctor-dtor-name>.
1760 ::= C1 # complete object (in-charge) ctor
1761 ::= C2 # base object (not-in-charge) ctor
1762 ::= C3 # complete object (in-charge) allocating ctor
1763 ::= D0 # deleting (in-charge) dtor
1764 ::= D1 # complete object (in-charge) dtor
1765 ::= D2 # base object (not-in-charge) dtor */
1768 demangle_ctor_dtor_name (dm
)
1771 static const char *const ctor_flavors
[] =
1777 static const char *const dtor_flavors
[] =
1779 "in-charge deleting",
1785 char peek
= peek_char (dm
);
1787 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
1791 /* A constructor name. Consume the C. */
1793 if (peek_char (dm
) < '1' || peek_char (dm
) > '3')
1794 return "Unrecognized constructor.";
1795 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1796 /* Print the flavor of the constructor if in verbose mode. */
1797 flavor
= next_char (dm
) - '1';
1800 RETURN_IF_ERROR (result_append (dm
, "["));
1801 RETURN_IF_ERROR (result_append (dm
, ctor_flavors
[flavor
]));
1802 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1805 else if (peek
== 'D')
1807 /* A destructor name. Consume the D. */
1809 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
1810 return "Unrecognized destructor.";
1811 RETURN_IF_ERROR (result_append_char (dm
, '~'));
1812 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1813 /* Print the flavor of the destructor if in verbose mode. */
1814 flavor
= next_char (dm
) - '0';
1817 RETURN_IF_ERROR (result_append (dm
, " ["));
1818 RETURN_IF_ERROR (result_append (dm
, dtor_flavors
[flavor
]));
1819 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1823 return STATUS_ERROR
;
1828 /* Handle pointer, reference, and pointer-to-member cases for
1829 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1830 build a pointer/reference type. We snarf all these, plus the
1831 following <type>, all at once since we need to know whether we have
1832 a pointer to data or pointer to function to construct the right
1833 output syntax. C++'s pointer syntax is hairy.
1837 ::= <pointer-to-member-type>
1839 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1842 demangle_type_ptr (dm
)
1848 /* Collect pointer symbols into this string. */
1849 dyn_string_t symbols
= dyn_string_new (10);
1851 DEMANGLE_TRACE ("type*", dm
);
1853 if (symbols
== NULL
)
1854 return STATUS_ALLOCATION_FAILED
;
1856 /* Scan forward, collecting pointers and references into symbols,
1857 until we hit something else. Then emit the type. */
1860 next
= peek_char (dm
);
1863 if (!dyn_string_append_char (symbols
, '*'))
1864 return STATUS_ALLOCATION_FAILED
;
1867 else if (next
== 'R')
1869 if (!dyn_string_append_char (symbols
, '&'))
1870 return STATUS_ALLOCATION_FAILED
;
1873 else if (next
== 'M')
1875 /* Pointer-to-member. */
1876 dyn_string_t class_type
;
1881 /* Capture the type of which this is a pointer-to-member. */
1882 RETURN_IF_ERROR (result_push (dm
));
1883 RETURN_IF_ERROR (demangle_type (dm
));
1884 class_type
= (dyn_string_t
) result_pop (dm
);
1886 /* Build the pointer-to-member notation. It comes before
1887 other pointer and reference qualifiers -- */
1888 if (!dyn_string_prepend_cstr (symbols
, "::*"))
1889 return STATUS_ALLOCATION_FAILED
;
1890 if (!dyn_string_prepend (symbols
, class_type
))
1891 return STATUS_ALLOCATION_FAILED
;
1892 dyn_string_delete (class_type
);
1894 if (peek_char (dm
) == 'F')
1897 /* Demangle the type of the pointed-to member. */
1898 status
= demangle_type (dm
);
1899 /* Make it pretty. */
1900 if (STATUS_NO_ERROR (status
))
1901 status
= result_append_space (dm
);
1902 /* Add the pointer-to-member syntax, and other pointer and
1903 reference symbols. */
1904 if (STATUS_NO_ERROR (status
))
1905 status
= result_append_string (dm
, symbols
);
1907 dyn_string_delete (symbols
);
1909 RETURN_IF_ERROR (status
);
1912 else if (next
== 'F')
1914 /* Ooh, tricky, a pointer-to-function. */
1915 int position
= result_length (dm
);
1916 status
= result_append_char (dm
, '(');
1917 if (STATUS_NO_ERROR (status
))
1918 status
= result_append_string (dm
, symbols
);
1919 if (STATUS_NO_ERROR (status
))
1920 status
= result_append_char (dm
, ')');
1921 dyn_string_delete (symbols
);
1922 RETURN_IF_ERROR (status
);
1924 RETURN_IF_ERROR (demangle_function_type (dm
, position
));
1929 /* No more pointer or reference tokens. Finish up. */
1930 status
= demangle_type (dm
);
1932 if (STATUS_NO_ERROR (status
))
1933 status
= result_append_string (dm
, symbols
);
1934 dyn_string_delete (symbols
);
1936 RETURN_IF_ERROR (status
);
1942 /* Demangles and emits a <type>.
1944 <type> ::= <builtin-type>
1946 ::= <class-enum-type>
1948 ::= <pointer-to-member-type>
1949 ::= <template-param>
1950 ::= <template-template-param> <template-args>
1951 ::= <CV-qualifiers> <type>
1952 ::= P <type> # pointer-to
1953 ::= R <type> # reference-to
1954 ::= C <type> # complex pair (C 2000)
1955 ::= G <type> # imaginary (C 2000)
1956 ::= U <source-name> <type> # vendor extended type qualifier
1957 ::= <substitution> */
1963 int start
= substitution_start (dm
);
1964 char peek
= peek_char (dm
);
1967 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1968 int template_parm
= NOT_TEMPLATE_PARM
;
1970 /* A <type> can be a <substitution>; therefore, this <type> is a
1971 substitution candidate unless a special condition holds (see
1973 int is_substitution_candidate
= 1;
1975 DEMANGLE_TRACE ("type", dm
);
1977 /* A <class-enum-type> can start with a digit (a <source-name>), an
1978 N (a <nested-name>), or a Z (a <local-name>). */
1979 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
1980 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &template_p
));
1981 /* Lower-case letters begin <builtin-type>s, except for `r', which
1982 denotes restrict. */
1983 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
1985 RETURN_IF_ERROR (demangle_builtin_type (dm
));
1986 /* Built-in types are not substitution candidates. */
1987 is_substitution_candidate
= 0;
1995 /* CV-qualifiers (including restrict). We have to demangle
1996 them off to the side, since C++ syntax puts them in a funny
1997 place for qualified pointer and reference types. */
2000 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2002 if (cv_qualifiers
== NULL
)
2003 return STATUS_ALLOCATION_FAILED
;
2005 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2007 /* If the qualifiers apply to a pointer or reference, they
2008 need to come after the whole qualified type. */
2009 if (peek_char (dm
) == 'P' || peek_char (dm
) == 'R')
2011 status
= demangle_type (dm
);
2012 if (STATUS_NO_ERROR (status
))
2013 status
= result_append_space (dm
);
2014 if (STATUS_NO_ERROR (status
))
2015 status
= result_append_string (dm
, cv_qualifiers
);
2017 /* Otherwise, the qualifiers come first. */
2020 status
= result_append_string (dm
, cv_qualifiers
);
2021 if (STATUS_NO_ERROR (status
))
2022 status
= result_append_space (dm
);
2023 if (STATUS_NO_ERROR (status
))
2024 status
= demangle_type (dm
);
2027 dyn_string_delete (cv_qualifiers
);
2028 RETURN_IF_ERROR (status
);
2033 return "Non-pointer or -reference function type.";
2036 RETURN_IF_ERROR (demangle_array_type (dm
));
2040 /* It's either a <template-param> or a
2041 <template-template-param>. In either case, demangle the
2043 RETURN_IF_ERROR (demangle_template_param (dm
, &template_parm
));
2045 /* Check for a template argument list; if one is found, it's a
2046 <template-template-param> ::= <template-param>
2047 ::= <substitution> */
2048 if (peek_char (dm
) == 'I')
2050 /* Add a substitution candidate. The template parameter
2051 `T' token is a substitution candidate by itself,
2052 without the template argument list. */
2053 RETURN_IF_ERROR (substitution_add (dm
, start
, template_p
,
2056 /* Now demangle the template argument list. */
2057 RETURN_IF_ERROR (demangle_template_args (dm
));
2058 /* The entire type, including the template template
2059 parameter and its argument list, will be added as a
2060 substitution candidate below. */
2066 /* First check if this is a special substitution. If it is,
2067 this is a <class-enum-type>. Special substitutions have a
2068 letter following the `S'; other substitutions have a digit
2070 peek_next
= peek_char_next (dm
);
2071 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2073 RETURN_IF_ERROR (demangle_substitution (dm
, &template_p
));
2075 /* The substituted name may have been a template name.
2076 Check if template arguments follow, and if so, demangle
2078 if (peek_char (dm
) == 'I')
2079 RETURN_IF_ERROR (demangle_template_args (dm
));
2081 /* A substitution token is not itself a substitution
2083 is_substitution_candidate
= 0;
2086 /* While the special substitution token itself is not a
2087 substitution candidate, the <class-enum-type> is, so
2088 don't clear is_substitution_candidate. */
2089 demangle_class_enum_type (dm
, &template_p
);
2096 RETURN_IF_ERROR (demangle_type_ptr (dm
));
2100 /* A C99 complex type. */
2101 RETURN_IF_ERROR (result_append (dm
, "complex "));
2103 RETURN_IF_ERROR (demangle_type (dm
));
2107 /* A C99 imaginary type. */
2108 RETURN_IF_ERROR (result_append (dm
, "imaginary "));
2110 RETURN_IF_ERROR (demangle_type (dm
));
2114 /* Vendor extended type qualifier. */
2116 RETURN_IF_ERROR (demangle_source_name (dm
));
2117 RETURN_IF_ERROR (result_append_char (dm
, ' '));
2118 RETURN_IF_ERROR (demangle_type (dm
));
2122 return "Unexpected character in <type>.";
2125 if (is_substitution_candidate
)
2126 /* Add a new substitution for the type. If this type was a
2127 <template-param>, pass its index since from the point of
2128 substitutions; a <template-param> token is a substitution
2129 candidate distinct from the type that is substituted for it. */
2130 RETURN_IF_ERROR (substitution_add (dm
, start
, template_p
, template_parm
));
2132 /* Pop off template argument lists added during mangling of this
2134 pop_to_template_arg_list (dm
, old_arg_list
);
2139 /* C++ source names of builtin types, indexed by the mangled code
2140 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2141 static const char *const builtin_type_names
[26] =
2143 "signed char", /* a */
2147 "long double", /* e */
2149 "__float128", /* g */
2150 "unsigned char", /* h */
2155 "unsigned long", /* m */
2157 "unsigned __int128", /* o */
2162 "unsigned short", /* t */
2166 "long long", /* x */
2167 "unsigned long long", /* y */
2171 /* Demangles and emits a <builtin-type>.
2173 <builtin-type> ::= v # void
2178 ::= h # unsigned char
2180 ::= t # unsigned short
2182 ::= j # unsigned int
2184 ::= m # unsigned long
2185 ::= x # long long, __int64
2186 ::= y # unsigned long long, __int64
2188 ::= o # unsigned __int128
2191 ::= e # long double, __float80
2194 ::= u <source-name> # vendor extended type */
2197 demangle_builtin_type (dm
)
2201 char code
= peek_char (dm
);
2203 DEMANGLE_TRACE ("builtin-type", dm
);
2208 RETURN_IF_ERROR (demangle_source_name (dm
));
2211 else if (code
>= 'a' && code
<= 'z')
2213 const char *type_name
= builtin_type_names
[code
- 'a'];
2214 if (type_name
== NULL
)
2215 return "Unrecognized <builtin-type> code.";
2217 RETURN_IF_ERROR (result_append (dm
, type_name
));
2222 return "Non-alphabetic <builtin-type> code.";
2225 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2226 restrict) at the current position. The qualifiers are appended to
2227 QUALIFIERS. Returns STATUS_OK. */
2230 demangle_CV_qualifiers (dm
, qualifiers
)
2232 dyn_string_t qualifiers
;
2234 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2238 switch (peek_char (dm
))
2241 if (!dyn_string_append_space (qualifiers
))
2242 return STATUS_ALLOCATION_FAILED
;
2243 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2244 return STATUS_ALLOCATION_FAILED
;
2248 if (!dyn_string_append_space (qualifiers
))
2249 return STATUS_ALLOCATION_FAILED
;
2250 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2251 return STATUS_ALLOCATION_FAILED
;
2255 if (!dyn_string_append_space (qualifiers
))
2256 return STATUS_ALLOCATION_FAILED
;
2257 if (!dyn_string_append_cstr (qualifiers
, "const"))
2258 return STATUS_ALLOCATION_FAILED
;
2269 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2270 position in the result string of the start of the function
2271 identifier, at which the function's return type will be inserted.
2273 <function-type> ::= F [Y] <bare-function-type> E */
2276 demangle_function_type (dm
, function_name_pos
)
2278 int function_name_pos
;
2280 DEMANGLE_TRACE ("function-type", dm
);
2281 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2282 if (peek_char (dm
) == 'Y')
2284 /* Indicate this function has C linkage if in verbose mode. */
2286 RETURN_IF_ERROR (result_append (dm
, " [extern \"C\"] "));
2289 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2290 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2294 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2295 position in the result string at which the function return type
2296 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2297 function's return type is assumed not to be encoded.
2299 <bare-function-type> ::= <signature type>+ */
2302 demangle_bare_function_type (dm
, return_type_pos
)
2304 int return_type_pos
;
2306 /* Sequence is the index of the current function parameter, counting
2307 from zero. The value -1 denotes the return type. */
2309 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2311 DEMANGLE_TRACE ("bare-function-type", dm
);
2313 RETURN_IF_ERROR (result_append_char (dm
, '('));
2314 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2317 /* We're decoding the function's return type. */
2319 dyn_string_t return_type
;
2320 status_t status
= STATUS_OK
;
2322 /* Decode the return type off to the side. */
2323 RETURN_IF_ERROR (result_push (dm
));
2324 RETURN_IF_ERROR (demangle_type (dm
));
2325 return_type
= (dyn_string_t
) result_pop (dm
);
2327 /* Add a space to the end of the type. Insert the return
2328 type where we've been asked to. */
2329 if (!dyn_string_append_space (return_type
)
2330 || !dyn_string_insert (result_string (dm
), return_type_pos
,
2332 status
= STATUS_ALLOCATION_FAILED
;
2334 dyn_string_delete (return_type
);
2335 RETURN_IF_ERROR (status
);
2339 /* Skip `void' parameter types. One should only occur as
2340 the only type in a parameter list; in that case, we want
2341 to print `foo ()' instead of `foo (void)'. */
2342 if (peek_char (dm
) == 'v')
2344 /* Consume the v. */
2348 /* Separate parameter types by commas. */
2350 RETURN_IF_ERROR (result_append (dm
, ", "));
2351 /* Demangle the type. */
2352 RETURN_IF_ERROR (demangle_type (dm
));
2357 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2362 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2363 non-zero if the type is a template-id, zero otherwise.
2365 <class-enum-type> ::= <name> */
2368 demangle_class_enum_type (dm
, template_p
)
2372 DEMANGLE_TRACE ("class-enum-type", dm
);
2374 RETURN_IF_ERROR (demangle_name (dm
, template_p
));
2378 /* Demangles and emits an <array-type>.
2380 <array-type> ::= A [<dimension number>] _ <element type>
2381 ::= A <dimension expression> _ <element type> */
2384 demangle_array_type (dm
)
2387 status_t status
= STATUS_OK
;
2388 dyn_string_t array_size
= NULL
;
2391 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2393 /* Demangle the array size into array_size. */
2394 peek
= peek_char (dm
);
2396 /* Array bound is omitted. This is a C99-style VLA. */
2398 else if (IS_DIGIT (peek_char (dm
)))
2400 /* It looks like a constant array bound. */
2401 array_size
= dyn_string_new (10);
2402 if (array_size
== NULL
)
2403 return STATUS_ALLOCATION_FAILED
;
2404 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2408 /* Anything is must be an expression for a nont-constant array
2409 bound. This happens if the array type occurs in a template
2410 and the array bound references a template parameter. */
2411 RETURN_IF_ERROR (result_push (dm
));
2412 RETURN_IF_ERROR (demangle_expression (dm
));
2413 array_size
= (dyn_string_t
) result_pop (dm
);
2415 /* array_size may have been allocated by now, so we can't use
2416 RETURN_IF_ERROR until it's been deallocated. */
2418 /* Demangle the base type of the array. */
2419 if (STATUS_NO_ERROR (status
))
2420 status
= demangle_char (dm
, '_');
2421 if (STATUS_NO_ERROR (status
))
2422 status
= demangle_type (dm
);
2424 /* Emit the array dimension syntax. */
2425 if (STATUS_NO_ERROR (status
))
2426 status
= result_append_char (dm
, '[');
2427 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2428 status
= result_append_string (dm
, array_size
);
2429 if (STATUS_NO_ERROR (status
))
2430 status
= result_append_char (dm
, ']');
2431 if (array_size
!= NULL
)
2432 dyn_string_delete (array_size
);
2434 RETURN_IF_ERROR (status
);
2439 /* Demangles and emits a <template-param>. The zero-indexed position
2440 in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
2442 <template-param> ::= T_ # first template parameter
2443 ::= T <parameter-2 number> _ */
2446 demangle_template_param (dm
, template_parm_number
)
2448 int *template_parm_number
;
2451 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2454 DEMANGLE_TRACE ("template-param", dm
);
2456 /* Make sure there is a template argmust list in which to look up
2457 this parameter reference. */
2458 if (current_arg_list
== NULL
)
2459 return "Template parameter outside of template.";
2461 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2462 if (peek_char (dm
) == '_')
2466 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2469 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2471 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2473 /* parm_number exceeded the number of arguments in the current
2474 template argument list. */
2475 return "Template parameter number out of bounds.";
2476 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2478 *template_parm_number
= parm_number
;
2482 /* Demangles and emits a <template-args>.
2484 <template-args> ::= I <template-arg>+ E */
2487 demangle_template_args (dm
)
2491 dyn_string_t old_last_source_name
;
2492 template_arg_list_t arg_list
= template_arg_list_new ();
2494 if (arg_list
== NULL
)
2495 return STATUS_ALLOCATION_FAILED
;
2497 /* Preserve the most recently demangled source name. */
2498 old_last_source_name
= dm
->last_source_name
;
2499 dm
->last_source_name
= dyn_string_new (0);
2501 DEMANGLE_TRACE ("template-args", dm
);
2503 if (dm
->last_source_name
== NULL
)
2504 return STATUS_ALLOCATION_FAILED
;
2506 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2507 RETURN_IF_ERROR (result_open_template_list (dm
));
2515 RETURN_IF_ERROR (result_append (dm
, ", "));
2517 /* Capture the template arg. */
2518 RETURN_IF_ERROR (result_push (dm
));
2519 RETURN_IF_ERROR (demangle_template_arg (dm
));
2520 arg
= result_pop (dm
);
2522 /* Emit it in the demangled name. */
2523 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2525 /* Save it for use in expanding <template-param>s. */
2526 template_arg_list_add_arg (arg_list
, arg
);
2528 while (peek_char (dm
) != 'E');
2529 /* Append the '>'. */
2530 RETURN_IF_ERROR (result_close_template_list (dm
));
2532 /* Consume the 'E'. */
2535 /* Restore the most recent demangled source name. */
2536 dyn_string_delete (dm
->last_source_name
);
2537 dm
->last_source_name
= old_last_source_name
;
2539 /* Push the list onto the top of the stack of template argument
2540 lists, so that arguments from it are used from now on when
2541 expanding <template-param>s. */
2542 push_template_arg_list (dm
, arg_list
);
2547 /* This function, which does not correspond to a production in the
2548 mangling spec, handles the `literal' production for both
2549 <template-arg> and <expr-primary>. It does not expect or consume
2550 the initial `L' or final `E'. The demangling is given by:
2552 <literal> ::= <type> </value/ number>
2554 and the emitted output is `(type)number'. */
2557 demangle_literal (dm
)
2560 char peek
= peek_char (dm
);
2561 dyn_string_t value_string
;
2564 DEMANGLE_TRACE ("literal", dm
);
2566 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2568 /* If not in verbose mode and this is a builtin type, see if we
2569 can produce simpler numerical output. In particular, for
2570 integer types shorter than `long', just write the number
2571 without type information; for bools, write `true' or `false'.
2572 Other refinements could be made here too. */
2574 /* This constant string is used to map from <builtin-type> codes
2575 (26 letters of the alphabet) to codes that determine how the
2576 value will be displayed. The codes are:
2580 A space means the value will be represented using cast
2582 static const char *const code_map
= "ibi iii ll ii i ";
2584 char code
= code_map
[peek
- 'a'];
2585 /* FIXME: Implement demangling of floats and doubles. */
2587 return STATUS_UNIMPLEMENTED
;
2590 /* It's a boolean. */
2593 /* Consume the b. */
2595 /* Look at the next character. It should be 0 or 1,
2596 corresponding to false or true, respectively. */
2597 value
= peek_char (dm
);
2599 RETURN_IF_ERROR (result_append (dm
, "false"));
2600 else if (value
== '1')
2601 RETURN_IF_ERROR (result_append (dm
, "true"));
2603 return "Unrecognized bool constant.";
2604 /* Consume the 0 or 1. */
2608 else if (code
== 'i' || code
== 'l')
2610 /* It's an integer or long. */
2612 /* Consume the type character. */
2615 /* Demangle the number and write it out. */
2616 value_string
= dyn_string_new (0);
2617 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2618 if (STATUS_NO_ERROR (status
))
2619 status
= result_append_string (dm
, value_string
);
2620 /* For long integers, append an l. */
2621 if (code
== 'l' && STATUS_NO_ERROR (status
))
2622 status
= result_append_char (dm
, code
);
2623 dyn_string_delete (value_string
);
2625 RETURN_IF_ERROR (status
);
2628 /* ...else code == ' ', so fall through to represent this
2629 literal's type explicitly using cast syntax. */
2632 RETURN_IF_ERROR (result_append_char (dm
, '('));
2633 RETURN_IF_ERROR (demangle_type (dm
));
2634 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2636 value_string
= dyn_string_new (0);
2637 if (value_string
== NULL
)
2638 return STATUS_ALLOCATION_FAILED
;
2640 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2641 if (STATUS_NO_ERROR (status
))
2642 status
= result_append_string (dm
, value_string
);
2643 dyn_string_delete (value_string
);
2644 RETURN_IF_ERROR (status
);
2649 /* Demangles and emits a <template-arg>.
2651 <template-arg> ::= <type> # type
2652 ::= L <type> <value number> E # literal
2653 ::= LZ <encoding> E # external name
2654 ::= X <expression> E # expression */
2657 demangle_template_arg (dm
)
2660 DEMANGLE_TRACE ("template-arg", dm
);
2662 switch (peek_char (dm
))
2667 if (peek_char (dm
) == 'Z')
2669 /* External name. */
2671 /* FIXME: Standard is contradictory here. */
2672 RETURN_IF_ERROR (demangle_encoding (dm
));
2675 RETURN_IF_ERROR (demangle_literal (dm
));
2676 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2682 RETURN_IF_ERROR (demangle_expression (dm
));
2686 RETURN_IF_ERROR (demangle_type (dm
));
2693 /* Demangles and emits an <expression>.
2695 <expression> ::= <unary operator-name> <expression>
2696 ::= <binary operator-name> <expression> <expression>
2698 ::= <scope-expression> */
2701 demangle_expression (dm
)
2704 char peek
= peek_char (dm
);
2706 DEMANGLE_TRACE ("expression", dm
);
2708 if (peek
== 'L' || peek
== 'T')
2709 RETURN_IF_ERROR (demangle_expr_primary (dm
));
2710 else if (peek
== 's' && peek_char_next (dm
) == 'r')
2711 RETURN_IF_ERROR (demangle_scope_expression (dm
));
2713 /* An operator expression. */
2716 status_t status
= STATUS_OK
;
2717 dyn_string_t operator_name
;
2719 /* We have an operator name. Since we want to output binary
2720 operations in infix notation, capture the operator name
2722 RETURN_IF_ERROR (result_push (dm
));
2723 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
2724 operator_name
= (dyn_string_t
) result_pop (dm
);
2726 /* If it's binary, do an operand first. */
2729 status
= result_append_char (dm
, '(');
2730 if (STATUS_NO_ERROR (status
))
2731 status
= demangle_expression (dm
);
2732 if (STATUS_NO_ERROR (status
))
2733 status
= result_append_char (dm
, ')');
2736 /* Emit the operator. */
2737 if (STATUS_NO_ERROR (status
))
2738 status
= result_append_string (dm
, operator_name
);
2739 dyn_string_delete (operator_name
);
2740 RETURN_IF_ERROR (status
);
2742 /* Emit its second (if binary) or only (if unary) operand. */
2743 RETURN_IF_ERROR (result_append_char (dm
, '('));
2744 RETURN_IF_ERROR (demangle_expression (dm
));
2745 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2747 /* The ternary operator takes a third operand. */
2750 RETURN_IF_ERROR (result_append (dm
, ":("));
2751 RETURN_IF_ERROR (demangle_expression (dm
));
2752 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2759 /* Demangles and emits a <scope-expression>.
2761 <scope-expression> ::= sr <qualifying type> <source-name>
2762 ::= sr <qualifying type> <encoding> */
2765 demangle_scope_expression (dm
)
2768 RETURN_IF_ERROR (demangle_char (dm
, 's'));
2769 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
2770 RETURN_IF_ERROR (demangle_type (dm
));
2771 RETURN_IF_ERROR (result_append (dm
, "::"));
2772 RETURN_IF_ERROR (demangle_encoding (dm
));
2776 /* Demangles and emits an <expr-primary>.
2778 <expr-primary> ::= <template-param>
2779 ::= L <type> <value number> E # literal
2780 ::= L <mangled-name> E # external name */
2783 demangle_expr_primary (dm
)
2786 char peek
= peek_char (dm
);
2789 DEMANGLE_TRACE ("expr-primary", dm
);
2792 RETURN_IF_ERROR (demangle_template_param (dm
, &unused
));
2793 else if (peek
== 'L')
2795 /* Consume the `L'. */
2797 peek
= peek_char (dm
);
2800 RETURN_IF_ERROR (demangle_mangled_name (dm
));
2802 RETURN_IF_ERROR (demangle_literal (dm
));
2804 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2807 return STATUS_ERROR
;
2812 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2813 if the substitution is the name of a template, zero otherwise.
2815 <substitution> ::= S <seq-id> _
2819 ::= Sa # ::std::allocator
2820 ::= Sb # ::std::basic_string
2821 ::= Ss # ::std::basic_string<char,
2822 ::std::char_traits<char>,
2823 ::std::allocator<char> >
2824 ::= Si # ::std::basic_istream<char,
2825 std::char_traits<char> >
2826 ::= So # ::std::basic_ostream<char,
2827 std::char_traits<char> >
2828 ::= Sd # ::std::basic_iostream<char,
2829 std::char_traits<char> >
2833 demangle_substitution (dm
, template_p
)
2841 DEMANGLE_TRACE ("substitution", dm
);
2843 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
2845 /* Scan the substitution sequence index. A missing number denotes
2847 peek
= peek_char (dm
);
2850 /* If the following character is 0-9 or a capital letter, interpret
2851 the sequence up to the next underscore as a base-36 substitution
2853 else if (IS_DIGIT ((unsigned char) peek
)
2854 || (peek
>= 'A' && peek
<= 'Z'))
2855 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
2858 const char *new_last_source_name
= NULL
;
2863 RETURN_IF_ERROR (result_append (dm
, "std"));
2867 RETURN_IF_ERROR (result_append (dm
, "std::allocator"));
2868 new_last_source_name
= "allocator";
2873 RETURN_IF_ERROR (result_append (dm
, "std::basic_string"));
2874 new_last_source_name
= "basic_string";
2881 RETURN_IF_ERROR (result_append (dm
, "std::string"));
2882 new_last_source_name
= "string";
2886 RETURN_IF_ERROR (result_append (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
2887 new_last_source_name
= "basic_string";
2895 RETURN_IF_ERROR (result_append (dm
, "std::istream"));
2896 new_last_source_name
= "istream";
2900 RETURN_IF_ERROR (result_append (dm
, "std::basic_istream<char, std::char_traints<char> >"));
2901 new_last_source_name
= "basic_istream";
2909 RETURN_IF_ERROR (result_append (dm
, "std::ostream"));
2910 new_last_source_name
= "ostream";
2914 RETURN_IF_ERROR (result_append (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
2915 new_last_source_name
= "basic_ostream";
2923 RETURN_IF_ERROR (result_append (dm
, "std::iostream"));
2924 new_last_source_name
= "iostream";
2928 RETURN_IF_ERROR (result_append (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
2929 new_last_source_name
= "basic_iostream";
2935 return "Unrecognized <substitution>.";
2938 /* Consume the character we just processed. */
2941 if (new_last_source_name
!= NULL
)
2943 if (!dyn_string_copy_cstr (dm
->last_source_name
,
2944 new_last_source_name
))
2945 return STATUS_ALLOCATION_FAILED
;
2951 /* Look up the substitution text. Since `S_' is the most recent
2952 substitution, `S0_' is the second-most-recent, etc., shift the
2953 numbering by one. */
2954 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
2956 return "Substitution number out of range.";
2958 /* Emit the substitution text. */
2959 RETURN_IF_ERROR (result_append_string (dm
, text
));
2961 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2965 /* Demangles and emits a <local-name>.
2967 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2968 := Z <function encoding> E s [<discriminator>] */
2971 demangle_local_name (dm
)
2974 DEMANGLE_TRACE ("local-name", dm
);
2976 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
2977 RETURN_IF_ERROR (demangle_encoding (dm
));
2978 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2979 RETURN_IF_ERROR (result_append (dm
, "::"));
2981 if (peek_char (dm
) == 's')
2983 /* Local character string literal. */
2984 RETURN_IF_ERROR (result_append (dm
, "string literal"));
2985 /* Consume the s. */
2987 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
2992 /* Local name for some other entity. Demangle its name. */
2993 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
2994 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3000 /* Optimonally demangles and emits a <discriminator>. If there is no
3001 <discriminator> at the current position in the mangled string, the
3002 descriminator is assumed to be zero. Emit the discriminator number
3003 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3004 discriminator is zero.
3006 <discriminator> ::= _ <number> */
3009 demangle_discriminator (dm
, suppress_first
)
3013 /* Output for <discriminator>s to the demangled name is completely
3014 supressed if not in verbose mode. */
3016 if (peek_char (dm
) == '_')
3018 /* Consume the underscore. */
3021 RETURN_IF_ERROR (result_append (dm
, " [#"));
3022 /* Check if there's a number following the underscore. */
3023 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3026 /* Demangle the number. */
3027 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3029 /* Write the discriminator. The mangled number is two
3030 less than the discriminator ordinal, counting from
3032 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 2,
3033 (dyn_string_t
) dm
->result
));
3038 /* A missing digit correspond to one. */
3039 RETURN_IF_ERROR (result_append_char (dm
, '1'));
3042 RETURN_IF_ERROR (result_append_char (dm
, ']'));
3044 else if (!suppress_first
)
3047 RETURN_IF_ERROR (result_append (dm
, " [#0]"));
3053 /* Demangle NAME into RESULT, which must be an initialized
3054 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3055 an error message, and the contents of RESULT are unchanged. */
3058 cp_demangle (name
, result
)
3060 dyn_string_t result
;
3063 int length
= strlen (name
);
3065 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3067 demangling_t dm
= demangling_new (name
);
3069 return STATUS_ALLOCATION_FAILED
;
3071 status
= result_push (dm
);
3072 if (status
!= STATUS_OK
)
3074 demangling_delete (dm
);
3078 status
= demangle_mangled_name (dm
);
3079 if (STATUS_NO_ERROR (status
))
3081 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3082 if (!dyn_string_copy (result
, demangled
))
3083 return STATUS_ALLOCATION_FAILED
;
3084 dyn_string_delete (demangled
);
3087 demangling_delete (dm
);
3091 /* It's evidently not a mangled C++ name. It could be the name
3092 of something with C linkage, though, so just copy NAME into
3094 if (!dyn_string_copy_cstr (result
, name
))
3095 return STATUS_ALLOCATION_FAILED
;
3102 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3103 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3104 an error message, and the contents of RESULT are unchanged. */
3108 cp_demangle_type (type_name
, result
)
3109 const char* type_name
;
3110 dyn_string_t result
;
3113 demangling_t dm
= demangling_new (type_name
);
3116 return STATUS_ALLOCATION_FAILED
;
3118 /* Demangle the type name. The demangled name is stored in dm. */
3119 status
= result_push (dm
);
3120 if (status
!= STATUS_OK
)
3122 demangling_delete (dm
);
3126 status
= demangle_type (dm
);
3128 if (STATUS_NO_ERROR (status
))
3130 /* The demangling succeeded. Pop the result out of dm and copy
3132 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3133 if (!dyn_string_copy (result
, demangled
))
3134 return STATUS_ALLOCATION_FAILED
;
3135 dyn_string_delete (demangled
);
3139 demangling_delete (dm
);
3144 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3146 /* ABI-mandated entry point in the C++ runtime library for performing
3147 demangling. MANGLED_NAME is a NUL-terminated character string
3148 containing the name to be demangled.
3150 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3151 *LENGTH bytes, into which the demangled name is stored. If
3152 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3153 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3154 is placed in a region of memory allocated with malloc.
3156 If LENGTH is non-NULL, the length of the buffer conaining the
3157 demangled name, is placed in *LENGTH.
3159 The return value is a pointer to the start of the NUL-terminated
3160 demangled name, or NULL if the demangling fails. The caller is
3161 responsible for deallocating this memory using free.
3163 *STATUS is set to one of the following values:
3164 0: The demangling operation succeeded.
3165 -1: A memory allocation failiure occurred.
3166 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3167 -3: One of the arguments is invalid.
3169 The demagling is performed using the C++ ABI mangling rules, with
3173 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3174 const char *mangled_name
;
3175 char *output_buffer
;
3179 struct dyn_string demangled_name
;
3185 if (mangled_name
== NULL
) {
3190 /* Did the caller provide a buffer for the demangled name? */
3191 if (output_buffer
== NULL
) {
3192 /* No; dyn_string will malloc a buffer for us. */
3193 if (!dyn_string_init (&demangled_name
, 0))
3200 /* Yes. Check that the length was provided. */
3201 if (length
== NULL
) {
3205 /* Install the buffer into a dyn_string. */
3206 demangled_name
.allocated
= *length
;
3207 demangled_name
.length
= 0;
3208 demangled_name
.s
= output_buffer
;
3211 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3212 /* MANGLED_NAME apprears to be a function or variable name.
3213 Demangle it accordingly. */
3214 result
= cp_demangle (mangled_name
, &demangled_name
);
3216 /* Try to demangled MANGLED_NAME as the name of a type. */
3217 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3219 if (result
== STATUS_OK
)
3220 /* The demangling succeeded. */
3222 /* If LENGTH isn't NULL, store the allocated buffer length
3223 there; the buffer may have been realloced by dyn_string
3226 *length
= demangled_name
.allocated
;
3227 /* The operation was a success. */
3229 return dyn_string_buf (&demangled_name
);
3231 else if (result
== STATUS_ALLOCATION_FAILED
)
3232 /* A call to malloc or realloc failed during the demangling
3239 /* The demangling failed for another reason, most probably because
3240 MANGLED_NAME isn't a valid mangled name. */
3242 /* If the buffer containing the demangled name wasn't provided
3243 by the caller, free it. */
3244 if (output_buffer
== NULL
)
3245 free (dyn_string_buf (&demangled_name
));
3251 #else /* !IN_LIBGCC2 */
3253 /* Variant entry point for integration with the existing cplus-dem
3254 demangler. Attempts to demangle MANGLED. If the demangling
3255 succeeds, returns a buffer, allocated with malloc, containing the
3256 demangled name. The caller must deallocate the buffer using free.
3257 If the demangling failes, returns NULL. */
3260 cplus_demangle_new_abi (mangled
)
3261 const char* mangled
;
3263 /* Create a dyn_string to hold the demangled name. */
3264 dyn_string_t demangled
= dyn_string_new (0);
3265 /* Attempt the demangling. */
3266 status_t status
= cp_demangle ((char *) mangled
, demangled
);
3267 if (STATUS_NO_ERROR (status
))
3268 /* Demangling succeeded. */
3270 /* Grab the demangled result from the dyn_string. It was
3271 allocated with malloc, so we can return it directly. */
3272 char *return_value
= dyn_string_release (demangled
);
3273 /* Hand back the demangled name. */
3274 return return_value
;
3276 else if (status
== STATUS_ALLOCATION_FAILED
)
3278 fprintf (stderr
, "Memory allocation failed.\n");
3282 /* Demangling failed. */
3284 dyn_string_delete (demangled
);
3289 #endif /* IN_LIBGCC2 */
3291 #ifdef STANDALONE_DEMANGLER
3295 static void print_usage
3296 PARAMS ((FILE* fp
, int exit_value
));
3298 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3299 #define is_mangled_char(CHAR) \
3300 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) || (CHAR) == '_')
3302 /* The name of this program, as invoked. */
3303 const char* program_name
;
3305 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3308 print_usage (fp
, exit_value
)
3312 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3313 fprintf (fp
, "Options:\n");
3314 fprintf (fp
, " -h,--help Display this message.\n");
3315 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3316 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3317 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3322 /* Option specification for getopt_long. */
3323 static struct option long_options
[] =
3325 { "help", no_argument
, NULL
, 'h' },
3326 { "strict", no_argument
, NULL
, 's' },
3327 { "verbose", no_argument
, NULL
, 'v' },
3328 { NULL
, no_argument
, NULL
, 0 },
3331 /* Main entry for a demangling filter executable. It will demangle
3332 its command line arguments, if any. If none are provided, it will
3333 filter stdin to stdout, replacing any recognized mangled C++ names
3334 with their demangled equivalents. */
3345 /* Use the program name of this program, as invoked. */
3346 program_name
= argv
[0];
3348 /* Parse options. */
3351 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3354 case '?': /* Unrecognized option. */
3355 print_usage (stderr
, 1);
3359 print_usage (stdout
, 0);
3371 while (opt_char
!= -1);
3374 /* No command line arguments were provided. Filter stdin. */
3376 dyn_string_t mangled
= dyn_string_new (3);
3377 dyn_string_t demangled
= dyn_string_new (0);
3380 /* Read all of input. */
3381 while (!feof (stdin
))
3383 char c
= getchar ();
3385 /* The first character of a mangled name is an underscore. */
3390 /* It's not a mangled name. Print the character and go
3397 /* The second character of a mangled name is a capital `Z'. */
3402 /* It's not a mangled name. Print the previous
3403 underscore, the `Z', and go on. */
3409 /* Start keeping track of the candidate mangled name. */
3410 dyn_string_append_char (mangled
, '_');
3411 dyn_string_append_char (mangled
, 'Z');
3413 /* Pile characters into mangled until we hit one that can't
3414 occur in a mangled name. */
3416 while (!feof (stdin
) && is_mangled_char (c
))
3418 dyn_string_append_char (mangled
, c
);
3424 /* Attempt to demangle the name. */
3425 status
= cp_demangle (dyn_string_buf (mangled
), demangled
);
3427 /* If the demangling succeeded, great! Print out the
3428 demangled version. */
3429 if (STATUS_NO_ERROR (status
))
3430 fputs (dyn_string_buf (demangled
), stdout
);
3431 /* Abort on allocation failures. */
3432 else if (status
== STATUS_ALLOCATION_FAILED
)
3434 fprintf (stderr
, "Memory allocation failed.\n");
3437 /* Otherwise, it might not have been a mangled name. Just
3438 print out the original text. */
3440 fputs (dyn_string_buf (mangled
), stdout
);
3442 /* If we haven't hit EOF yet, we've read one character that
3443 can't occur in a mangled name, so print it out. */
3447 /* Clear the candidate mangled name, to start afresh next
3448 time we hit a `_Z'. */
3449 dyn_string_clear (mangled
);
3452 dyn_string_delete (mangled
);
3453 dyn_string_delete (demangled
);
3456 /* Demangle command line arguments. */
3458 dyn_string_t result
= dyn_string_new (0);
3460 /* Loop over command line arguments. */
3461 for (i
= optind
; i
< argc
; ++i
)
3463 /* Attempt to demangle. */
3464 status
= cp_demangle (argv
[i
], result
);
3466 /* If it worked, print the demangled name. */
3467 if (STATUS_NO_ERROR (status
))
3468 printf ("%s\n", dyn_string_buf (result
));
3469 /* Abort on allocaiton failures. */
3470 else if (status
== STATUS_ALLOCATION_FAILED
)
3472 fprintf (stderr
, "Memory allocaiton failed.\n");
3475 /* If not, print the error message to stderr instead. */
3477 fprintf (stderr
, "%s\n", status
);
3479 dyn_string_delete (result
);
3485 #endif /* STANDALONE_DEMANGLER */