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
30 #include <sys/types.h>
43 #include "libiberty.h"
44 #include "dyn-string.h"
47 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
48 and other debugging output, will be generated. */
49 #ifdef CP_DEMANGLE_DEBUG
50 #define DEMANGLE_TRACE(PRODUCTION, DM) \
51 fprintf (stderr, " -> %-24s at position %3d\n", \
52 (PRODUCTION), current_position (DM));
54 #define DEMANGLE_TRACE(PRODUCTION, DM)
57 /* Don't include <ctype.h>, to prevent additional unresolved symbols
58 from being dragged into the C++ runtime library. */
59 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
60 #define IS_ALPHA(CHAR) \
61 (((CHAR) >= 'a' && (CHAR) <= 'z') \
62 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
64 /* If flag_verbose is zero, some simplifications will be made to the
65 output to make it easier to read and supress details that are
66 generally not of interest to the average C++ programmer.
67 Otherwise, the demangled representation will attempt to convey as
68 much information as the mangled form. */
69 static int flag_verbose
;
71 /* If flag_strict is non-zero, demangle strictly according to the
72 specification -- don't demangle special g++ manglings. */
73 static int flag_strict
;
75 /* String_list_t is an extended form of dyn_string_t which provides a link
76 field. A string_list_t may safely be cast to and used as a
79 struct string_list_def
81 struct dyn_string string
;
82 struct string_list_def
*next
;
85 typedef struct string_list_def
*string_list_t
;
87 /* Data structure representing a potential substitution. */
89 struct substitution_def
91 /* The demangled text of the substitution. */
94 /* The template parameter that this represents, indexed from zero.
95 If this is not a template paramter number, the value is
97 int template_parm_number
;
99 /* Whether this substitution represents a template item. */
103 #define NOT_TEMPLATE_PARM (-1)
105 /* Data structure representing a template argument list. */
107 struct template_arg_list_def
109 /* The next (lower) template argument list in the stack of currently
110 active template arguments. */
111 struct template_arg_list_def
*next
;
113 /* The first element in the list of template arguments in
114 left-to-right order. */
115 string_list_t first_argument
;
117 /* The last element in the arguments lists. */
118 string_list_t last_argument
;
121 typedef struct template_arg_list_def
*template_arg_list_t
;
123 /* Data structure to maintain the state of the current demangling. */
125 struct demangling_def
127 /* The full mangled name being mangled. */
130 /* Pointer into name at the current position. */
133 /* Stack for strings containing demangled result generated so far.
134 Text is emitted to the topmost (first) string. */
135 string_list_t result
;
137 /* The number of presently available substitutions. */
138 int num_substitutions
;
140 /* The allocated size of the substitutions array. */
141 int substitutions_allocated
;
143 /* An array of available substitutions. The number of elements in
144 the array is given by num_substitions, and the allocated array
145 size in substitutions_size.
147 The most recent substition is at the end, so
149 - `S_' corresponds to substititutions[num_substitutions - 1]
150 - `S0_' corresponds to substititutions[num_substitutions - 2]
153 struct substitution_def
*substitutions
;
155 /* The stack of template argument lists. */
156 template_arg_list_t template_arg_lists
;
158 /* The most recently demangled source-name. */
159 dyn_string_t last_source_name
;
162 typedef struct demangling_def
*demangling_t
;
164 /* This type is the standard return code from most functions. Values
165 other than STATUS_OK contain descriptive messages. */
166 typedef const char *status_t
;
168 /* Special values that can be used as a status_t. */
169 #define STATUS_OK NULL
170 #define STATUS_ERROR "Error."
171 #define STATUS_UNIMPLEMENTED "Unimplemented."
172 #define STATUS_INTERNAL_ERROR "Internal error."
174 /* This status code indicates a failure in malloc or realloc. */
175 static const char* const status_allocation_failed
= "Allocation failed.";
176 #define STATUS_ALLOCATION_FAILED status_allocation_failed
178 /* Non-zero if STATUS indicates that no error has occurred. */
179 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
181 /* Evaluate EXPR, which must produce a status_t. If the status code
182 indicates an error, return from the current function with that
184 #define RETURN_IF_ERROR(EXPR) \
188 if (!STATUS_NO_ERROR (s)) \
193 static status_t int_to_dyn_string
194 PARAMS ((int, dyn_string_t
));
195 static string_list_t string_list_new
197 static void string_list_delete
198 PARAMS ((string_list_t
));
199 static status_t result_close_template_list
200 PARAMS ((demangling_t
));
201 static status_t result_push
202 PARAMS ((demangling_t
));
203 static string_list_t result_pop
204 PARAMS ((demangling_t
));
205 static int substitution_start
206 PARAMS ((demangling_t
));
207 static status_t substitution_add
208 PARAMS ((demangling_t
, int, int, int));
209 static dyn_string_t substitution_get
210 PARAMS ((demangling_t
, int, int *));
211 #ifdef CP_DEMANGLE_DEBUG
212 static void substitutions_print
213 PARAMS ((demangling_t
, FILE *));
215 static template_arg_list_t template_arg_list_new
217 static void template_arg_list_delete
218 PARAMS ((template_arg_list_t
));
219 static void template_arg_list_add_arg
220 PARAMS ((template_arg_list_t
, string_list_t
));
221 static string_list_t template_arg_list_get_arg
222 PARAMS ((template_arg_list_t
, int));
223 static void push_template_arg_list
224 PARAMS ((demangling_t
, template_arg_list_t
));
225 static void pop_to_template_arg_list
226 PARAMS ((demangling_t
, template_arg_list_t
));
227 #ifdef CP_DEMANGLE_DEBUG
228 static void template_arg_list_print
229 PARAMS ((template_arg_list_t
, FILE *));
231 static template_arg_list_t current_template_arg_list
232 PARAMS ((demangling_t
));
233 static demangling_t demangling_new
234 PARAMS ((const char *));
235 static void demangling_delete
236 PARAMS ((demangling_t
));
238 /* The last character of DS. Warning: DS is evaluated twice. */
239 #define dyn_string_last_char(DS) \
240 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
242 /* Append a space character (` ') to DS if it does not already end
243 with one. Evaluates to 1 on success, or 0 on allocation failure. */
244 #define dyn_string_append_space(DS) \
245 ((dyn_string_length (DS) > 0 \
246 && dyn_string_last_char (DS) != ' ') \
247 ? dyn_string_append_char ((DS), ' ') \
250 /* Returns the index of the current position in the mangled name. */
251 #define current_position(DM) ((DM)->next - (DM)->name)
253 /* Returns the character at the current position of the mangled name. */
254 #define peek_char(DM) (*((DM)->next))
256 /* Returns the character one past the current position of the mangled
258 #define peek_char_next(DM) \
259 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
261 /* Returns the character at the current position, and advances the
262 current position to the next character. */
263 #define next_char(DM) (*((DM)->next)++)
265 /* Returns non-zero if the current position is the end of the mangled
266 name, i.e. one past the last character. */
267 #define end_of_name_p(DM) (peek_char (DM) == '\0')
269 /* Advances the current position by one character. */
270 #define advance_char(DM) (++(DM)->next)
272 /* Returns the string containing the current demangled result. */
273 #define result_string(DM) (&(DM)->result->string)
275 /* Appends a dyn_string_t to the demangled result. */
276 #define result_append_string(DM, STRING) \
277 (dyn_string_append (&(DM)->result->string, (STRING)) \
278 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
280 /* Appends NUL-terminated string CSTR to the demangled result. */
281 #define result_append(DM, CSTR) \
282 (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
283 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
285 /* Appends character CHAR to the demangled result. */
286 #define result_append_char(DM, CHAR) \
287 (dyn_string_append_char (&(DM)->result->string, (CHAR)) \
288 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
290 /* The length of the current demangled result. */
291 #define result_length(DM) \
292 dyn_string_length (&(DM)->result->string)
294 /* Appends a space to the demangled result if the last character is
296 #define result_append_space(DM) \
297 (dyn_string_append_space (&(DM)->result->string) \
298 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
300 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
301 success. On failure, deletes DS and returns an error code. */
304 int_to_dyn_string (value
, ds
)
311 /* Handle zero up front. */
314 if (!dyn_string_append_char (ds
, '0'))
315 return STATUS_ALLOCATION_FAILED
;
319 /* For negative numbers, emit a minus sign. */
322 if (!dyn_string_append_char (ds
, '-'))
323 return STATUS_ALLOCATION_FAILED
;
327 /* Find the power of 10 of the first digit. */
335 /* Write the digits. */
338 int digit
= value
/ mask
;
340 if (!dyn_string_append_char (ds
, '0' + digit
))
341 return STATUS_ALLOCATION_FAILED
;
343 value
-= digit
* mask
;
350 /* Creates a new string list node. The contents of the string are
351 empty, but the initial buffer allocation is LENGTH. The string
352 list node should be deleted with string_list_delete. Returns NULL
353 if allocation fails. */
356 string_list_new (length
)
359 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
362 if (!dyn_string_init ((dyn_string_t
) s
, length
))
367 /* Deletes the entire string list starting at NODE. */
370 string_list_delete (node
)
375 string_list_t next
= node
->next
;
381 /* Appends a greater-than character to the demangled result. If the
382 last character is a greater-than character, a space is inserted
383 first, so that the two greater-than characters don't look like a
384 right shift token. */
387 result_close_template_list (dm
)
390 dyn_string_t s
= &dm
->result
->string
;
392 /* Add a space if the last character is already a closing angle
393 bracket, so that a nested template arg list doesn't look like
394 it's closed with a right-shift operator. */
395 if (dyn_string_last_char (s
) == '>')
397 if (!dyn_string_append_char (s
, ' '))
398 return STATUS_ALLOCATION_FAILED
;
401 /* Add closing angle brackets. */
402 if (!dyn_string_append_char (s
, '>'))
403 return STATUS_ALLOCATION_FAILED
;
408 /* Allocates and pushes a new string onto the demangled results stack
409 for DM. Subsequent demangling with DM will emit to the new string.
410 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
411 allocation failure. */
417 string_list_t new_string
= string_list_new (0);
418 if (new_string
== NULL
)
419 /* Allocation failed. */
420 return STATUS_ALLOCATION_FAILED
;
422 /* Link the new string to the front of the list of result strings. */
423 new_string
->next
= (string_list_t
) dm
->result
;
424 dm
->result
= new_string
;
428 /* Removes and returns the topmost element on the demangled results
429 stack for DM. The caller assumes ownership for the returned
436 string_list_t top
= dm
->result
;
437 dm
->result
= top
->next
;
441 /* Returns the start position of a fragment of the demangled result
442 that will be a substitution candidate. Should be called at the
443 start of productions that can add substitutions. */
446 substitution_start (dm
)
449 return result_length (dm
);
452 /* Adds the suffix of the current demangled result of DM starting at
453 START_POSITION as a potential substitution. If TEMPLATE_P is
454 non-zero, this potential substitution is a template-id.
456 If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution
457 is for that particular <template-param>, and is distinct from other
458 otherwise-identical types and other <template-param>s with
459 different indices. */
462 substitution_add (dm
, start_position
, template_p
, template_parm_number
)
466 int template_parm_number
;
468 dyn_string_t result
= result_string (dm
);
469 dyn_string_t substitution
= dyn_string_new (0);
472 if (substitution
== NULL
)
473 return STATUS_ALLOCATION_FAILED
;
475 /* Extract the substring of the current demangling result that
476 represents the subsitution candidate. */
477 if (!dyn_string_substring (substitution
,
478 result
, start_position
, result_length (dm
)))
480 dyn_string_delete (substitution
);
481 return STATUS_ALLOCATION_FAILED
;
484 /* Check whether SUBSTITUTION already occurs. */
485 for (i
= 0; i
< dm
->num_substitutions
; ++i
)
486 if (dyn_string_eq (dm
->substitutions
[i
].text
, substitution
)
487 && dm
->substitutions
[i
].template_parm_number
== template_parm_number
)
488 /* Found SUBSTITUTION already present. */
490 /* Callers expect this function to take ownership of
491 SUBSTITUTION, so delete it. */
492 dyn_string_delete (substitution
);
496 /* If there's no room for the new entry, grow the array. */
497 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
499 size_t new_array_size
;
500 dm
->substitutions_allocated
*= 2;
502 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
504 dm
->substitutions
= (struct substitution_def
*)
505 realloc (dm
->substitutions
, new_array_size
);
506 if (dm
->substitutions
== NULL
)
507 /* Realloc failed. */
509 dyn_string_delete (substitution
);
510 return STATUS_ALLOCATION_FAILED
;
514 /* Add the substitution to the array. */
515 dm
->substitutions
[i
].text
= substitution
;
516 dm
->substitutions
[i
].template_p
= template_p
;
517 dm
->substitutions
[i
].template_parm_number
= template_parm_number
;
518 ++dm
->num_substitutions
;
520 #ifdef CP_DEMANGLE_DEBUG
521 substitutions_print (dm
, stderr
);
527 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
528 non-zero if the substitution is a template-id, zero otherwise.
529 N is numbered from zero. DM retains ownership of the returned
530 string. If N is negative, or equal to or greater than the current
531 number of substitution candidates, returns NULL. */
534 substitution_get (dm
, n
, template_p
)
539 struct substitution_def
*sub
;
541 /* Make sure N is in the valid range. */
542 if (n
< 0 || n
>= dm
->num_substitutions
)
545 sub
= &(dm
->substitutions
[n
]);
546 *template_p
= sub
->template_p
;
550 #ifdef CP_DEMANGLE_DEBUG
551 /* Debugging routine to print the current substitutions to FP. */
554 substitutions_print (dm
, fp
)
559 int num
= dm
->num_substitutions
;
561 fprintf (fp
, "SUBSTITUTIONS:\n");
562 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
565 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
568 fprintf (fp
, " S_ ");
570 fprintf (fp
, " S%d_", seq_id
);
571 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
575 #endif /* CP_DEMANGLE_DEBUG */
577 /* Creates a new template argument list. Returns NULL if allocation
580 static template_arg_list_t
581 template_arg_list_new ()
583 template_arg_list_t new_list
=
584 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
585 if (new_list
== NULL
)
587 /* Initialize the new list to have no arguments. */
588 new_list
->first_argument
= NULL
;
589 new_list
->last_argument
= NULL
;
590 /* Return the new list. */
594 /* Deletes a template argument list and the template arguments it
598 template_arg_list_delete (list
)
599 template_arg_list_t list
;
601 /* If there are any arguments on LIST, delete them. */
602 if (list
->first_argument
!= NULL
)
603 string_list_delete (list
->first_argument
);
608 /* Adds ARG to the template argument list ARG_LIST. */
611 template_arg_list_add_arg (arg_list
, arg
)
612 template_arg_list_t arg_list
;
615 if (arg_list
->first_argument
== NULL
)
616 /* If there were no arguments before, ARG is the first one. */
617 arg_list
->first_argument
= arg
;
619 /* Make ARG the last argument on the list. */
620 arg_list
->last_argument
->next
= arg
;
621 /* Make ARG the last on the list. */
622 arg_list
->last_argument
= arg
;
626 /* Returns the template arugment at position INDEX in template
627 argument list ARG_LIST. */
630 template_arg_list_get_arg (arg_list
, index
)
631 template_arg_list_t arg_list
;
634 string_list_t arg
= arg_list
->first_argument
;
635 /* Scan down the list of arguments to find the one at position
641 /* Ran out of arguments before INDEX hit zero. That's an
645 /* Return the argument at position INDEX. */
649 /* Pushes ARG_LIST onto the top of the template argument list stack. */
652 push_template_arg_list (dm
, arg_list
)
654 template_arg_list_t arg_list
;
656 arg_list
->next
= dm
->template_arg_lists
;
657 dm
->template_arg_lists
= arg_list
;
658 #ifdef CP_DEMANGLE_DEBUG
659 fprintf (stderr
, " ** pushing template arg list\n");
660 template_arg_list_print (arg_list
, stderr
);
664 /* Pops and deletes elements on the template argument list stack until
665 arg_list is the topmost element. If arg_list is NULL, all elements
666 are popped and deleted. */
669 pop_to_template_arg_list (dm
, arg_list
)
671 template_arg_list_t arg_list
;
673 while (dm
->template_arg_lists
!= arg_list
)
675 template_arg_list_t top
= dm
->template_arg_lists
;
676 /* Disconnect the topmost element from the list. */
677 dm
->template_arg_lists
= top
->next
;
678 /* Delete the popped element. */
679 template_arg_list_delete (top
);
680 #ifdef CP_DEMANGLE_DEBUG
681 fprintf (stderr
, " ** removing template arg list\n");
686 #ifdef CP_DEMANGLE_DEBUG
688 /* Prints the contents of ARG_LIST to FP. */
691 template_arg_list_print (arg_list
, fp
)
692 template_arg_list_t arg_list
;
698 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
699 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
702 fprintf (fp
, " T_ : ");
704 fprintf (fp
, " T%d_ : ", index
);
706 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
710 #endif /* CP_DEMANGLE_DEBUG */
712 /* Returns the topmost element on the stack of template argument
713 lists. If there is no list of template arguments, returns NULL. */
715 static template_arg_list_t
716 current_template_arg_list (dm
)
719 return dm
->template_arg_lists
;
722 /* Allocates a demangling_t object for demangling mangled NAME. A new
723 result must be pushed before the returned object can be used.
724 Returns NULL if allocation fails. */
727 demangling_new (name
)
731 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
738 dm
->num_substitutions
= 0;
739 dm
->substitutions_allocated
= 10;
740 dm
->template_arg_lists
= NULL
;
741 dm
->last_source_name
= dyn_string_new (0);
742 if (dm
->last_source_name
== NULL
)
744 dm
->substitutions
= (struct substitution_def
*)
745 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
746 if (dm
->substitutions
== NULL
)
748 dyn_string_delete (dm
->last_source_name
);
755 /* Deallocates a demangling_t object and all memory associated with
759 demangling_delete (dm
)
763 template_arg_list_t arg_list
= dm
->template_arg_lists
;
765 /* Delete the stack of template argument lists. */
766 while (arg_list
!= NULL
)
768 template_arg_list_t next
= arg_list
->next
;
769 template_arg_list_delete (arg_list
);
772 /* Delete the list of substitutions. */
773 for (i
= dm
->num_substitutions
; --i
>= 0; )
774 dyn_string_delete (dm
->substitutions
[i
].text
);
775 free (dm
->substitutions
);
776 /* Delete the demangled result. */
777 string_list_delete (dm
->result
);
778 /* Delete the stored identifier name. */
779 dyn_string_delete (dm
->last_source_name
);
780 /* Delete the context object itself. */
784 /* These functions demangle an alternative of the corresponding
785 production in the mangling spec. The first argument of each is a
786 demangling context structure for the current demangling
787 operation. Most emit demangled text directly to the topmost result
788 string on the result string stack in the demangling context
791 static status_t demangle_char
792 PARAMS ((demangling_t
, int));
793 static status_t demangle_mangled_name
794 PARAMS ((demangling_t
));
795 static status_t demangle_encoding
796 PARAMS ((demangling_t
));
797 static status_t demangle_name
798 PARAMS ((demangling_t
, int *));
799 static status_t demangle_nested_name
800 PARAMS ((demangling_t
, int *));
801 static status_t demangle_prefix
802 PARAMS ((demangling_t
, int *));
803 static status_t demangle_unqualified_name
804 PARAMS ((demangling_t
));
805 static status_t demangle_source_name
806 PARAMS ((demangling_t
));
807 static status_t demangle_number
808 PARAMS ((demangling_t
, int *, int, int));
809 static status_t demangle_number_literally
810 PARAMS ((demangling_t
, dyn_string_t
, int, int));
811 static status_t demangle_identifier
812 PARAMS ((demangling_t
, int, dyn_string_t
));
813 static status_t demangle_operator_name
814 PARAMS ((demangling_t
, int, int *));
815 static status_t demangle_special_name
816 PARAMS ((demangling_t
));
817 static status_t demangle_ctor_dtor_name
818 PARAMS ((demangling_t
));
819 static status_t demangle_type_ptr
820 PARAMS ((demangling_t
));
821 static status_t demangle_type
822 PARAMS ((demangling_t
));
823 static status_t demangle_CV_qualifiers
824 PARAMS ((demangling_t
, dyn_string_t
));
825 static status_t demangle_builtin_type
826 PARAMS ((demangling_t
));
827 static status_t demangle_function_type
828 PARAMS ((demangling_t
, int));
829 static status_t demangle_bare_function_type
830 PARAMS ((demangling_t
, int));
831 static status_t demangle_class_enum_type
832 PARAMS ((demangling_t
, int *));
833 static status_t demangle_array_type
834 PARAMS ((demangling_t
));
835 static status_t demangle_template_param
836 PARAMS ((demangling_t
, int *));
837 static status_t demangle_template_args
838 PARAMS ((demangling_t
));
839 static status_t demangle_literal
840 PARAMS ((demangling_t
));
841 static status_t demangle_template_arg
842 PARAMS ((demangling_t
));
843 static status_t demangle_expression
844 PARAMS ((demangling_t
));
845 static status_t demangle_scope_expression
846 PARAMS ((demangling_t
));
847 static status_t demangle_expr_primary
848 PARAMS ((demangling_t
));
849 static status_t demangle_substitution
850 PARAMS ((demangling_t
, int *, int *));
851 static status_t demangle_local_name
852 PARAMS ((demangling_t
));
853 static status_t demangle_discriminator
854 PARAMS ((demangling_t
, int));
855 static status_t cp_demangle
856 PARAMS ((const char *, dyn_string_t
));
858 static status_t cp_demangle_type
859 PARAMS ((const char*, dyn_string_t
));
862 /* When passed to demangle_bare_function_type, indicates that the
863 function's return type is not encoded before its parameter types. */
864 #define BFT_NO_RETURN_TYPE -1
866 /* Check that the next character is C. If so, consume it. If not,
870 demangle_char (dm
, c
)
874 static char *error_message
= NULL
;
876 if (peek_char (dm
) == c
)
883 if (error_message
== NULL
)
884 error_message
= strdup ("Expected ?");
885 error_message
[9] = c
;
886 return error_message
;
890 /* Demangles and emits a <mangled-name>.
892 <mangled-name> ::= _Z <encoding> */
895 demangle_mangled_name (dm
)
898 DEMANGLE_TRACE ("mangled-name", dm
);
899 RETURN_IF_ERROR (demangle_char (dm
, '_'));
900 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
901 RETURN_IF_ERROR (demangle_encoding (dm
));
905 /* Demangles and emits an <encoding>.
907 <encoding> ::= <function name> <bare-function-type>
909 ::= <special-name> */
912 demangle_encoding (dm
)
917 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
918 char peek
= peek_char (dm
);
920 DEMANGLE_TRACE ("encoding", dm
);
922 /* Remember where the name starts. If it turns out to be a template
923 function, we'll have to insert the return type here. */
924 start_position
= result_length (dm
);
926 if (peek
== 'G' || peek
== 'T')
927 RETURN_IF_ERROR (demangle_special_name (dm
));
930 /* Now demangle the name. */
931 RETURN_IF_ERROR (demangle_name (dm
, &template_p
));
933 /* If there's anything left, the name was a function name, with
934 maybe its return type, and its parameters types, following. */
935 if (!end_of_name_p (dm
)
936 && peek_char (dm
) != 'E')
939 /* Template functions have their return type encoded. The
940 return type should be inserted at start_position. */
942 (demangle_bare_function_type (dm
, start_position
));
944 /* Non-template functions don't have their return type
947 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
951 /* Pop off template argument lists that were built during the
952 mangling of this name, to restore the old template context. */
953 pop_to_template_arg_list (dm
, old_arg_list
);
958 /* Demangles and emits a <name>.
960 <name> ::= <unscoped-name>
961 ::= <unscoped-template-name> <template-args>
965 <unscoped-name> ::= <unqualified-name>
966 ::= St <unqualified-name> # ::std::
968 <unscoped-template-name>
970 ::= <substitution> */
973 demangle_name (dm
, template_p
)
977 int special_std_substitution
;
978 int start
= substitution_start (dm
);
980 DEMANGLE_TRACE ("name", dm
);
982 switch (peek_char (dm
))
985 /* This is a <nested-name>. */
986 RETURN_IF_ERROR (demangle_nested_name (dm
, template_p
));
990 RETURN_IF_ERROR (demangle_local_name (dm
));
994 /* The `St' substitution allows a name nested in std:: to appear
995 without being enclosed in a nested name. */
996 if (peek_char_next (dm
) == 't')
998 (void) next_char (dm
);
999 (void) next_char (dm
);
1000 RETURN_IF_ERROR (result_append (dm
, "std::"));
1001 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1005 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
,
1006 &special_std_substitution
));
1007 if (special_std_substitution
)
1009 /* This was the magic `std::' substitution. We can have
1010 a <nested-name> or one of the unscoped names
1012 RETURN_IF_ERROR (result_append (dm
, "::"));
1013 RETURN_IF_ERROR (demangle_name (dm
, template_p
));
1016 /* Check if a template argument list immediately follows.
1017 If so, then we just demangled an <unqualified-template-name>. */
1018 if (peek_char (dm
) == 'I')
1020 RETURN_IF_ERROR (substitution_add (dm
, start
, 0,
1021 NOT_TEMPLATE_PARM
));
1022 RETURN_IF_ERROR (demangle_template_args (dm
));
1027 /* This is an <unscoped-name> or <unscoped-template-name>. */
1028 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1030 /* If the <unqualified-name> is followed by template args, this
1031 is an <unscoped-template-name>. */
1032 if (peek_char (dm
) == 'I')
1034 /* Add a substitution for the unqualified template name. */
1035 RETURN_IF_ERROR (substitution_add (dm
, start
, 0,
1036 NOT_TEMPLATE_PARM
));
1038 RETURN_IF_ERROR (demangle_template_args (dm
));
1050 /* Demangles and emits a <nested-name>.
1052 <nested-name> ::= N [<CV-qualifiers>] <prefix> <component> E */
1055 demangle_nested_name (dm
, template_p
)
1061 DEMANGLE_TRACE ("nested-name", dm
);
1063 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1065 peek
= peek_char (dm
);
1066 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1070 /* Snarf up and emit CV qualifiers. */
1071 dyn_string_t cv_qualifiers
= dyn_string_new (24);
1072 if (cv_qualifiers
== NULL
)
1073 return STATUS_ALLOCATION_FAILED
;
1075 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1076 status
= result_append_string (dm
, cv_qualifiers
);
1077 dyn_string_delete (cv_qualifiers
);
1078 RETURN_IF_ERROR (status
);
1079 RETURN_IF_ERROR (result_append_space (dm
));
1082 RETURN_IF_ERROR (demangle_prefix (dm
, template_p
));
1083 /* No need to demangle the final <component>; demangle_prefix will
1085 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1090 /* Demangles and emits a <prefix>.
1092 <prefix> ::= <prefix> <component>
1093 ::= <template-prefix> <template-args>
1097 <template-prefix> ::= <prefix>
1100 <component> ::= <unqualified-name>
1104 demangle_prefix (dm
, template_p
)
1108 int start
= substitution_start (dm
);
1111 /* TEMPLATE_P is updated as we decend the nesting chain. After
1112 <template-args>, it is set to non-zero; after everything else it
1115 DEMANGLE_TRACE ("prefix", dm
);
1122 if (end_of_name_p (dm
))
1123 return "Unexpected end of name in <compound-name>.";
1125 peek
= peek_char (dm
);
1127 if (IS_DIGIT ((unsigned char) peek
)
1128 || (peek
>= 'a' && peek
<= 'z')
1129 || peek
== 'C' || peek
== 'D'
1132 /* We have another level of scope qualification. */
1134 RETURN_IF_ERROR (result_append (dm
, "::"));
1139 /* The substitution determines whether this is a
1141 RETURN_IF_ERROR (demangle_substitution (dm
, template_p
,
1145 RETURN_IF_ERROR (demangle_unqualified_name (dm
));
1149 else if (peek
== 'Z')
1150 RETURN_IF_ERROR (demangle_local_name (dm
));
1151 else if (peek
== 'I')
1154 return STATUS_INTERNAL_ERROR
;
1155 /* The template name is a substitution candidate. */
1156 RETURN_IF_ERROR (substitution_add (dm
, start
, 0, NOT_TEMPLATE_PARM
));
1157 RETURN_IF_ERROR (demangle_template_args (dm
));
1160 else if (peek
== 'E')
1164 return "Unexpected character in <compound-name>.";
1166 /* Add a new substitution for the prefix thus far. */
1167 RETURN_IF_ERROR (substitution_add (dm
, start
, *template_p
,
1168 NOT_TEMPLATE_PARM
));
1172 /* Demangles and emits an <unqualified-name>. If the
1173 <unqualified-name> is a function and the first element in the
1174 argument list should be taken to be its return type,
1175 ENCODE_RETURN_TYPE is non-zero.
1177 <unqualified-name> ::= <operator-name>
1179 ::= <source-name> */
1182 demangle_unqualified_name (dm
)
1185 char peek
= peek_char (dm
);
1187 DEMANGLE_TRACE ("unqualified-name", dm
);
1189 if (IS_DIGIT ((unsigned char) peek
))
1190 RETURN_IF_ERROR (demangle_source_name (dm
));
1191 else if (peek
>= 'a' && peek
<= 'z')
1194 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
));
1196 else if (peek
== 'C' || peek
== 'D')
1197 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1199 return "Unexpected character in <unqualified-name>.";
1204 /* Demangles and emits <source-name>.
1206 <source-name> ::= <length number> <identifier> */
1209 demangle_source_name (dm
)
1214 DEMANGLE_TRACE ("source-name", dm
);
1216 /* Decode the length of the identifier. */
1217 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1219 return "Zero length in <source-name>.";
1221 /* Now the identifier itself. It's placed into last_source_name,
1222 where it can be used to build a constructor or destructor name. */
1223 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1224 dm
->last_source_name
));
1227 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1232 /* Demangles a number, either a <number> or a <positive-number> at the
1233 current position, consuming all consecutive digit characters. Sets
1234 *VALUE to the resulting numberand returns STATUS_OK. The number is
1235 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1236 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1238 <number> ::= [n] <positive-number>
1240 <positive-number> ::= <decimal integer> */
1243 demangle_number (dm
, value
, base
, is_signed
)
1249 dyn_string_t number
= dyn_string_new (10);
1251 DEMANGLE_TRACE ("number", dm
);
1254 return STATUS_ALLOCATION_FAILED
;
1256 demangle_number_literally (dm
, number
, base
, is_signed
);
1257 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1258 dyn_string_delete (number
);
1263 /* Demangles a number at the current position. The digits (and minus
1264 sign, if present) that make up the number are appended to STR.
1265 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1266 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1267 accepted. Does not consume a trailing underscore or other
1268 terminating character. */
1271 demangle_number_literally (dm
, str
, base
, is_signed
)
1277 DEMANGLE_TRACE ("number*", dm
);
1279 if (base
!= 10 && base
!= 36)
1280 return STATUS_INTERNAL_ERROR
;
1282 /* An `n' denotes a negative number. */
1283 if (is_signed
&& peek_char (dm
) == 'n')
1285 /* Skip past the n. */
1287 /* The normal way to write a negative number is with a minus
1289 if (!dyn_string_append_char (str
, '-'))
1290 return STATUS_ALLOCATION_FAILED
;
1293 /* Loop until we hit a non-digit. */
1296 char peek
= peek_char (dm
);
1297 if (IS_DIGIT ((unsigned char) peek
)
1298 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1300 /* Accumulate digits. */
1301 if (!dyn_string_append_char (str
, next_char (dm
)))
1302 return STATUS_ALLOCATION_FAILED
;
1305 /* Not a digit? All done. */
1312 /* Demangles an identifier at the current position of LENGTH
1313 characters and places it in IDENTIFIER. */
1316 demangle_identifier (dm
, length
, identifier
)
1319 dyn_string_t identifier
;
1321 DEMANGLE_TRACE ("identifier", dm
);
1323 dyn_string_clear (identifier
);
1324 if (!dyn_string_resize (identifier
, length
))
1325 return STATUS_ALLOCATION_FAILED
;
1327 while (length
-- > 0)
1329 if (end_of_name_p (dm
))
1330 return "Unexpected end of name in <identifier>.";
1331 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1332 return STATUS_ALLOCATION_FAILED
;
1338 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1339 the short form is emitted; otherwise the full source form
1340 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1341 operands that the operator takes.
1392 ::= cv <type> # cast
1393 ::= vx <source-name> # vendor extended operator */
1396 demangle_operator_name (dm
, short_name
, num_args
)
1401 struct operator_code
1403 /* The mangled code for this operator. */
1405 /* The source name of this operator. */
1407 /* The number of arguments this operator takes. */
1411 static const struct operator_code operators
[] =
1422 { "da", " delete[]", 1 },
1424 { "dl", " delete" , 1 },
1432 { "lS", "<<=" , 2 },
1441 { "na", " new[]" , 1 },
1445 { "nw", " new" , 1 },
1451 { "pm", "->*" , 2 },
1456 { "rS", ">>=" , 2 },
1459 { "sz", " sizeof" , 1 }
1462 const int num_operators
=
1463 sizeof (operators
) / sizeof (struct operator_code
);
1465 int c0
= next_char (dm
);
1466 int c1
= next_char (dm
);
1467 const struct operator_code
* p1
= operators
;
1468 const struct operator_code
* p2
= operators
+ num_operators
;
1470 DEMANGLE_TRACE ("operator-name", dm
);
1472 /* Is this a vendor extended operator? */
1473 if (c0
== 'v' && c1
== 'x')
1475 RETURN_IF_ERROR (result_append (dm
, "operator"));
1476 RETURN_IF_ERROR (demangle_source_name (dm
));
1481 /* Is this a conversion operator? */
1482 if (c0
== 'c' && c1
== 'v')
1484 RETURN_IF_ERROR (result_append (dm
, "operator "));
1485 /* Demangle the converted-to type. */
1486 RETURN_IF_ERROR (demangle_type (dm
));
1491 /* Perform a binary search for the operator code. */
1494 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1495 char match0
= p
->code
[0];
1496 char match1
= p
->code
[1];
1498 if (c0
== match0
&& c1
== match1
)
1502 RETURN_IF_ERROR (result_append (dm
, "operator"));
1503 RETURN_IF_ERROR (result_append (dm
, p
->name
));
1504 *num_args
= p
->num_args
;
1510 /* Couldn't find it. */
1511 return "Unknown code in <operator-name>.";
1514 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1521 /* Demangles and emits a <special-name>.
1523 <special-name> ::= GV <object name> # Guard variable
1524 ::= Th[n] <offset number> _ <base name> <base encoding>
1525 # non-virtual base override thunk
1526 ::= Tv[n] <offset number> _ <vcall offset number>
1528 # virtual base override thunk
1529 ::= TV <type> # virtual table
1531 ::= TI <type> # typeinfo structure
1532 ::= TS <type> # typeinfo name
1534 Also demangles the special g++ manglings,
1536 <special-name> ::= CT <type> <offset number> _ <base type>
1537 # construction vtable
1538 ::= TF <type> # typeinfo function (old ABI only)
1539 ::= TJ <type> # java Class structure */
1542 demangle_special_name (dm
)
1545 dyn_string_t number
;
1547 char peek
= peek_char (dm
);
1549 DEMANGLE_TRACE ("special-name", dm
);
1553 /* A guard variable name. Consume the G. */
1555 RETURN_IF_ERROR (demangle_char (dm
, 'V'));
1556 RETURN_IF_ERROR (result_append (dm
, "guard variable for "));
1557 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1559 else if (peek
== 'T')
1561 status_t status
= STATUS_OK
;
1563 /* Other C++ implementation miscellania. Consume the T. */
1566 switch (peek_char (dm
))
1569 /* Virtual table. */
1571 RETURN_IF_ERROR (result_append (dm
, "vtable for "));
1572 RETURN_IF_ERROR (demangle_type (dm
));
1576 /* VTT structure. */
1578 RETURN_IF_ERROR (result_append (dm
, "VTT for "));
1579 RETURN_IF_ERROR (demangle_type (dm
));
1583 /* Typeinfo structure. */
1585 RETURN_IF_ERROR (result_append (dm
, "typeinfo for "));
1586 RETURN_IF_ERROR (demangle_type (dm
));
1590 /* Typeinfo function. Used only in old ABI with new mangling. */
1592 RETURN_IF_ERROR (result_append (dm
, "typeinfo fn for "));
1593 RETURN_IF_ERROR (demangle_type (dm
));
1597 /* Character string containing type name, used in typeinfo. */
1599 RETURN_IF_ERROR (result_append (dm
, "typeinfo name for "));
1600 RETURN_IF_ERROR (demangle_type (dm
));
1604 /* The java Class variable corresponding to a C++ class. */
1606 RETURN_IF_ERROR (result_append (dm
, "java Class for "));
1607 RETURN_IF_ERROR (demangle_type (dm
));
1611 /* Non-virtual thunk. */
1613 RETURN_IF_ERROR (result_append (dm
, "non-virtual thunk"));
1614 /* Demangle and emit the offset. */
1615 number
= dyn_string_new (4);
1617 return STATUS_ALLOCATION_FAILED
;
1618 demangle_number_literally (dm
, number
, 10, 1);
1619 /* Don't display the offset unless in verbose mode. */
1622 status
= result_append_char (dm
, ' ');
1623 if (STATUS_NO_ERROR (status
))
1624 status
= result_append_string (dm
, number
);
1626 dyn_string_delete (number
);
1627 RETURN_IF_ERROR (status
);
1628 /* Demangle the separator. */
1629 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1630 /* Demangle and emit the target name and function type. */
1631 RETURN_IF_ERROR (result_append (dm
, " to "));
1632 RETURN_IF_ERROR (demangle_encoding (dm
));
1636 /* Virtual thunk. */
1638 RETURN_IF_ERROR (result_append (dm
, "virtual thunk "));
1639 /* Demangle and emit the offset. */
1640 number
= dyn_string_new (4);
1642 return STATUS_ALLOCATION_FAILED
;
1643 demangle_number_literally (dm
, number
, 10, 1);
1644 /* Don't display the offset unless in verbose mode. */
1647 status
= result_append_string (dm
, number
);
1648 if (STATUS_NO_ERROR (status
))
1649 result_append_char (dm
, ' ');
1651 dyn_string_delete (number
);
1652 RETURN_IF_ERROR (status
);
1653 /* Demangle the separator. */
1654 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1655 /* Demangle and emit the vcall offset. */
1656 number
= dyn_string_new (4);
1658 return STATUS_ALLOCATION_FAILED
;
1659 demangle_number_literally (dm
, number
, 10, 1);
1660 /* Don't display the vcall offset unless in verbose mode. */
1663 status
= result_append_string (dm
, number
);
1664 if (STATUS_NO_ERROR (status
))
1665 status
= result_append_char (dm
, ' ');
1667 dyn_string_delete (number
);
1668 RETURN_IF_ERROR (status
);
1669 /* Demangle the separator. */
1670 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1671 /* Demangle and emit the target function. */
1672 RETURN_IF_ERROR (result_append (dm
, "to "));
1673 RETURN_IF_ERROR (demangle_encoding (dm
));
1677 /* TC is a special g++ mangling for a construction vtable. */
1680 dyn_string_t derived_type
;
1683 RETURN_IF_ERROR (result_append (dm
, "construction vtable for "));
1685 /* Demangle the derived type off to the side. */
1686 RETURN_IF_ERROR (result_push (dm
));
1687 RETURN_IF_ERROR (demangle_type (dm
));
1688 derived_type
= (dyn_string_t
) result_pop (dm
);
1690 /* Demangle the offset. */
1691 number
= dyn_string_new (4);
1694 dyn_string_delete (derived_type
);
1695 return STATUS_ALLOCATION_FAILED
;
1697 demangle_number_literally (dm
, number
, 10, 1);
1698 /* Demangle the underscore separator. */
1699 status
= demangle_char (dm
, '_');
1701 /* Demangle the base type. */
1702 if (STATUS_NO_ERROR (status
))
1703 status
= demangle_type (dm
);
1705 /* Emit the derived type. */
1706 if (STATUS_NO_ERROR (status
))
1707 status
= result_append (dm
, "-in-");
1708 if (STATUS_NO_ERROR (status
))
1709 status
= result_append_string (dm
, derived_type
);
1710 dyn_string_delete (derived_type
);
1712 /* Don't display the offset unless in verbose mode. */
1715 status
= result_append_char (dm
, ' ');
1716 if (STATUS_NO_ERROR (status
))
1717 result_append_string (dm
, number
);
1719 dyn_string_delete (number
);
1720 RETURN_IF_ERROR (status
);
1723 /* If flag_strict, fall through. */
1726 return "Unrecognized <special-name>.";
1730 return STATUS_ERROR
;
1735 /* Demangles and emits a <ctor-dtor-name>.
1738 ::= C1 # complete object (in-charge) ctor
1739 ::= C2 # base object (not-in-charge) ctor
1740 ::= C3 # complete object (in-charge) allocating ctor
1741 ::= C4 # base object (not-in-charge) allocating ctor
1742 ::= D0 # deleting (in-charge) dtor
1743 ::= D1 # complete object (in-charge) dtor
1744 ::= D2 # base object (not-in-charge) dtor */
1747 demangle_ctor_dtor_name (dm
)
1750 static const char *const ctor_flavors
[] =
1754 "in-charge allocating",
1755 "not-in-charge allocating"
1757 static const char *const dtor_flavors
[] =
1759 "in-charge deleting",
1765 char peek
= peek_char (dm
);
1767 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
1771 /* A constructor name. Consume the C. */
1773 if (peek_char (dm
) < '1' || peek_char (dm
) > '4')
1774 return "Unrecognized constructor.";
1775 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1776 /* Print the flavor of the constructor if in verbose mode. */
1777 flavor
= next_char (dm
) - '1';
1780 RETURN_IF_ERROR (result_append (dm
, "["));
1781 RETURN_IF_ERROR (result_append (dm
, ctor_flavors
[flavor
]));
1782 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1785 else if (peek
== 'D')
1787 /* A destructor name. Consume the D. */
1789 if (peek_char (dm
) < '0' || peek_char (dm
) > '2')
1790 return "Unrecognized destructor.";
1791 RETURN_IF_ERROR (result_append_char (dm
, '~'));
1792 RETURN_IF_ERROR (result_append_string (dm
, dm
->last_source_name
));
1793 /* Print the flavor of the destructor if in verbose mode. */
1794 flavor
= next_char (dm
) - '0';
1797 RETURN_IF_ERROR (result_append (dm
, " ["));
1798 RETURN_IF_ERROR (result_append (dm
, dtor_flavors
[flavor
]));
1799 RETURN_IF_ERROR (result_append_char (dm
, ']'));
1803 return STATUS_ERROR
;
1808 /* Handle pointer, reference, and pointer-to-member cases for
1809 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
1810 build a pointer/reference type. We snarf all these, plus the
1811 following <type>, all at once since we need to know whether we have
1812 a pointer to data or pointer to function to construct the right
1813 output syntax. C++'s pointer syntax is hairy.
1817 ::= <pointer-to-member-type>
1819 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
1822 demangle_type_ptr (dm
)
1828 /* Collect pointer symbols into this string. */
1829 dyn_string_t symbols
= dyn_string_new (10);
1831 DEMANGLE_TRACE ("type*", dm
);
1833 if (symbols
== NULL
)
1834 return STATUS_ALLOCATION_FAILED
;
1836 /* Scan forward, collecting pointers and references into symbols,
1837 until we hit something else. Then emit the type. */
1840 next
= peek_char (dm
);
1843 if (!dyn_string_append_char (symbols
, '*'))
1844 return STATUS_ALLOCATION_FAILED
;
1847 else if (next
== 'R')
1849 if (!dyn_string_append_char (symbols
, '&'))
1850 return STATUS_ALLOCATION_FAILED
;
1853 else if (next
== 'M')
1855 /* Pointer-to-member. */
1856 dyn_string_t class_type
;
1861 /* Capture the type of which this is a pointer-to-member. */
1862 RETURN_IF_ERROR (result_push (dm
));
1863 RETURN_IF_ERROR (demangle_type (dm
));
1864 class_type
= (dyn_string_t
) result_pop (dm
);
1866 /* Build the pointer-to-member notation. It comes before
1867 other pointer and reference qualifiers -- */
1868 if (!dyn_string_prepend_cstr (symbols
, "::*"))
1869 return STATUS_ALLOCATION_FAILED
;
1870 if (!dyn_string_prepend (symbols
, class_type
))
1871 return STATUS_ALLOCATION_FAILED
;
1872 dyn_string_delete (class_type
);
1874 if (peek_char (dm
) == 'F')
1877 /* Demangle the type of the pointed-to member. */
1878 status
= demangle_type (dm
);
1879 /* Make it pretty. */
1880 if (STATUS_NO_ERROR (status
))
1881 status
= result_append_space (dm
);
1882 /* Add the pointer-to-member syntax, and other pointer and
1883 reference symbols. */
1884 if (STATUS_NO_ERROR (status
))
1885 status
= result_append_string (dm
, symbols
);
1887 dyn_string_delete (symbols
);
1889 RETURN_IF_ERROR (status
);
1892 else if (next
== 'F')
1894 /* Ooh, tricky, a pointer-to-function. */
1895 int position
= result_length (dm
);
1896 status
= result_append_char (dm
, '(');
1897 if (STATUS_NO_ERROR (status
))
1898 status
= result_append_string (dm
, symbols
);
1899 if (STATUS_NO_ERROR (status
))
1900 status
= result_append_char (dm
, ')');
1901 dyn_string_delete (symbols
);
1902 RETURN_IF_ERROR (status
);
1904 RETURN_IF_ERROR (demangle_function_type (dm
, position
));
1909 /* No more pointe or reference tokens. Finish up. */
1910 status
= demangle_type (dm
);
1912 if (STATUS_NO_ERROR (status
))
1913 status
= result_append_string (dm
, symbols
);
1914 dyn_string_delete (symbols
);
1915 RETURN_IF_ERROR (status
);
1917 RETURN_IF_ERROR (status
);
1923 /* Demangles and emits a <type>.
1925 <type> ::= <builtin-type>
1927 ::= <class-enum-type>
1929 ::= <pointer-to-member-type>
1930 ::= <template-param>
1931 ::= <CV-qualifiers> <type>
1932 ::= P <type> # pointer-to
1933 ::= R <type> # reference-to
1934 ::= C <type> # complex pair (C 2000)
1935 ::= G <type> # imaginary (C 2000)
1936 ::= U <source-name> <type> # vendor extended type qualifier
1937 ::= <substitution> */
1943 int start
= substitution_start (dm
);
1944 char peek
= peek_char (dm
);
1947 int special_std_substitution
;
1948 int is_builtin_type
= 0;
1949 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1950 int template_parm
= NOT_TEMPLATE_PARM
;
1952 DEMANGLE_TRACE ("type", dm
);
1954 /* A <class-enum-type> can start with a digit (a <source-name>), an
1955 N (a <nested-name>), or a Z (a <local-name>). */
1956 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
1957 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &template_p
));
1958 else if (peek
>= 'a' && peek
<= 'z')
1960 RETURN_IF_ERROR (demangle_builtin_type (dm
));
1961 is_builtin_type
= 1;
1971 dyn_string_t cv_qualifiers
= dyn_string_new (24);
1973 if (cv_qualifiers
== NULL
)
1974 return STATUS_ALLOCATION_FAILED
;
1976 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1978 /* If the qualifiers apply to a pointer or reference, they
1979 need to come after the whole qualified type. */
1980 if (peek_char (dm
) == 'P' || peek_char (dm
) == 'R')
1982 status
= demangle_type (dm
);
1983 if (STATUS_NO_ERROR (status
))
1984 status
= result_append_space (dm
);
1985 if (STATUS_NO_ERROR (status
))
1986 status
= result_append_string (dm
, cv_qualifiers
);
1988 /* Otherwise, the qualifiers come first. */
1991 status
= result_append_string (dm
, cv_qualifiers
);
1992 if (STATUS_NO_ERROR (status
))
1993 status
= result_append_space (dm
);
1994 if (STATUS_NO_ERROR (status
))
1995 status
= demangle_type (dm
);
1998 dyn_string_delete (cv_qualifiers
);
1999 RETURN_IF_ERROR (status
);
2004 return "Non-pointer or -reference function type.";
2007 RETURN_IF_ERROR (demangle_array_type (dm
));
2011 RETURN_IF_ERROR (demangle_template_param (dm
, &template_parm
));
2015 /* First check if this is a special substitution. If it is,
2016 this is a <class-enum-type>. Special substitutions have a
2017 letter following the `S'; other substitutions have a digit
2019 peek_next
= peek_char_next (dm
);
2020 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2021 RETURN_IF_ERROR (demangle_substitution (dm
, &template_p
,
2022 &special_std_substitution
));
2024 demangle_class_enum_type (dm
, &template_p
);
2030 RETURN_IF_ERROR (demangle_type_ptr (dm
));
2034 /* A C99 complex type. */
2035 RETURN_IF_ERROR (result_append (dm
, "complex "));
2037 RETURN_IF_ERROR (demangle_type (dm
));
2041 /* A C99 imaginary type. */
2042 RETURN_IF_ERROR (result_append (dm
, "imaginary "));
2044 RETURN_IF_ERROR (demangle_type (dm
));
2048 /* Vendor extended type qualifier. */
2050 RETURN_IF_ERROR (demangle_source_name (dm
));
2051 RETURN_IF_ERROR (result_append_char (dm
, ' '));
2052 RETURN_IF_ERROR (demangle_type (dm
));
2056 return "Unexpected character in <type>.";
2059 /* Unqualified builin types are not substitution candidates. */
2060 if (!is_builtin_type
)
2061 /* Add a new substitution for the type. If this type was a
2062 <template-param>, pass its index since from the point of
2063 substitutions, a <template-param> token is a substitution
2064 candidate distinct from the type that is substituted for it. */
2065 RETURN_IF_ERROR (substitution_add (dm
, start
, template_p
, template_parm
));
2067 /* Pop off template argument lists added during mangling of this
2069 pop_to_template_arg_list (dm
, old_arg_list
);
2074 /* C++ source names of builtin types, indexed by the mangled code
2075 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2076 static const char *const builtin_type_names
[26] =
2078 "signed char", /* a */
2082 "long double", /* e */
2084 "__float128", /* g */
2085 "unsigned char", /* h */
2090 "unsigned long", /* m */
2092 "unsigned __int128", /* o */
2097 "unsigned short", /* t */
2101 "long long", /* x */
2102 "unsigned long long", /* y */
2106 /* Demangles and emits a <builtin-type>.
2108 <builtin-type> ::= v # void
2113 ::= h # unsigned char
2115 ::= t # unsigned short
2117 ::= j # unsigned int
2119 ::= m # unsigned long
2120 ::= x # long long, __int64
2121 ::= y # unsigned long long, __int64
2123 ::= o # unsigned __int128
2126 ::= e # long double, __float80
2129 ::= u <source-name> # vendor extended type */
2132 demangle_builtin_type (dm
)
2136 char code
= peek_char (dm
);
2138 DEMANGLE_TRACE ("builtin-type", dm
);
2143 RETURN_IF_ERROR (demangle_source_name (dm
));
2146 else if (code
>= 'a' && code
<= 'z')
2148 const char *type_name
= builtin_type_names
[code
- 'a'];
2149 if (type_name
== NULL
)
2150 return "Unrecognized <builtin-type> code.";
2152 RETURN_IF_ERROR (result_append (dm
, type_name
));
2157 return "Non-alphabetic <builtin-type> code.";
2160 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2161 restrict) at the current position. The qualifiers are appended to
2162 QUALIFIERS. Returns STATUS_OK. */
2165 demangle_CV_qualifiers (dm
, qualifiers
)
2167 dyn_string_t qualifiers
;
2169 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2173 switch (peek_char (dm
))
2176 if (!dyn_string_append_space (qualifiers
))
2177 return STATUS_ALLOCATION_FAILED
;
2178 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2179 return STATUS_ALLOCATION_FAILED
;
2183 if (!dyn_string_append_space (qualifiers
))
2184 return STATUS_ALLOCATION_FAILED
;
2185 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2186 return STATUS_ALLOCATION_FAILED
;
2190 if (!dyn_string_append_space (qualifiers
))
2191 return STATUS_ALLOCATION_FAILED
;
2192 if (!dyn_string_append_cstr (qualifiers
, "const"))
2193 return STATUS_ALLOCATION_FAILED
;
2204 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2205 position in the result string of the start of the function
2206 identifier, at which the function's return type will be inserted.
2208 <function-type> ::= F [Y] <bare-function-type> E */
2211 demangle_function_type (dm
, function_name_pos
)
2213 int function_name_pos
;
2215 DEMANGLE_TRACE ("function-type", dm
);
2216 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2217 if (peek_char (dm
) == 'Y')
2219 /* Indicate this function has C linkage if in verbose mode. */
2221 RETURN_IF_ERROR (result_append (dm
, " [extern \"C\"] "));
2224 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2225 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2229 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2230 position in the result string at which the function return type
2231 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2232 function's return type is assumed not to be encoded.
2234 <bare-function-type> ::= <signature type>+ */
2237 demangle_bare_function_type (dm
, return_type_pos
)
2239 int return_type_pos
;
2241 /* Sequence is the index of the current function parameter, counting
2242 from zero. The value -1 denotes the return type. */
2244 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2246 DEMANGLE_TRACE ("bare-function-type", dm
);
2248 RETURN_IF_ERROR (result_append_char (dm
, '('));
2249 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2252 /* We're decoding the function's return type. */
2254 dyn_string_t return_type
;
2255 status_t status
= STATUS_OK
;
2257 /* Decode the return type off to the side. */
2258 RETURN_IF_ERROR (result_push (dm
));
2259 RETURN_IF_ERROR (demangle_type (dm
));
2260 return_type
= (dyn_string_t
) result_pop (dm
);
2262 /* Add a space to the end of the type. Insert the return
2263 type where we've been asked to. */
2264 if (!dyn_string_append_space (return_type
)
2265 || !dyn_string_insert (result_string (dm
), return_type_pos
,
2267 status
= STATUS_ALLOCATION_FAILED
;
2269 dyn_string_delete (return_type
);
2270 RETURN_IF_ERROR (status
);
2274 /* Skip `void' parameter types. One should only occur as
2275 the only type in a parameter list; in that case, we want
2276 to print `foo ()' instead of `foo (void)'. */
2277 if (peek_char (dm
) == 'v')
2279 /* Consume the v. */
2283 /* Separate parameter types by commas. */
2285 RETURN_IF_ERROR (result_append (dm
, ", "));
2286 /* Demangle the type. */
2287 RETURN_IF_ERROR (demangle_type (dm
));
2292 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2297 /* Demangles and emits a <class-enum-type>. *TEMPLATE_P is set to
2298 non-zero if the type is a template-id, zero otherwise.
2300 <class-enum-type> ::= <name> */
2303 demangle_class_enum_type (dm
, template_p
)
2307 DEMANGLE_TRACE ("class-enum-type", dm
);
2309 RETURN_IF_ERROR (demangle_name (dm
, template_p
));
2313 /* Demangles and emits an <array-type>.
2315 <array-type> ::= A [<dimension number>] _ <element type> */
2318 demangle_array_type (dm
)
2322 dyn_string_t array_size
= dyn_string_new (10);
2324 if (array_size
== NULL
)
2325 return STATUS_ALLOCATION_FAILED
;
2327 status
= demangle_char (dm
, 'A');
2329 /* Demangle the array size into array_size. */
2330 if (STATUS_NO_ERROR (status
))
2331 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2333 /* Demangle the base type of the array. */
2334 if (STATUS_NO_ERROR (status
))
2335 status
= demangle_char (dm
, '_');
2336 if (STATUS_NO_ERROR (status
))
2337 status
= demangle_type (dm
);
2339 /* Emit the array dimension syntax. */
2340 if (STATUS_NO_ERROR (status
))
2341 status
= result_append_char (dm
, '[');
2342 if (STATUS_NO_ERROR (status
))
2343 status
= result_append_string (dm
, array_size
);
2344 if (STATUS_NO_ERROR (status
))
2345 status
= result_append_char (dm
, ']');
2346 dyn_string_delete (array_size
);
2348 RETURN_IF_ERROR (status
);
2353 /* Demangles and emits a <template-param>. The zero-indexed position
2354 in the parameter list is placed in *TEMPLATE_PARM_NUMBER.
2356 <template-param> ::= T_ # first template parameter
2357 ::= T <parameter-2 number> _ */
2360 demangle_template_param (dm
, template_parm_number
)
2362 int *template_parm_number
;
2365 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2368 DEMANGLE_TRACE ("template-param", dm
);
2370 /* Make sure there is a template argmust list in which to look up
2371 this parameter reference. */
2372 if (current_arg_list
== NULL
)
2373 return "Template parameter outside of template.";
2375 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2376 if (peek_char (dm
) == '_')
2380 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2383 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2385 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2387 /* parm_number exceeded the number of arguments in the current
2388 template argument list. */
2389 return "Template parameter number out of bounds.";
2390 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2392 if (peek_char (dm
) == 'I')
2393 RETURN_IF_ERROR (demangle_template_args (dm
));
2395 *template_parm_number
= parm_number
;
2399 /* Demangles and emits a <template-args>.
2401 <template-args> ::= I <template-arg>+ E */
2404 demangle_template_args (dm
)
2408 dyn_string_t old_last_source_name
;
2409 template_arg_list_t arg_list
= template_arg_list_new ();
2411 if (arg_list
== NULL
)
2412 return STATUS_ALLOCATION_FAILED
;
2414 /* Preserve the most recently demangled source name. */
2415 old_last_source_name
= dm
->last_source_name
;
2416 dm
->last_source_name
= dyn_string_new (0);
2418 DEMANGLE_TRACE ("template-args", dm
);
2420 if (dm
->last_source_name
== NULL
)
2421 return STATUS_ALLOCATION_FAILED
;
2423 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2424 RETURN_IF_ERROR (result_append_char (dm
, '<'));
2432 RETURN_IF_ERROR (result_append (dm
, ", "));
2434 /* Capture the template arg. */
2435 RETURN_IF_ERROR (result_push (dm
));
2436 RETURN_IF_ERROR (demangle_template_arg (dm
));
2437 arg
= result_pop (dm
);
2439 /* Emit it in the demangled name. */
2440 RETURN_IF_ERROR (result_append_string (dm
, (dyn_string_t
) arg
));
2442 /* Save it for use in expanding <template-param>s. */
2443 template_arg_list_add_arg (arg_list
, arg
);
2445 while (peek_char (dm
) != 'E');
2446 /* Append the '>'. */
2447 RETURN_IF_ERROR (result_close_template_list (dm
));
2449 /* Consume the 'E'. */
2452 /* Restore the most recent demangled source name. */
2453 dyn_string_delete (dm
->last_source_name
);
2454 dm
->last_source_name
= old_last_source_name
;
2456 /* Push the list onto the top of the stack of template argument
2457 lists, so that arguments from it are used from now on when
2458 expanding <template-param>s. */
2459 push_template_arg_list (dm
, arg_list
);
2464 /* This function, which does not correspond to a production in the
2465 mangling spec, handles the `literal' production for both
2466 <template-arg> and <expr-primary>. It does not expect or consume
2467 the initial `L' or final `E'. The demangling is given by:
2469 <literal> ::= <type> </value/ number>
2471 and the emitted output is `(type)number'. */
2474 demangle_literal (dm
)
2477 char peek
= peek_char (dm
);
2478 dyn_string_t value_string
;
2481 DEMANGLE_TRACE ("literal", dm
);
2483 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
2485 /* If not in verbose mode and this is a builtin type, see if we
2486 can produce simpler numerical output. In particular, for
2487 integer types shorter than `long', just write the number
2488 without type information; for bools, write `true' or `false'.
2489 Other refinements could be made here too. */
2491 /* This constant string is used to map from <builtin-type> codes
2492 (26 letters of the alphabet) to codes that determine how the
2493 value will be displayed. The codes are:
2497 A space means the value will be represented using cast
2499 static const char *const code_map
= "ibi iii ll ii i ";
2501 char code
= code_map
[peek
- 'a'];
2502 /* FIXME: Implement demangling of floats and doubles. */
2504 return STATUS_UNIMPLEMENTED
;
2507 /* It's a boolean. */
2510 /* Consume the b. */
2512 /* Look at the next character. It should be 0 or 1,
2513 corresponding to false or true, respectively. */
2514 value
= peek_char (dm
);
2516 RETURN_IF_ERROR (result_append (dm
, "false"));
2517 else if (value
== '1')
2518 RETURN_IF_ERROR (result_append (dm
, "true"));
2520 return "Unrecognized bool constant.";
2521 /* Consume the 0 or 1. */
2525 else if (code
== 'i' || code
== 'l')
2527 /* It's an integer or long. */
2529 /* Consume the type character. */
2532 /* Demangle the number and write it out. */
2533 value_string
= dyn_string_new (0);
2534 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2535 if (STATUS_NO_ERROR (status
))
2536 status
= result_append_string (dm
, value_string
);
2537 /* For long integers, append an l. */
2538 if (code
== 'l' && STATUS_NO_ERROR (status
))
2539 status
= result_append_char (dm
, code
);
2540 dyn_string_delete (value_string
);
2542 RETURN_IF_ERROR (status
);
2545 /* ...else code == ' ', so fall through to represent this
2546 literal's type explicitly using cast syntax. */
2549 RETURN_IF_ERROR (result_append_char (dm
, '('));
2550 RETURN_IF_ERROR (demangle_type (dm
));
2551 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2553 value_string
= dyn_string_new (0);
2554 if (value_string
== NULL
)
2555 return STATUS_ALLOCATION_FAILED
;
2557 status
= demangle_number_literally (dm
, value_string
, 10, 1);
2558 if (STATUS_NO_ERROR (status
))
2559 status
= result_append_string (dm
, value_string
);
2560 dyn_string_delete (value_string
);
2561 RETURN_IF_ERROR (status
);
2566 /* Demangles and emits a <template-arg>.
2568 <template-arg> ::= <type> # type
2569 ::= L <type> <value number> E # literal
2570 ::= LZ <encoding> E # external name
2571 ::= X <expression> E # expression */
2574 demangle_template_arg (dm
)
2577 DEMANGLE_TRACE ("template-arg", dm
);
2579 switch (peek_char (dm
))
2584 if (peek_char (dm
) == 'Z')
2586 /* External name. */
2588 /* FIXME: Standard is contradictory here. */
2589 RETURN_IF_ERROR (demangle_encoding (dm
));
2592 RETURN_IF_ERROR (demangle_literal (dm
));
2593 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2599 RETURN_IF_ERROR (demangle_expression (dm
));
2603 RETURN_IF_ERROR (demangle_type (dm
));
2610 /* Demangles and emits an <expression>.
2612 <expression> ::= <unary operator-name> <expression>
2613 ::= <binary operator-name> <expression> <expression>
2615 ::= <scope-expression> */
2618 demangle_expression (dm
)
2621 char peek
= peek_char (dm
);
2623 DEMANGLE_TRACE ("expression", dm
);
2625 if (peek
== 'L' || peek
== 'T')
2626 RETURN_IF_ERROR (demangle_expr_primary (dm
));
2627 else if (peek
== 's' && peek_char_next (dm
) == 'r')
2628 RETURN_IF_ERROR (demangle_scope_expression (dm
));
2630 /* An operator expression. */
2633 status_t status
= STATUS_OK
;
2634 dyn_string_t operator_name
;
2636 /* We have an operator name. Since we want to output binary
2637 operations in infix notation, capture the operator name
2639 RETURN_IF_ERROR (result_push (dm
));
2640 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
));
2641 operator_name
= (dyn_string_t
) result_pop (dm
);
2643 /* If it's binary, do an operand first. */
2646 status
= result_append_char (dm
, '(');
2647 if (STATUS_NO_ERROR (status
))
2648 status
= demangle_expression (dm
);
2649 if (STATUS_NO_ERROR (status
))
2650 status
= result_append_char (dm
, ')');
2653 /* Emit the operator. */
2654 if (STATUS_NO_ERROR (status
))
2655 status
= result_append_string (dm
, operator_name
);
2656 dyn_string_delete (operator_name
);
2657 RETURN_IF_ERROR (status
);
2659 /* Emit its second (if binary) or only (if unary) operand. */
2660 RETURN_IF_ERROR (result_append_char (dm
, '('));
2661 RETURN_IF_ERROR (demangle_expression (dm
));
2662 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2664 /* The ternary operator takes a third operand. */
2667 RETURN_IF_ERROR (result_append (dm
, ":("));
2668 RETURN_IF_ERROR (demangle_expression (dm
));
2669 RETURN_IF_ERROR (result_append_char (dm
, ')'));
2676 /* Demangles and emits a <scope-expression>.
2678 <scope-expression> ::= sr <qualifying type> <source-name>
2679 ::= sr <qualifying type> <encoding> */
2682 demangle_scope_expression (dm
)
2685 RETURN_IF_ERROR (demangle_char (dm
, 's'));
2686 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
2687 RETURN_IF_ERROR (demangle_type (dm
));
2688 RETURN_IF_ERROR (result_append (dm
, "::"));
2689 RETURN_IF_ERROR (demangle_encoding (dm
));
2693 /* Demangles and emits an <expr-primary>.
2695 <expr-primary> ::= <template-param>
2696 ::= L <type> <value number> E # literal
2697 ::= L <mangled-name> E # external name */
2700 demangle_expr_primary (dm
)
2703 char peek
= peek_char (dm
);
2706 DEMANGLE_TRACE ("expr-primary", dm
);
2709 RETURN_IF_ERROR (demangle_template_param (dm
, &unused
));
2710 else if (peek
== 'L')
2712 /* Consume the `L'. */
2714 peek
= peek_char (dm
);
2717 RETURN_IF_ERROR (demangle_mangled_name (dm
));
2719 RETURN_IF_ERROR (demangle_literal (dm
));
2721 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2724 return STATUS_ERROR
;
2729 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
2730 if the substitution is the name of a template, zero otherwise. If
2731 the substitution token is St, which corresponds to the `::std::'
2732 namespace and can appear in a non-nested name, sets
2733 *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.
2735 <substitution> ::= S <seq-id> _
2739 ::= Sa # ::std::allocator
2740 ::= Sb # ::std::basic_string
2741 ::= Ss # ::std::basic_string<char,
2742 ::std::char_traits<char>,
2743 ::std::allocator<char> >
2744 ::= Si # ::std::basic_istream<char,
2745 std::char_traits<char> >
2746 ::= So # ::std::basic_ostream<char,
2747 std::char_traits<char> >
2748 ::= Sd # ::std::basic_iostream<char,
2749 std::char_traits<char> >
2753 demangle_substitution (dm
, template_p
, special_std_substitution
)
2756 int *special_std_substitution
;
2762 DEMANGLE_TRACE ("substitution", dm
);
2764 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
2765 *special_std_substitution
= 0;
2767 /* Scan the substitution sequence index. A missing number denotes
2769 peek
= peek_char (dm
);
2772 /* If the following character is 0-9 or a capital letter, interpret
2773 the sequence up to the next underscore as a base-36 substitution
2775 else if (IS_DIGIT ((unsigned char) peek
)
2776 || (peek
>= 'A' && peek
<= 'Z'))
2777 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
2780 const char *new_last_source_name
= NULL
;
2785 RETURN_IF_ERROR (result_append (dm
, "std"));
2786 *special_std_substitution
= 1;
2790 RETURN_IF_ERROR (result_append (dm
, "std::allocator"));
2791 new_last_source_name
= "allocator";
2796 RETURN_IF_ERROR (result_append (dm
, "std::basic_string"));
2797 new_last_source_name
= "basic_string";
2804 RETURN_IF_ERROR (result_append (dm
, "std::string"));
2805 new_last_source_name
= "string";
2809 RETURN_IF_ERROR (result_append (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
2810 new_last_source_name
= "basic_string";
2818 RETURN_IF_ERROR (result_append (dm
, "std::istream"));
2819 new_last_source_name
= "istream";
2823 RETURN_IF_ERROR (result_append (dm
, "std::basic_istream<char, std::char_traints<char> >"));
2824 new_last_source_name
= "basic_istream";
2832 RETURN_IF_ERROR (result_append (dm
, "std::ostream"));
2833 new_last_source_name
= "ostream";
2837 RETURN_IF_ERROR (result_append (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
2838 new_last_source_name
= "basic_ostream";
2846 RETURN_IF_ERROR (result_append (dm
, "std::iostream"));
2847 new_last_source_name
= "iostream";
2851 RETURN_IF_ERROR (result_append (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
2852 new_last_source_name
= "basic_iostream";
2858 return "Unrecognized <substitution>.";
2861 /* Consume the character we just processed. */
2864 if (new_last_source_name
!= NULL
)
2866 if (!dyn_string_copy_cstr (dm
->last_source_name
,
2867 new_last_source_name
))
2868 return STATUS_ALLOCATION_FAILED
;
2874 /* Look up the substitution text. Since `S_' is the most recent
2875 substitution, `S0_' is the second-most-recent, etc., shift the
2876 numbering by one. */
2877 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
2879 return "Substitution number out of range.";
2881 /* Emit the substitution text. */
2882 RETURN_IF_ERROR (result_append_string (dm
, text
));
2884 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2888 /* Demangles and emits a <local-name>.
2890 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2891 := Z <function encoding> E s [<discriminator>] */
2894 demangle_local_name (dm
)
2897 DEMANGLE_TRACE ("local-name", dm
);
2899 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
2900 RETURN_IF_ERROR (demangle_encoding (dm
));
2901 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2902 RETURN_IF_ERROR (result_append (dm
, "'s "));
2904 if (peek_char (dm
) == 's')
2906 /* Local character string literal. */
2907 RETURN_IF_ERROR (result_append (dm
, "string literal"));
2908 /* Consume the s. */
2910 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
2915 RETURN_IF_ERROR (result_append (dm
, "local "));
2916 /* Local name for some other entity. Demangle its name. */
2917 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
2918 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
2924 /* Optimonally demangles and emits a <discriminator>. If there is no
2925 <discriminator> at the current position in the mangled string, the
2926 descriminator is assumed to be zero. Emit the discriminator number
2927 in parentheses, unless SUPPRESS_FIRST is non-zero and the
2928 discriminator is zero.
2930 <discriminator> ::= _ <number> */
2933 demangle_discriminator (dm
, suppress_first
)
2937 /* Output for <discriminator>s to the demangled name is completely
2938 supressed if not in verbose mode. */
2940 if (peek_char (dm
) == '_')
2942 /* Consume the underscore. */
2945 RETURN_IF_ERROR (result_append (dm
, " [#"));
2946 /* Check if there's a number following the underscore. */
2947 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
2950 /* Demangle the number. */
2951 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
2953 /* Write the discriminator. The mangled number is two
2954 less than the discriminator ordinal, counting from
2956 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 2,
2957 (dyn_string_t
) dm
->result
));
2962 /* A missing digit correspond to one. */
2963 RETURN_IF_ERROR (result_append_char (dm
, '1'));
2966 RETURN_IF_ERROR (result_append_char (dm
, ']'));
2968 else if (!suppress_first
)
2971 RETURN_IF_ERROR (result_append (dm
, " [#0]"));
2977 /* Demangle NAME into RESULT, which must be an initialized
2978 dyn_string_t. On success, returns STATUS_OK. On failure, returns
2979 an error message, and the contents of RESULT are unchanged. */
2982 cp_demangle (name
, result
)
2984 dyn_string_t result
;
2987 int length
= strlen (name
);
2989 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
2991 demangling_t dm
= demangling_new (name
);
2993 return STATUS_ALLOCATION_FAILED
;
2995 status
= result_push (dm
);
2996 if (status
!= STATUS_OK
)
2998 demangling_delete (dm
);
3002 status
= demangle_mangled_name (dm
);
3003 if (STATUS_NO_ERROR (status
))
3005 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3006 if (!dyn_string_copy (result
, demangled
))
3007 return STATUS_ALLOCATION_FAILED
;
3008 dyn_string_delete (demangled
);
3011 demangling_delete (dm
);
3015 /* It's evidently not a mangled C++ name. It could be the name
3016 of something with C linkage, though, so just copy NAME into
3018 if (!dyn_string_copy_cstr (result
, name
))
3019 return STATUS_ALLOCATION_FAILED
;
3026 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3027 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3028 an error message, and the contents of RESULT are unchanged. */
3032 cp_demangle_type (type_name
, result
)
3033 const char* type_name
;
3034 dyn_string_t result
;
3037 demangling_t dm
= demangling_new (type_name
);
3040 return STATUS_ALLOCATION_FAILED
;
3042 /* Demangle the type name. The demangled name is stored in dm. */
3043 status
= result_push (dm
);
3044 if (status
!= STATUS_OK
)
3046 demangling_delete (dm
);
3050 status
= demangle_type (dm
);
3052 if (STATUS_NO_ERROR (status
))
3054 /* The demangling succeeded. Pop the result out of dm and copy
3056 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3057 if (!dyn_string_copy (result
, demangled
))
3058 return STATUS_ALLOCATION_FAILED
;
3059 dyn_string_delete (demangled
);
3063 demangling_delete (dm
);
3068 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3070 /* ABI-mandated entry point in the C++ runtime library for performing
3071 demangling. MANGLED_NAME is a NUL-terminated character string
3072 containing the name to be demangled.
3074 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3075 *LENGTH bytes, into which the demangled name is stored. If
3076 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3077 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3078 is placed in a region of memory allocated with malloc.
3080 If LENGTH is non-NULL, the length of the buffer conaining the
3081 demangled name, is placed in *LENGTH.
3083 The return value is a pointer to the start of the NUL-terminated
3084 demangled name, or NULL if the demangling fails. The caller is
3085 responsible for deallocating this memory using free.
3087 *STATUS is set to one of the following values:
3088 0: The demangling operation succeeded.
3089 -1: A memory allocation failiure occurred.
3090 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3091 -3: One of the arguments is invalid.
3093 The demagling is performed using the C++ ABI mangling rules, with
3097 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3098 const char *mangled_name
;
3099 char *output_buffer
;
3103 struct dyn_string demangled_name
;
3109 if (mangled_name
== NULL
) {
3114 /* Did the caller provide a buffer for the demangled name? */
3115 if (output_buffer
== NULL
) {
3116 /* No; dyn_string will malloc a buffer for us. */
3117 if (!dyn_string_init (&demangled_name
, 0))
3124 /* Yes. Check that the length was provided. */
3125 if (length
== NULL
) {
3129 /* Install the buffer into a dyn_string. */
3130 demangled_name
.allocated
= *length
;
3131 demangled_name
.length
= 0;
3132 demangled_name
.s
= output_buffer
;
3135 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3136 /* MANGLED_NAME apprears to be a function or variable name.
3137 Demangle it accordingly. */
3138 result
= cp_demangle (mangled_name
, &demangled_name
);
3140 /* Try to demangled MANGLED_NAME as the name of a type. */
3141 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3143 if (result
== STATUS_OK
)
3144 /* The demangling succeeded. */
3146 /* If LENGTH isn't NULL, store the allocated buffer length
3147 there; the buffer may have been realloced by dyn_string
3150 *length
= demangled_name
.allocated
;
3151 /* The operation was a success. */
3153 return dyn_string_buf (&demangled_name
);
3155 else if (result
== STATUS_ALLOCATION_FAILED
)
3156 /* A call to malloc or realloc failed during the demangling
3163 /* The demangling failed for another reason, most probably because
3164 MANGLED_NAME isn't a valid mangled name. */
3166 /* If the buffer containing the demangled name wasn't provided
3167 by the caller, free it. */
3168 if (output_buffer
== NULL
)
3169 free (dyn_string_buf (&demangled_name
));
3175 #else /* !IN_LIBGCC2 */
3177 /* Variant entry point for integration with the existing cplus-dem
3178 demangler. Attempts to demangle MANGLED. If the demangling
3179 succeeds, returns a buffer, allocated with malloc, containing the
3180 demangled name. The caller must deallocate the buffer using free.
3181 If the demangling failes, returns NULL. */
3184 cplus_demangle_new_abi (mangled
)
3185 const char* mangled
;
3187 /* Create a dyn_string to hold the demangled name. */
3188 dyn_string_t demangled
= dyn_string_new (0);
3189 /* Attempt the demangling. */
3190 status_t status
= cp_demangle ((char *) mangled
, demangled
);
3191 if (STATUS_NO_ERROR (status
))
3192 /* Demangling succeeded. */
3194 /* Grab the demangled result from the dyn_string. It was
3195 allocated with malloc, so we can return it directly. */
3196 char *return_value
= dyn_string_release (demangled
);
3197 /* Hand back the demangled name. */
3198 return return_value
;
3200 else if (status
== STATUS_ALLOCATION_FAILED
)
3202 fprintf (stderr
, "Memory allocation failed.\n");
3206 /* Demangling failed. */
3208 dyn_string_delete (demangled
);
3213 #endif /* IN_LIBGCC2 */
3215 #ifdef STANDALONE_DEMANGLER
3219 static void print_usage
3220 PARAMS ((FILE* fp
, int exit_value
));
3222 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3223 #define is_mangled_char(CHAR) \
3224 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) || (CHAR) == '_')
3226 /* The name of this program, as invoked. */
3227 const char* program_name
;
3229 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3232 print_usage (fp
, exit_value
)
3236 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3237 fprintf (fp
, "Options:\n", program_name
);
3238 fprintf (fp
, " -h,--help Display this message.\n");
3239 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3240 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3241 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3246 /* Option specification for getopt_long. */
3247 static struct option long_options
[] =
3249 { "help", no_argument
, NULL
, 'h' },
3250 { "strict", no_argument
, NULL
, 's' },
3251 { "verbose", no_argument
, NULL
, 'v' },
3252 { NULL
, no_argument
, NULL
, 0 },
3255 /* Main entry for a demangling filter executable. It will demangle
3256 its command line arguments, if any. If none are provided, it will
3257 filter stdin to stdout, replacing any recognized mangled C++ names
3258 with their demangled equivalents. */
3269 /* Use the program name of this program, as invoked. */
3270 program_name
= argv
[0];
3272 /* Parse options. */
3275 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
3278 case '?': /* Unrecognized option. */
3279 print_usage (stderr
, 1);
3283 print_usage (stdout
, 0);
3295 while (opt_char
!= -1);
3298 /* No command line arguments were provided. Filter stdin. */
3300 dyn_string_t mangled
= dyn_string_new (3);
3301 dyn_string_t demangled
= dyn_string_new (0);
3304 /* Read all of input. */
3305 while (!feof (stdin
))
3307 char c
= getchar ();
3309 /* The first character of a mangled name is an underscore. */
3314 /* It's not a mangled name. Print the character and go
3321 /* The second character of a mangled name is a capital `Z'. */
3326 /* It's not a mangled name. Print the previous
3327 underscore, the `Z', and go on. */
3333 /* Start keeping track of the candidate mangled name. */
3334 dyn_string_append_char (mangled
, '_');
3335 dyn_string_append_char (mangled
, 'Z');
3337 /* Pile characters into mangled until we hit one that can't
3338 occur in a mangled name. */
3340 while (!feof (stdin
) && is_mangled_char (c
))
3342 dyn_string_append_char (mangled
, c
);
3348 /* Attempt to demangle the name. */
3349 status
= cp_demangle (dyn_string_buf (mangled
), demangled
);
3351 /* If the demangling succeeded, great! Print out the
3352 demangled version. */
3353 if (STATUS_NO_ERROR (status
))
3354 fputs (dyn_string_buf (demangled
), stdout
);
3355 /* Abort on allocation failures. */
3356 else if (status
== STATUS_ALLOCATION_FAILED
)
3358 fprintf (stderr
, "Memory allocation failed.\n");
3361 /* Otherwise, it might not have been a mangled name. Just
3362 print out the original text. */
3364 fputs (dyn_string_buf (mangled
), stdout
);
3366 /* If we haven't hit EOF yet, we've read one character that
3367 can't occur in a mangled name, so print it out. */
3371 /* Clear the candidate mangled name, to start afresh next
3372 time we hit a `_Z'. */
3373 dyn_string_clear (mangled
);
3376 dyn_string_delete (mangled
);
3377 dyn_string_delete (demangled
);
3380 /* Demangle command line arguments. */
3382 dyn_string_t result
= dyn_string_new (0);
3384 /* Loop over command line arguments. */
3385 for (i
= optind
; i
< argc
; ++i
)
3387 /* Attempt to demangle. */
3388 status
= cp_demangle (argv
[i
], result
);
3390 /* If it worked, print the demangled name. */
3391 if (STATUS_NO_ERROR (status
))
3392 printf ("%s\n", dyn_string_buf (result
));
3393 /* Abort on allocaiton failures. */
3394 else if (status
== STATUS_ALLOCATION_FAILED
)
3396 fprintf (stderr
, "Memory allocaiton failed.\n");
3399 /* If not, print the error message to stderr instead. */
3401 fprintf (stderr
, "%s\n", status
);
3403 dyn_string_delete (result
);
3409 #endif /* STANDALONE_DEMANGLER */