1 /* Demangler for IA64 / g++ V3 ABI.
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Alex Samuel <samuel@codesourcery.com>.
5 This file is part of GNU CC.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 In addition to the permissions in the GNU General Public License, the
13 Free Software Foundation gives you unlimited permission to link the
14 compiled version of this file into combinations with other programs,
15 and to distribute those combinations without any restriction coming
16 from the use of this file. (The General Public License restrictions
17 do apply in other respects; for example, they cover modification of
18 the file, and distribution when not linked into a combined
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 /* This file implements demangling of C++ names mangled according to
32 the IA64 / g++ V3 ABI. Use the cp_demangle function to
33 demangle a mangled name, or compile with the preprocessor macro
34 STANDALONE_DEMANGLER defined to create a demangling filter
35 executable (functionally similar to c++filt, but includes this
42 #include <sys/types.h>
55 #include "libiberty.h"
56 #include "dyn-string.h"
59 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
60 and other debugging output, will be generated. */
61 #ifdef CP_DEMANGLE_DEBUG
62 #define DEMANGLE_TRACE(PRODUCTION, DM) \
63 fprintf (stderr, " -> %-24s at position %3d\n", \
64 (PRODUCTION), current_position (DM));
66 #define DEMANGLE_TRACE(PRODUCTION, DM)
69 /* Don't include <ctype.h>, to prevent additional unresolved symbols
70 from being dragged into the C++ runtime library. */
71 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
72 #define IS_ALPHA(CHAR) \
73 (((CHAR) >= 'a' && (CHAR) <= 'z') \
74 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
76 /* The prefix prepended by GCC to an identifier represnting the
77 anonymous namespace. */
78 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
80 /* Character(s) to use for namespace separation in demangled output */
81 #define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
83 /* If flag_verbose is zero, some simplifications will be made to the
84 output to make it easier to read and supress details that are
85 generally not of interest to the average C++ programmer.
86 Otherwise, the demangled representation will attempt to convey as
87 much information as the mangled form. */
88 static int flag_verbose
;
90 /* If flag_strict is non-zero, demangle strictly according to the
91 specification -- don't demangle special g++ manglings. */
92 static int flag_strict
;
94 /* String_list_t is an extended form of dyn_string_t which provides a
95 link field and a caret position for additions to the string. A
96 string_list_t may safely be cast to and used as a dyn_string_t. */
98 struct string_list_def
100 /* The dyn_string; must be first. */
101 struct dyn_string string
;
103 /* The position at which additional text is added to this string
104 (using the result_add* macros). This value is an offset from the
105 end of the string, not the beginning (and should be
109 /* The next string in the list. */
110 struct string_list_def
*next
;
113 typedef struct string_list_def
*string_list_t
;
115 /* Data structure representing a potential substitution. */
117 struct substitution_def
119 /* The demangled text of the substitution. */
122 /* Whether this substitution represents a template item. */
126 /* Data structure representing a template argument list. */
128 struct template_arg_list_def
130 /* The next (lower) template argument list in the stack of currently
131 active template arguments. */
132 struct template_arg_list_def
*next
;
134 /* The first element in the list of template arguments in
135 left-to-right order. */
136 string_list_t first_argument
;
138 /* The last element in the arguments lists. */
139 string_list_t last_argument
;
142 typedef struct template_arg_list_def
*template_arg_list_t
;
144 /* Data structure to maintain the state of the current demangling. */
146 struct demangling_def
148 /* The full mangled name being mangled. */
151 /* Pointer into name at the current position. */
154 /* Stack for strings containing demangled result generated so far.
155 Text is emitted to the topmost (first) string. */
156 string_list_t result
;
158 /* The number of presently available substitutions. */
159 int num_substitutions
;
161 /* The allocated size of the substitutions array. */
162 int substitutions_allocated
;
164 /* An array of available substitutions. The number of elements in
165 the array is given by num_substitions, and the allocated array
166 size in substitutions_size.
168 The most recent substition is at the end, so
170 - `S_' corresponds to substititutions[num_substitutions - 1]
171 - `S0_' corresponds to substititutions[num_substitutions - 2]
174 struct substitution_def
*substitutions
;
176 /* The stack of template argument lists. */
177 template_arg_list_t template_arg_lists
;
179 /* The most recently demangled source-name. */
180 dyn_string_t last_source_name
;
182 /* Language style to use for demangled output. */
185 /* Set to non-zero iff this name is a constructor. The actual value
186 indicates what sort of constructor this is; see demangle.h. */
187 enum gnu_v3_ctor_kinds is_constructor
;
189 /* Set to non-zero iff this name is a destructor. The actual value
190 indicates what sort of destructor this is; see demangle.h. */
191 enum gnu_v3_dtor_kinds is_destructor
;
195 typedef struct demangling_def
*demangling_t
;
197 /* This type is the standard return code from most functions. Values
198 other than STATUS_OK contain descriptive messages. */
199 typedef const char *status_t
;
201 /* Special values that can be used as a status_t. */
202 #define STATUS_OK NULL
203 #define STATUS_ERROR "Error."
204 #define STATUS_UNIMPLEMENTED "Unimplemented."
205 #define STATUS_INTERNAL_ERROR "Internal error."
207 /* This status code indicates a failure in malloc or realloc. */
208 static const char *const status_allocation_failed
= "Allocation failed.";
209 #define STATUS_ALLOCATION_FAILED status_allocation_failed
211 /* Non-zero if STATUS indicates that no error has occurred. */
212 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
214 /* Evaluate EXPR, which must produce a status_t. If the status code
215 indicates an error, return from the current function with that
217 #define RETURN_IF_ERROR(EXPR) \
221 if (!STATUS_NO_ERROR (s)) \
226 static status_t int_to_dyn_string
227 PARAMS ((int, dyn_string_t
));
228 static string_list_t string_list_new
230 static void string_list_delete
231 PARAMS ((string_list_t
));
232 static status_t result_add_separated_char
233 PARAMS ((demangling_t
, int));
234 static status_t result_push
235 PARAMS ((demangling_t
));
236 static string_list_t result_pop
237 PARAMS ((demangling_t
));
238 static int substitution_start
239 PARAMS ((demangling_t
));
240 static status_t substitution_add
241 PARAMS ((demangling_t
, int, int));
242 static dyn_string_t substitution_get
243 PARAMS ((demangling_t
, int, int *));
244 #ifdef CP_DEMANGLE_DEBUG
245 static void substitutions_print
246 PARAMS ((demangling_t
, FILE *));
248 static template_arg_list_t template_arg_list_new
250 static void template_arg_list_delete
251 PARAMS ((template_arg_list_t
));
252 static void template_arg_list_add_arg
253 PARAMS ((template_arg_list_t
, string_list_t
));
254 static string_list_t template_arg_list_get_arg
255 PARAMS ((template_arg_list_t
, int));
256 static void push_template_arg_list
257 PARAMS ((demangling_t
, template_arg_list_t
));
258 static void pop_to_template_arg_list
259 PARAMS ((demangling_t
, template_arg_list_t
));
260 #ifdef CP_DEMANGLE_DEBUG
261 static void template_arg_list_print
262 PARAMS ((template_arg_list_t
, FILE *));
264 static template_arg_list_t current_template_arg_list
265 PARAMS ((demangling_t
));
266 static demangling_t demangling_new
267 PARAMS ((const char *, int));
268 static void demangling_delete
269 PARAMS ((demangling_t
));
271 /* The last character of DS. Warning: DS is evaluated twice. */
272 #define dyn_string_last_char(DS) \
273 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
275 /* Append a space character (` ') to DS if it does not already end
276 with one. Evaluates to 1 on success, or 0 on allocation failure. */
277 #define dyn_string_append_space(DS) \
278 ((dyn_string_length (DS) > 0 \
279 && dyn_string_last_char (DS) != ' ') \
280 ? dyn_string_append_char ((DS), ' ') \
283 /* Returns the index of the current position in the mangled name. */
284 #define current_position(DM) ((DM)->next - (DM)->name)
286 /* Returns the character at the current position of the mangled name. */
287 #define peek_char(DM) (*((DM)->next))
289 /* Returns the character one past the current position of the mangled
291 #define peek_char_next(DM) \
292 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
294 /* Returns the character at the current position, and advances the
295 current position to the next character. */
296 #define next_char(DM) (*((DM)->next)++)
298 /* Returns non-zero if the current position is the end of the mangled
299 name, i.e. one past the last character. */
300 #define end_of_name_p(DM) (peek_char (DM) == '\0')
302 /* Advances the current position by one character. */
303 #define advance_char(DM) (++(DM)->next)
305 /* Returns the string containing the current demangled result. */
306 #define result_string(DM) (&(DM)->result->string)
308 /* Returns the position at which new text is inserted into the
310 #define result_caret_pos(DM) \
311 (result_length (DM) + \
312 ((string_list_t) result_string (DM))->caret_position)
314 /* Adds a dyn_string_t to the demangled result. */
315 #define result_add_string(DM, STRING) \
316 (dyn_string_insert (&(DM)->result->string, \
317 result_caret_pos (DM), (STRING)) \
318 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
320 /* Adds NUL-terminated string CSTR to the demangled result. */
321 #define result_add(DM, CSTR) \
322 (dyn_string_insert_cstr (&(DM)->result->string, \
323 result_caret_pos (DM), (CSTR)) \
324 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
326 /* Adds character CHAR to the demangled result. */
327 #define result_add_char(DM, CHAR) \
328 (dyn_string_insert_char (&(DM)->result->string, \
329 result_caret_pos (DM), (CHAR)) \
330 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
332 /* Inserts a dyn_string_t to the demangled result at position POS. */
333 #define result_insert_string(DM, POS, STRING) \
334 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
335 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
337 /* Inserts NUL-terminated string CSTR to the demangled result at
339 #define result_insert(DM, POS, CSTR) \
340 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
341 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
343 /* Inserts character CHAR to the demangled result at position POS. */
344 #define result_insert_char(DM, POS, CHAR) \
345 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
346 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
348 /* The length of the current demangled result. */
349 #define result_length(DM) \
350 dyn_string_length (&(DM)->result->string)
352 /* Appends a (less-than, greater-than) character to the result in DM
353 to (open, close) a template argument or parameter list. Appends a
354 space first if necessary to prevent spurious elision of angle
355 brackets with the previous character. */
356 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
357 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
359 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
360 success. On failure, deletes DS and returns an error code. */
363 int_to_dyn_string (value
, ds
)
370 /* Handle zero up front. */
373 if (!dyn_string_append_char (ds
, '0'))
374 return STATUS_ALLOCATION_FAILED
;
378 /* For negative numbers, emit a minus sign. */
381 if (!dyn_string_append_char (ds
, '-'))
382 return STATUS_ALLOCATION_FAILED
;
386 /* Find the power of 10 of the first digit. */
394 /* Write the digits. */
397 int digit
= value
/ mask
;
399 if (!dyn_string_append_char (ds
, '0' + digit
))
400 return STATUS_ALLOCATION_FAILED
;
402 value
-= digit
* mask
;
409 /* Creates a new string list node. The contents of the string are
410 empty, but the initial buffer allocation is LENGTH. The string
411 list node should be deleted with string_list_delete. Returns NULL
412 if allocation fails. */
415 string_list_new (length
)
418 string_list_t s
= (string_list_t
) malloc (sizeof (struct string_list_def
));
419 s
->caret_position
= 0;
422 if (!dyn_string_init ((dyn_string_t
) s
, length
))
427 /* Deletes the entire string list starting at NODE. */
430 string_list_delete (node
)
435 string_list_t next
= node
->next
;
436 dyn_string_delete ((dyn_string_t
) node
);
441 /* Appends CHARACTER to the demangled result. If the current trailing
442 character of the result is CHARACTER, a space is inserted first. */
445 result_add_separated_char (dm
, character
)
449 char *result
= dyn_string_buf (result_string (dm
));
450 int caret_pos
= result_caret_pos (dm
);
452 /* Add a space if the last character is already the character we
454 if (caret_pos
> 0 && result
[caret_pos
- 1] == character
)
455 RETURN_IF_ERROR (result_add_char (dm
, ' '));
456 /* Add the character. */
457 RETURN_IF_ERROR (result_add_char (dm
, character
));
462 /* Allocates and pushes a new string onto the demangled results stack
463 for DM. Subsequent demangling with DM will emit to the new string.
464 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
465 allocation failure. */
471 string_list_t new_string
= string_list_new (0);
472 if (new_string
== NULL
)
473 /* Allocation failed. */
474 return STATUS_ALLOCATION_FAILED
;
476 /* Link the new string to the front of the list of result strings. */
477 new_string
->next
= (string_list_t
) dm
->result
;
478 dm
->result
= new_string
;
482 /* Removes and returns the topmost element on the demangled results
483 stack for DM. The caller assumes ownership for the returned
490 string_list_t top
= dm
->result
;
491 dm
->result
= top
->next
;
495 /* Returns the current value of the caret for the result string. The
496 value is an offet from the end of the result string. */
499 result_get_caret (dm
)
502 return ((string_list_t
) result_string (dm
))->caret_position
;
505 /* Sets the value of the caret for the result string, counted as an
506 offet from the end of the result string. */
509 result_set_caret (dm
, position
)
513 ((string_list_t
) result_string (dm
))->caret_position
= position
;
516 /* Shifts the position of the next addition to the result by
517 POSITION_OFFSET. A negative value shifts the caret to the left. */
520 result_shift_caret (dm
, position_offset
)
524 ((string_list_t
) result_string (dm
))->caret_position
+= position_offset
;
527 /* Returns non-zero if the character that comes right before the place
528 where text will be added to the result is a space. In this case,
529 the caller should supress adding another space. */
532 result_previous_char_is_space (dm
)
535 char *result
= dyn_string_buf (result_string (dm
));
536 int pos
= result_caret_pos (dm
);
537 return pos
> 0 && result
[pos
- 1] == ' ';
540 /* Returns the start position of a fragment of the demangled result
541 that will be a substitution candidate. Should be called at the
542 start of productions that can add substitutions. */
545 substitution_start (dm
)
548 return result_caret_pos (dm
);
551 /* Adds the suffix of the current demangled result of DM starting at
552 START_POSITION as a potential substitution. If TEMPLATE_P is
553 non-zero, this potential substitution is a template-id. */
556 substitution_add (dm
, start_position
, template_p
)
561 dyn_string_t result
= result_string (dm
);
562 dyn_string_t substitution
= dyn_string_new (0);
565 if (substitution
== NULL
)
566 return STATUS_ALLOCATION_FAILED
;
568 /* Extract the substring of the current demangling result that
569 represents the subsitution candidate. */
570 if (!dyn_string_substring (substitution
,
571 result
, start_position
, result_caret_pos (dm
)))
573 dyn_string_delete (substitution
);
574 return STATUS_ALLOCATION_FAILED
;
577 /* If there's no room for the new entry, grow the array. */
578 if (dm
->substitutions_allocated
== dm
->num_substitutions
)
580 size_t new_array_size
;
581 if (dm
->substitutions_allocated
> 0)
582 dm
->substitutions_allocated
*= 2;
584 dm
->substitutions_allocated
= 2;
586 sizeof (struct substitution_def
) * dm
->substitutions_allocated
;
588 dm
->substitutions
= (struct substitution_def
*)
589 realloc (dm
->substitutions
, new_array_size
);
590 if (dm
->substitutions
== NULL
)
591 /* Realloc failed. */
593 dyn_string_delete (substitution
);
594 return STATUS_ALLOCATION_FAILED
;
598 /* Add the substitution to the array. */
599 i
= dm
->num_substitutions
++;
600 dm
->substitutions
[i
].text
= substitution
;
601 dm
->substitutions
[i
].template_p
= template_p
;
603 #ifdef CP_DEMANGLE_DEBUG
604 substitutions_print (dm
, stderr
);
610 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
611 non-zero if the substitution is a template-id, zero otherwise.
612 N is numbered from zero. DM retains ownership of the returned
613 string. If N is negative, or equal to or greater than the current
614 number of substitution candidates, returns NULL. */
617 substitution_get (dm
, n
, template_p
)
622 struct substitution_def
*sub
;
624 /* Make sure N is in the valid range. */
625 if (n
< 0 || n
>= dm
->num_substitutions
)
628 sub
= &(dm
->substitutions
[n
]);
629 *template_p
= sub
->template_p
;
633 #ifdef CP_DEMANGLE_DEBUG
634 /* Debugging routine to print the current substitutions to FP. */
637 substitutions_print (dm
, fp
)
642 int num
= dm
->num_substitutions
;
644 fprintf (fp
, "SUBSTITUTIONS:\n");
645 for (seq_id
= -1; seq_id
< num
- 1; ++seq_id
)
648 dyn_string_t text
= substitution_get (dm
, seq_id
+ 1, &template_p
);
651 fprintf (fp
, " S_ ");
653 fprintf (fp
, " S%d_", seq_id
);
654 fprintf (fp
, " %c: %s\n", template_p
? '*' : ' ', dyn_string_buf (text
));
658 #endif /* CP_DEMANGLE_DEBUG */
660 /* Creates a new template argument list. Returns NULL if allocation
663 static template_arg_list_t
664 template_arg_list_new ()
666 template_arg_list_t new_list
=
667 (template_arg_list_t
) malloc (sizeof (struct template_arg_list_def
));
668 if (new_list
== NULL
)
670 /* Initialize the new list to have no arguments. */
671 new_list
->first_argument
= NULL
;
672 new_list
->last_argument
= NULL
;
673 /* Return the new list. */
677 /* Deletes a template argument list and the template arguments it
681 template_arg_list_delete (list
)
682 template_arg_list_t list
;
684 /* If there are any arguments on LIST, delete them. */
685 if (list
->first_argument
!= NULL
)
686 string_list_delete (list
->first_argument
);
691 /* Adds ARG to the template argument list ARG_LIST. */
694 template_arg_list_add_arg (arg_list
, arg
)
695 template_arg_list_t arg_list
;
698 if (arg_list
->first_argument
== NULL
)
699 /* If there were no arguments before, ARG is the first one. */
700 arg_list
->first_argument
= arg
;
702 /* Make ARG the last argument on the list. */
703 arg_list
->last_argument
->next
= arg
;
704 /* Make ARG the last on the list. */
705 arg_list
->last_argument
= arg
;
709 /* Returns the template arugment at position INDEX in template
710 argument list ARG_LIST. */
713 template_arg_list_get_arg (arg_list
, index
)
714 template_arg_list_t arg_list
;
717 string_list_t arg
= arg_list
->first_argument
;
718 /* Scan down the list of arguments to find the one at position
724 /* Ran out of arguments before INDEX hit zero. That's an
728 /* Return the argument at position INDEX. */
732 /* Pushes ARG_LIST onto the top of the template argument list stack. */
735 push_template_arg_list (dm
, arg_list
)
737 template_arg_list_t arg_list
;
739 arg_list
->next
= dm
->template_arg_lists
;
740 dm
->template_arg_lists
= arg_list
;
741 #ifdef CP_DEMANGLE_DEBUG
742 fprintf (stderr
, " ** pushing template arg list\n");
743 template_arg_list_print (arg_list
, stderr
);
747 /* Pops and deletes elements on the template argument list stack until
748 arg_list is the topmost element. If arg_list is NULL, all elements
749 are popped and deleted. */
752 pop_to_template_arg_list (dm
, arg_list
)
754 template_arg_list_t arg_list
;
756 while (dm
->template_arg_lists
!= arg_list
)
758 template_arg_list_t top
= dm
->template_arg_lists
;
759 /* Disconnect the topmost element from the list. */
760 dm
->template_arg_lists
= top
->next
;
761 /* Delete the popped element. */
762 template_arg_list_delete (top
);
763 #ifdef CP_DEMANGLE_DEBUG
764 fprintf (stderr
, " ** removing template arg list\n");
769 #ifdef CP_DEMANGLE_DEBUG
771 /* Prints the contents of ARG_LIST to FP. */
774 template_arg_list_print (arg_list
, fp
)
775 template_arg_list_t arg_list
;
781 fprintf (fp
, "TEMPLATE ARGUMENT LIST:\n");
782 for (arg
= arg_list
->first_argument
; arg
!= NULL
; arg
= arg
->next
)
785 fprintf (fp
, " T_ : ");
787 fprintf (fp
, " T%d_ : ", index
);
789 fprintf (fp
, "%s\n", dyn_string_buf ((dyn_string_t
) arg
));
793 #endif /* CP_DEMANGLE_DEBUG */
795 /* Returns the topmost element on the stack of template argument
796 lists. If there is no list of template arguments, returns NULL. */
798 static template_arg_list_t
799 current_template_arg_list (dm
)
802 return dm
->template_arg_lists
;
805 /* Allocates a demangling_t object for demangling mangled NAME. A new
806 result must be pushed before the returned object can be used.
807 Returns NULL if allocation fails. */
810 demangling_new (name
, style
)
815 dm
= (demangling_t
) malloc (sizeof (struct demangling_def
));
822 dm
->num_substitutions
= 0;
823 dm
->substitutions_allocated
= 10;
824 dm
->template_arg_lists
= NULL
;
825 dm
->last_source_name
= dyn_string_new (0);
826 if (dm
->last_source_name
== NULL
)
828 dm
->substitutions
= (struct substitution_def
*)
829 malloc (dm
->substitutions_allocated
* sizeof (struct substitution_def
));
830 if (dm
->substitutions
== NULL
)
832 dyn_string_delete (dm
->last_source_name
);
836 dm
->is_constructor
= 0;
837 dm
->is_destructor
= 0;
842 /* Deallocates a demangling_t object and all memory associated with
846 demangling_delete (dm
)
850 template_arg_list_t arg_list
= dm
->template_arg_lists
;
852 /* Delete the stack of template argument lists. */
853 while (arg_list
!= NULL
)
855 template_arg_list_t next
= arg_list
->next
;
856 template_arg_list_delete (arg_list
);
859 /* Delete the list of substitutions. */
860 for (i
= dm
->num_substitutions
; --i
>= 0; )
861 dyn_string_delete (dm
->substitutions
[i
].text
);
862 free (dm
->substitutions
);
863 /* Delete the demangled result. */
864 string_list_delete (dm
->result
);
865 /* Delete the stored identifier name. */
866 dyn_string_delete (dm
->last_source_name
);
867 /* Delete the context object itself. */
871 /* These functions demangle an alternative of the corresponding
872 production in the mangling spec. The first argument of each is a
873 demangling context structure for the current demangling
874 operation. Most emit demangled text directly to the topmost result
875 string on the result string stack in the demangling context
878 static status_t demangle_char
879 PARAMS ((demangling_t
, int));
880 static status_t demangle_mangled_name
881 PARAMS ((demangling_t
));
882 static status_t demangle_encoding
883 PARAMS ((demangling_t
));
884 static status_t demangle_name
885 PARAMS ((demangling_t
, int *));
886 static status_t demangle_nested_name
887 PARAMS ((demangling_t
, int *));
888 static status_t demangle_prefix
889 PARAMS ((demangling_t
, int *));
890 static status_t demangle_unqualified_name
891 PARAMS ((demangling_t
, int *));
892 static status_t demangle_source_name
893 PARAMS ((demangling_t
));
894 static status_t demangle_number
895 PARAMS ((demangling_t
, int *, int, int));
896 static status_t demangle_number_literally
897 PARAMS ((demangling_t
, dyn_string_t
, int, int));
898 static status_t demangle_identifier
899 PARAMS ((demangling_t
, int, dyn_string_t
));
900 static status_t demangle_operator_name
901 PARAMS ((demangling_t
, int, int *, int *));
902 static status_t demangle_nv_offset
903 PARAMS ((demangling_t
));
904 static status_t demangle_v_offset
905 PARAMS ((demangling_t
));
906 static status_t demangle_call_offset
907 PARAMS ((demangling_t
));
908 static status_t demangle_special_name
909 PARAMS ((demangling_t
));
910 static status_t demangle_ctor_dtor_name
911 PARAMS ((demangling_t
));
912 static status_t demangle_type_ptr
913 PARAMS ((demangling_t
, int *, int));
914 static status_t demangle_type
915 PARAMS ((demangling_t
));
916 static status_t demangle_CV_qualifiers
917 PARAMS ((demangling_t
, dyn_string_t
));
918 static status_t demangle_builtin_type
919 PARAMS ((demangling_t
));
920 static status_t demangle_function_type
921 PARAMS ((demangling_t
, int *));
922 static status_t demangle_bare_function_type
923 PARAMS ((demangling_t
, int *));
924 static status_t demangle_class_enum_type
925 PARAMS ((demangling_t
, int *));
926 static status_t demangle_array_type
927 PARAMS ((demangling_t
, int *));
928 static status_t demangle_template_param
929 PARAMS ((demangling_t
));
930 static status_t demangle_template_args
931 PARAMS ((demangling_t
));
932 static status_t demangle_literal
933 PARAMS ((demangling_t
));
934 static status_t demangle_template_arg
935 PARAMS ((demangling_t
));
936 static status_t demangle_expression
937 PARAMS ((demangling_t
));
938 static status_t demangle_scope_expression
939 PARAMS ((demangling_t
));
940 static status_t demangle_expr_primary
941 PARAMS ((demangling_t
));
942 static status_t demangle_substitution
943 PARAMS ((demangling_t
, int *));
944 static status_t demangle_local_name
945 PARAMS ((demangling_t
));
946 static status_t demangle_discriminator
947 PARAMS ((demangling_t
, int));
948 static status_t cp_demangle
949 PARAMS ((const char *, dyn_string_t
, int));
950 static status_t cp_demangle_type
951 PARAMS ((const char*, dyn_string_t
));
953 /* When passed to demangle_bare_function_type, indicates that the
954 function's return type is not encoded before its parameter types. */
955 #define BFT_NO_RETURN_TYPE NULL
957 /* Check that the next character is C. If so, consume it. If not,
961 demangle_char (dm
, c
)
965 static char *error_message
= NULL
;
967 if (peek_char (dm
) == c
)
974 if (error_message
== NULL
)
975 error_message
= strdup ("Expected ?");
976 error_message
[9] = c
;
977 return error_message
;
981 /* Demangles and emits a <mangled-name>.
983 <mangled-name> ::= _Z <encoding> */
986 demangle_mangled_name (dm
)
989 DEMANGLE_TRACE ("mangled-name", dm
);
990 RETURN_IF_ERROR (demangle_char (dm
, '_'));
991 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
992 RETURN_IF_ERROR (demangle_encoding (dm
));
996 /* Demangles and emits an <encoding>.
998 <encoding> ::= <function name> <bare-function-type>
1000 ::= <special-name> */
1003 demangle_encoding (dm
)
1006 int encode_return_type
;
1008 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
1009 char peek
= peek_char (dm
);
1011 DEMANGLE_TRACE ("encoding", dm
);
1013 /* Remember where the name starts. If it turns out to be a template
1014 function, we'll have to insert the return type here. */
1015 start_position
= result_caret_pos (dm
);
1017 if (peek
== 'G' || peek
== 'T')
1018 RETURN_IF_ERROR (demangle_special_name (dm
));
1021 /* Now demangle the name. */
1022 RETURN_IF_ERROR (demangle_name (dm
, &encode_return_type
));
1024 /* If there's anything left, the name was a function name, with
1025 maybe its return type, and its parameter types, following. */
1026 if (!end_of_name_p (dm
)
1027 && peek_char (dm
) != 'E')
1029 if (encode_return_type
)
1030 /* Template functions have their return type encoded. The
1031 return type should be inserted at start_position. */
1033 (demangle_bare_function_type (dm
, &start_position
));
1035 /* Non-template functions don't have their return type
1038 (demangle_bare_function_type (dm
, BFT_NO_RETURN_TYPE
));
1042 /* Pop off template argument lists that were built during the
1043 mangling of this name, to restore the old template context. */
1044 pop_to_template_arg_list (dm
, old_arg_list
);
1049 /* Demangles and emits a <name>.
1051 <name> ::= <unscoped-name>
1052 ::= <unscoped-template-name> <template-args>
1056 <unscoped-name> ::= <unqualified-name>
1057 ::= St <unqualified-name> # ::std::
1059 <unscoped-template-name>
1061 ::= <substitution> */
1064 demangle_name (dm
, encode_return_type
)
1066 int *encode_return_type
;
1068 int start
= substitution_start (dm
);
1069 char peek
= peek_char (dm
);
1070 int is_std_substitution
= 0;
1072 /* Generally, the return type is encoded if the function is a
1073 template-id, and suppressed otherwise. There are a few cases,
1074 though, in which the return type is not encoded even for a
1075 templated function. In these cases, this flag is set. */
1076 int suppress_return_type
= 0;
1078 DEMANGLE_TRACE ("name", dm
);
1083 /* This is a <nested-name>. */
1084 RETURN_IF_ERROR (demangle_nested_name (dm
, encode_return_type
));
1088 RETURN_IF_ERROR (demangle_local_name (dm
));
1089 *encode_return_type
= 0;
1093 /* The `St' substitution allows a name nested in std:: to appear
1094 without being enclosed in a nested name. */
1095 if (peek_char_next (dm
) == 't')
1097 (void) next_char (dm
);
1098 (void) next_char (dm
);
1099 RETURN_IF_ERROR (result_add (dm
, "std::"));
1101 (demangle_unqualified_name (dm
, &suppress_return_type
));
1102 is_std_substitution
= 1;
1105 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1106 /* Check if a template argument list immediately follows.
1107 If so, then we just demangled an <unqualified-template-name>. */
1108 if (peek_char (dm
) == 'I')
1110 /* A template name of the form std::<unqualified-name> is a
1111 substitution candidate. */
1112 if (is_std_substitution
)
1113 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1114 /* Demangle the <template-args> here. */
1115 RETURN_IF_ERROR (demangle_template_args (dm
));
1116 *encode_return_type
= !suppress_return_type
;
1119 *encode_return_type
= 0;
1124 /* This is an <unscoped-name> or <unscoped-template-name>. */
1125 RETURN_IF_ERROR (demangle_unqualified_name (dm
, &suppress_return_type
));
1127 /* If the <unqualified-name> is followed by template args, this
1128 is an <unscoped-template-name>. */
1129 if (peek_char (dm
) == 'I')
1131 /* Add a substitution for the unqualified template name. */
1132 RETURN_IF_ERROR (substitution_add (dm
, start
, 0));
1134 RETURN_IF_ERROR (demangle_template_args (dm
));
1135 *encode_return_type
= !suppress_return_type
;
1138 *encode_return_type
= 0;
1146 /* Demangles and emits a <nested-name>.
1148 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1151 demangle_nested_name (dm
, encode_return_type
)
1153 int *encode_return_type
;
1157 DEMANGLE_TRACE ("nested-name", dm
);
1159 RETURN_IF_ERROR (demangle_char (dm
, 'N'));
1161 peek
= peek_char (dm
);
1162 if (peek
== 'r' || peek
== 'V' || peek
== 'K')
1164 dyn_string_t cv_qualifiers
;
1167 /* Snarf up CV qualifiers. */
1168 cv_qualifiers
= dyn_string_new (24);
1169 if (cv_qualifiers
== NULL
)
1170 return STATUS_ALLOCATION_FAILED
;
1171 demangle_CV_qualifiers (dm
, cv_qualifiers
);
1173 /* Emit them, preceded by a space. */
1174 status
= result_add_char (dm
, ' ');
1175 if (STATUS_NO_ERROR (status
))
1176 status
= result_add_string (dm
, cv_qualifiers
);
1177 /* The CV qualifiers that occur in a <nested-name> will be
1178 qualifiers for member functions. These are placed at the end
1179 of the function. Therefore, shift the caret to the left by
1180 the length of the qualifiers, so other text is inserted
1181 before them and they stay at the end. */
1182 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
) - 1);
1184 dyn_string_delete (cv_qualifiers
);
1185 RETURN_IF_ERROR (status
);
1188 RETURN_IF_ERROR (demangle_prefix (dm
, encode_return_type
));
1189 /* No need to demangle the final <unqualified-name>; demangle_prefix
1191 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
1196 /* Demangles and emits a <prefix>.
1198 <prefix> ::= <prefix> <unqualified-name>
1199 ::= <template-prefix> <template-args>
1203 <template-prefix> ::= <prefix>
1204 ::= <substitution> */
1207 demangle_prefix (dm
, encode_return_type
)
1209 int *encode_return_type
;
1211 int start
= substitution_start (dm
);
1214 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1215 After <template-args>, it is set to non-zero; after everything
1216 else it is set to zero. */
1218 /* Generally, the return type is encoded if the function is a
1219 template-id, and suppressed otherwise. There are a few cases,
1220 though, in which the return type is not encoded even for a
1221 templated function. In these cases, this flag is set. */
1222 int suppress_return_type
= 0;
1224 DEMANGLE_TRACE ("prefix", dm
);
1230 if (end_of_name_p (dm
))
1231 return "Unexpected end of name in <compound-name>.";
1233 peek
= peek_char (dm
);
1235 /* We'll initialize suppress_return_type to false, and set it to true
1236 if we end up demangling a constructor name. However, make
1237 sure we're not actually about to demangle template arguments
1238 -- if so, this is the <template-args> following a
1239 <template-prefix>, so we'll want the previous flag value
1242 suppress_return_type
= 0;
1244 if (IS_DIGIT ((unsigned char) peek
)
1245 || (peek
>= 'a' && peek
<= 'z')
1246 || peek
== 'C' || peek
== 'D'
1249 /* We have another level of scope qualification. */
1251 RETURN_IF_ERROR (result_add (dm
, NAMESPACE_SEPARATOR
));
1256 /* The substitution determines whether this is a
1258 RETURN_IF_ERROR (demangle_substitution (dm
, encode_return_type
));
1261 /* It's just a name. */
1263 (demangle_unqualified_name (dm
, &suppress_return_type
));
1264 *encode_return_type
= 0;
1267 else if (peek
== 'Z')
1268 RETURN_IF_ERROR (demangle_local_name (dm
));
1269 else if (peek
== 'I')
1271 RETURN_IF_ERROR (demangle_template_args (dm
));
1273 /* Now we want to indicate to the caller that we've
1274 demangled template arguments, thus the prefix was a
1275 <template-prefix>. That's so that the caller knows to
1276 demangle the function's return type, if this turns out to
1277 be a function name. But, if it's a member template
1278 constructor or a templated conversion operator, report it
1279 as untemplated. Those never get encoded return types. */
1280 *encode_return_type
= !suppress_return_type
;
1282 else if (peek
== 'E')
1286 return "Unexpected character in <compound-name>.";
1289 && peek_char (dm
) != 'E')
1290 /* Add a new substitution for the prefix thus far. */
1291 RETURN_IF_ERROR (substitution_add (dm
, start
, *encode_return_type
));
1295 /* Demangles and emits an <unqualified-name>. If this
1296 <unqualified-name> is for a special function type that should never
1297 have its return type encoded (particularly, a constructor or
1298 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1301 <unqualified-name> ::= <operator-name>
1303 ::= <source-name> */
1306 demangle_unqualified_name (dm
, suppress_return_type
)
1308 int *suppress_return_type
;
1310 char peek
= peek_char (dm
);
1312 DEMANGLE_TRACE ("unqualified-name", dm
);
1314 /* By default, don't force suppression of the return type (though
1315 non-template functions still don't get a return type encoded). */
1316 *suppress_return_type
= 0;
1318 if (IS_DIGIT ((unsigned char) peek
))
1319 RETURN_IF_ERROR (demangle_source_name (dm
));
1320 else if (peek
>= 'a' && peek
<= 'z')
1324 /* Conversion operators never have a return type encoded. */
1325 if (peek
== 'c' && peek_char_next (dm
) == 'v')
1326 *suppress_return_type
= 1;
1328 RETURN_IF_ERROR (demangle_operator_name (dm
, 0, &num_args
, NULL
));
1330 else if (peek
== 'C' || peek
== 'D')
1332 /* Constructors never have a return type encoded. */
1334 *suppress_return_type
= 1;
1336 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm
));
1339 return "Unexpected character in <unqualified-name>.";
1344 /* Demangles and emits <source-name>.
1346 <source-name> ::= <length number> <identifier> */
1349 demangle_source_name (dm
)
1354 DEMANGLE_TRACE ("source-name", dm
);
1356 /* Decode the length of the identifier. */
1357 RETURN_IF_ERROR (demangle_number (dm
, &length
, 10, 0));
1359 return "Zero length in <source-name>.";
1361 /* Now the identifier itself. It's placed into last_source_name,
1362 where it can be used to build a constructor or destructor name. */
1363 RETURN_IF_ERROR (demangle_identifier (dm
, length
,
1364 dm
->last_source_name
));
1367 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
1372 /* Demangles a number, either a <number> or a <positive-number> at the
1373 current position, consuming all consecutive digit characters. Sets
1374 *VALUE to the resulting numberand returns STATUS_OK. The number is
1375 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1376 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1378 <number> ::= [n] <positive-number>
1380 <positive-number> ::= <decimal integer> */
1383 demangle_number (dm
, value
, base
, is_signed
)
1389 dyn_string_t number
= dyn_string_new (10);
1391 DEMANGLE_TRACE ("number", dm
);
1394 return STATUS_ALLOCATION_FAILED
;
1396 demangle_number_literally (dm
, number
, base
, is_signed
);
1397 *value
= strtol (dyn_string_buf (number
), NULL
, base
);
1398 dyn_string_delete (number
);
1403 /* Demangles a number at the current position. The digits (and minus
1404 sign, if present) that make up the number are appended to STR.
1405 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1406 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1407 accepted. Does not consume a trailing underscore or other
1408 terminating character. */
1411 demangle_number_literally (dm
, str
, base
, is_signed
)
1417 DEMANGLE_TRACE ("number*", dm
);
1419 if (base
!= 10 && base
!= 36)
1420 return STATUS_INTERNAL_ERROR
;
1422 /* An `n' denotes a negative number. */
1423 if (is_signed
&& peek_char (dm
) == 'n')
1425 /* Skip past the n. */
1427 /* The normal way to write a negative number is with a minus
1429 if (!dyn_string_append_char (str
, '-'))
1430 return STATUS_ALLOCATION_FAILED
;
1433 /* Loop until we hit a non-digit. */
1436 char peek
= peek_char (dm
);
1437 if (IS_DIGIT ((unsigned char) peek
)
1438 || (base
== 36 && peek
>= 'A' && peek
<= 'Z'))
1440 /* Accumulate digits. */
1441 if (!dyn_string_append_char (str
, next_char (dm
)))
1442 return STATUS_ALLOCATION_FAILED
;
1445 /* Not a digit? All done. */
1452 /* Demangles an identifier at the current position of LENGTH
1453 characters and places it in IDENTIFIER. */
1456 demangle_identifier (dm
, length
, identifier
)
1459 dyn_string_t identifier
;
1461 DEMANGLE_TRACE ("identifier", dm
);
1463 dyn_string_clear (identifier
);
1464 if (!dyn_string_resize (identifier
, length
))
1465 return STATUS_ALLOCATION_FAILED
;
1467 while (length
-- > 0)
1469 if (end_of_name_p (dm
))
1470 return "Unexpected end of name in <identifier>.";
1471 if (!dyn_string_append_char (identifier
, next_char (dm
)))
1472 return STATUS_ALLOCATION_FAILED
;
1475 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1476 followed by the source file name and some random characters.
1477 Unless we're in strict mode, decipher these names appropriately. */
1480 char *name
= dyn_string_buf (identifier
);
1481 int prefix_length
= strlen (ANONYMOUS_NAMESPACE_PREFIX
);
1483 /* Compare the first, fixed part. */
1484 if (strncmp (name
, ANONYMOUS_NAMESPACE_PREFIX
, prefix_length
) == 0)
1486 name
+= prefix_length
;
1487 /* The next character might be a period, an underscore, or
1488 dollar sign, depending on the target architecture's
1489 assembler's capabilities. After that comes an `N'. */
1490 if ((*name
== '.' || *name
== '_' || *name
== '$')
1491 && *(name
+ 1) == 'N')
1492 /* This looks like the anonymous namespace identifier.
1493 Replace it with something comprehensible. */
1494 dyn_string_copy_cstr (identifier
, "(anonymous namespace)");
1501 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1502 the short form is emitted; otherwise the full source form
1503 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1504 operands that the operator takes. If TYPE_ARG is non-NULL,
1505 *TYPE_ARG is set to 1 if the first argument is a type and 0
1556 ::= st # sizeof (a type)
1557 ::= sz # sizeof (an expression)
1558 ::= cv <type> # cast
1559 ::= v [0-9] <source-name> # vendor extended operator */
1562 demangle_operator_name (dm
, short_name
, num_args
, type_arg
)
1568 struct operator_code
1570 /* The mangled code for this operator. */
1571 const char *const code
;
1572 /* The source name of this operator. */
1573 const char *const name
;
1574 /* The number of arguments this operator takes. */
1578 static const struct operator_code operators
[] =
1589 { "da", " delete[]", 1 },
1591 { "dl", " delete" , 1 },
1599 { "lS", "<<=" , 2 },
1608 { "na", " new[]" , 1 },
1612 { "nw", " new" , 1 },
1618 { "pm", "->*" , 2 },
1624 { "rS", ">>=" , 2 },
1627 { "sz", " sizeof" , 1 }
1630 const int num_operators
=
1631 sizeof (operators
) / sizeof (struct operator_code
);
1633 int c0
= next_char (dm
);
1634 int c1
= next_char (dm
);
1635 const struct operator_code
* p1
= operators
;
1636 const struct operator_code
* p2
= operators
+ num_operators
;
1638 DEMANGLE_TRACE ("operator-name", dm
);
1640 /* Assume the first argument is not a type. */
1644 /* Is this a vendor-extended operator? */
1645 if (c0
== 'v' && IS_DIGIT (c1
))
1647 RETURN_IF_ERROR (result_add (dm
, "operator "));
1648 RETURN_IF_ERROR (demangle_source_name (dm
));
1653 /* Is this a conversion operator? */
1654 if (c0
== 'c' && c1
== 'v')
1656 RETURN_IF_ERROR (result_add (dm
, "operator "));
1657 /* Demangle the converted-to type. */
1658 RETURN_IF_ERROR (demangle_type (dm
));
1663 /* Is it the sizeof variant that takes a type? */
1664 if (c0
== 's' && c1
== 't')
1666 RETURN_IF_ERROR (result_add (dm
, " sizeof"));
1673 /* Perform a binary search for the operator code. */
1676 const struct operator_code
* p
= p1
+ (p2
- p1
) / 2;
1677 char match0
= p
->code
[0];
1678 char match1
= p
->code
[1];
1680 if (c0
== match0
&& c1
== match1
)
1684 RETURN_IF_ERROR (result_add (dm
, "operator"));
1685 RETURN_IF_ERROR (result_add (dm
, p
->name
));
1686 *num_args
= p
->num_args
;
1692 /* Couldn't find it. */
1693 return "Unknown code in <operator-name>.";
1696 if (c0
< match0
|| (c0
== match0
&& c1
< match1
))
1703 /* Demangles and omits an <nv-offset>.
1705 <nv-offset> ::= <offset number> # non-virtual base override */
1708 demangle_nv_offset (dm
)
1711 dyn_string_t number
;
1712 status_t status
= STATUS_OK
;
1714 DEMANGLE_TRACE ("h-offset", dm
);
1716 /* Demangle the offset. */
1717 number
= dyn_string_new (4);
1719 return STATUS_ALLOCATION_FAILED
;
1720 demangle_number_literally (dm
, number
, 10, 1);
1722 /* Don't display the offset unless in verbose mode. */
1725 status
= result_add (dm
, " [nv:");
1726 if (STATUS_NO_ERROR (status
))
1727 status
= result_add_string (dm
, number
);
1728 if (STATUS_NO_ERROR (status
))
1729 status
= result_add_char (dm
, ']');
1733 dyn_string_delete (number
);
1734 RETURN_IF_ERROR (status
);
1738 /* Demangles and emits a <v-offset>.
1740 <v-offset> ::= <offset number> _ <virtual offset number>
1741 # virtual base override, with vcall offset */
1744 demangle_v_offset (dm
)
1747 dyn_string_t number
;
1748 status_t status
= STATUS_OK
;
1750 DEMANGLE_TRACE ("v-offset", dm
);
1752 /* Demangle the offset. */
1753 number
= dyn_string_new (4);
1755 return STATUS_ALLOCATION_FAILED
;
1756 demangle_number_literally (dm
, number
, 10, 1);
1758 /* Don't display the offset unless in verbose mode. */
1761 status
= result_add (dm
, " [v:");
1762 if (STATUS_NO_ERROR (status
))
1763 status
= result_add_string (dm
, number
);
1764 if (STATUS_NO_ERROR (status
))
1765 result_add_char (dm
, ',');
1767 dyn_string_delete (number
);
1768 RETURN_IF_ERROR (status
);
1770 /* Demangle the separator. */
1771 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1773 /* Demangle the vcall offset. */
1774 number
= dyn_string_new (4);
1776 return STATUS_ALLOCATION_FAILED
;
1777 demangle_number_literally (dm
, number
, 10, 1);
1779 /* Don't display the vcall offset unless in verbose mode. */
1782 status
= result_add_string (dm
, number
);
1783 if (STATUS_NO_ERROR (status
))
1784 status
= result_add_char (dm
, ']');
1786 dyn_string_delete (number
);
1787 RETURN_IF_ERROR (status
);
1792 /* Demangles and emits a <call-offset>.
1794 <call-offset> ::= h <nv-offset> _
1795 ::= v <v-offset> _ */
1798 demangle_call_offset (dm
)
1801 DEMANGLE_TRACE ("call-offset", dm
);
1803 switch (peek_char (dm
))
1807 /* Demangle the offset. */
1808 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1809 /* Demangle the separator. */
1810 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1815 /* Demangle the offset. */
1816 RETURN_IF_ERROR (demangle_v_offset (dm
));
1817 /* Demangle the separator. */
1818 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1822 return "Unrecognized <call-offset>.";
1828 /* Demangles and emits a <special-name>.
1830 <special-name> ::= GV <object name> # Guard variable
1831 ::= TV <type> # virtual table
1833 ::= TI <type> # typeinfo structure
1834 ::= TS <type> # typeinfo name
1836 Other relevant productions include thunks:
1838 <special-name> ::= T <call-offset> <base encoding>
1839 # base is the nominal target function of thunk
1841 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1842 # base is the nominal target function of thunk
1843 # first call-offset is 'this' adjustment
1844 # second call-offset is result adjustment
1848 <call-offset> ::= h <nv-offset> _
1851 Also demangles the special g++ manglings,
1853 <special-name> ::= TC <type> <offset number> _ <base type>
1854 # construction vtable
1855 ::= TF <type> # typeinfo function (old ABI only)
1856 ::= TJ <type> # java Class structure */
1859 demangle_special_name (dm
)
1862 dyn_string_t number
;
1864 char peek
= peek_char (dm
);
1866 DEMANGLE_TRACE ("special-name", dm
);
1870 /* Consume the G. */
1872 switch (peek_char (dm
))
1875 /* A guard variable name. */
1877 RETURN_IF_ERROR (result_add (dm
, "guard variable for "));
1878 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1882 /* A reference temporary. */
1884 RETURN_IF_ERROR (result_add (dm
, "reference temporary for "));
1885 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
1889 return "Unrecognized <special-name>.";
1892 else if (peek
== 'T')
1894 status_t status
= STATUS_OK
;
1896 /* Other C++ implementation miscellania. Consume the T. */
1899 switch (peek_char (dm
))
1902 /* Virtual table. */
1904 RETURN_IF_ERROR (result_add (dm
, "vtable for "));
1905 RETURN_IF_ERROR (demangle_type (dm
));
1909 /* VTT structure. */
1911 RETURN_IF_ERROR (result_add (dm
, "VTT for "));
1912 RETURN_IF_ERROR (demangle_type (dm
));
1916 /* Typeinfo structure. */
1918 RETURN_IF_ERROR (result_add (dm
, "typeinfo for "));
1919 RETURN_IF_ERROR (demangle_type (dm
));
1923 /* Typeinfo function. Used only in old ABI with new mangling. */
1925 RETURN_IF_ERROR (result_add (dm
, "typeinfo fn for "));
1926 RETURN_IF_ERROR (demangle_type (dm
));
1930 /* Character string containing type name, used in typeinfo. */
1932 RETURN_IF_ERROR (result_add (dm
, "typeinfo name for "));
1933 RETURN_IF_ERROR (demangle_type (dm
));
1937 /* The java Class variable corresponding to a C++ class. */
1939 RETURN_IF_ERROR (result_add (dm
, "java Class for "));
1940 RETURN_IF_ERROR (demangle_type (dm
));
1944 /* Non-virtual thunk. */
1946 RETURN_IF_ERROR (result_add (dm
, "non-virtual thunk"));
1947 RETURN_IF_ERROR (demangle_nv_offset (dm
));
1948 /* Demangle the separator. */
1949 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1950 /* Demangle and emit the target name and function type. */
1951 RETURN_IF_ERROR (result_add (dm
, " to "));
1952 RETURN_IF_ERROR (demangle_encoding (dm
));
1956 /* Virtual thunk. */
1958 RETURN_IF_ERROR (result_add (dm
, "virtual thunk"));
1959 RETURN_IF_ERROR (demangle_v_offset (dm
));
1960 /* Demangle the separator. */
1961 RETURN_IF_ERROR (demangle_char (dm
, '_'));
1962 /* Demangle and emit the target function. */
1963 RETURN_IF_ERROR (result_add (dm
, " to "));
1964 RETURN_IF_ERROR (demangle_encoding (dm
));
1968 /* Covariant return thunk. */
1970 RETURN_IF_ERROR (result_add (dm
, "covariant return thunk"));
1971 RETURN_IF_ERROR (demangle_call_offset (dm
));
1972 RETURN_IF_ERROR (demangle_call_offset (dm
));
1973 /* Demangle and emit the target function. */
1974 RETURN_IF_ERROR (result_add (dm
, " to "));
1975 RETURN_IF_ERROR (demangle_encoding (dm
));
1979 /* TC is a special g++ mangling for a construction vtable. */
1982 dyn_string_t derived_type
;
1985 RETURN_IF_ERROR (result_add (dm
, "construction vtable for "));
1987 /* Demangle the derived type off to the side. */
1988 RETURN_IF_ERROR (result_push (dm
));
1989 RETURN_IF_ERROR (demangle_type (dm
));
1990 derived_type
= (dyn_string_t
) result_pop (dm
);
1992 /* Demangle the offset. */
1993 number
= dyn_string_new (4);
1996 dyn_string_delete (derived_type
);
1997 return STATUS_ALLOCATION_FAILED
;
1999 demangle_number_literally (dm
, number
, 10, 1);
2000 /* Demangle the underscore separator. */
2001 status
= demangle_char (dm
, '_');
2003 /* Demangle the base type. */
2004 if (STATUS_NO_ERROR (status
))
2005 status
= demangle_type (dm
);
2007 /* Emit the derived type. */
2008 if (STATUS_NO_ERROR (status
))
2009 status
= result_add (dm
, "-in-");
2010 if (STATUS_NO_ERROR (status
))
2011 status
= result_add_string (dm
, derived_type
);
2012 dyn_string_delete (derived_type
);
2014 /* Don't display the offset unless in verbose mode. */
2017 status
= result_add_char (dm
, ' ');
2018 if (STATUS_NO_ERROR (status
))
2019 result_add_string (dm
, number
);
2021 dyn_string_delete (number
);
2022 RETURN_IF_ERROR (status
);
2025 /* If flag_strict, fall through. */
2028 return "Unrecognized <special-name>.";
2032 return STATUS_ERROR
;
2037 /* Demangles and emits a <ctor-dtor-name>.
2040 ::= C1 # complete object (in-charge) ctor
2041 ::= C2 # base object (not-in-charge) ctor
2042 ::= C3 # complete object (in-charge) allocating ctor
2043 ::= D0 # deleting (in-charge) dtor
2044 ::= D1 # complete object (in-charge) dtor
2045 ::= D2 # base object (not-in-charge) dtor */
2048 demangle_ctor_dtor_name (dm
)
2051 static const char *const ctor_flavors
[] =
2057 static const char *const dtor_flavors
[] =
2059 "in-charge deleting",
2065 char peek
= peek_char (dm
);
2067 DEMANGLE_TRACE ("ctor-dtor-name", dm
);
2071 /* A constructor name. Consume the C. */
2073 flavor
= next_char (dm
);
2074 if (flavor
< '1' || flavor
> '3')
2075 return "Unrecognized constructor.";
2076 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2079 case '1': dm
->is_constructor
= gnu_v3_complete_object_ctor
;
2081 case '2': dm
->is_constructor
= gnu_v3_base_object_ctor
;
2083 case '3': dm
->is_constructor
= gnu_v3_complete_object_allocating_ctor
;
2086 /* Print the flavor of the constructor if in verbose mode. */
2089 RETURN_IF_ERROR (result_add (dm
, "["));
2090 RETURN_IF_ERROR (result_add (dm
, ctor_flavors
[flavor
- '1']));
2091 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2094 else if (peek
== 'D')
2096 /* A destructor name. Consume the D. */
2098 flavor
= next_char (dm
);
2099 if (flavor
< '0' || flavor
> '2')
2100 return "Unrecognized destructor.";
2101 RETURN_IF_ERROR (result_add_char (dm
, '~'));
2102 RETURN_IF_ERROR (result_add_string (dm
, dm
->last_source_name
));
2105 case '0': dm
->is_destructor
= gnu_v3_deleting_dtor
;
2107 case '1': dm
->is_destructor
= gnu_v3_complete_object_dtor
;
2109 case '2': dm
->is_destructor
= gnu_v3_base_object_dtor
;
2112 /* Print the flavor of the destructor if in verbose mode. */
2115 RETURN_IF_ERROR (result_add (dm
, " ["));
2116 RETURN_IF_ERROR (result_add (dm
, dtor_flavors
[flavor
- '0']));
2117 RETURN_IF_ERROR (result_add_char (dm
, ']'));
2121 return STATUS_ERROR
;
2126 /* Handle pointer, reference, and pointer-to-member cases for
2127 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2128 build a pointer/reference type. We snarf all these, plus the
2129 following <type>, all at once since we need to know whether we have
2130 a pointer to data or pointer to function to construct the right
2131 output syntax. C++'s pointer syntax is hairy.
2133 This function adds substitution candidates for every nested
2134 pointer/reference type it processes, including the outermost, final
2135 type, assuming the substitution starts at SUBSTITUTION_START in the
2136 demangling result. For example, if this function demangles
2137 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2138 `Foo**', in that order.
2140 *INSERT_POS is a quantity used internally, when this function calls
2141 itself recursively, to figure out where to insert pointer
2142 punctuation on the way up. On entry to this function, INSERT_POS
2143 should point to a temporary value, but that value need not be
2148 ::= <pointer-to-member-type>
2150 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2153 demangle_type_ptr (dm
, insert_pos
, substitution_start
)
2156 int substitution_start
;
2159 int is_substitution_candidate
= 1;
2161 DEMANGLE_TRACE ("type*", dm
);
2163 /* Scan forward, collecting pointers and references into symbols,
2164 until we hit something else. Then emit the type. */
2165 switch (peek_char (dm
))
2168 /* A pointer. Snarf the `P'. */
2170 /* Demangle the underlying type. */
2171 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2172 substitution_start
));
2173 /* Insert an asterisk where we're told to; it doesn't
2174 necessarily go at the end. If we're doing Java style output,
2175 there is no pointer symbol. */
2176 if (dm
->style
!= DMGL_JAVA
)
2177 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '*'));
2178 /* The next (outermost) pointer or reference character should go
2184 /* A reference. Snarf the `R'. */
2186 /* Demangle the underlying type. */
2187 RETURN_IF_ERROR (demangle_type_ptr (dm
, insert_pos
,
2188 substitution_start
));
2189 /* Insert an ampersand where we're told to; it doesn't
2190 necessarily go at the end. */
2191 RETURN_IF_ERROR (result_insert_char (dm
, *insert_pos
, '&'));
2192 /* The next (outermost) pointer or reference character should go
2199 /* A pointer-to-member. */
2200 dyn_string_t class_type
;
2205 /* Capture the type of which this is a pointer-to-member. */
2206 RETURN_IF_ERROR (result_push (dm
));
2207 RETURN_IF_ERROR (demangle_type (dm
));
2208 class_type
= (dyn_string_t
) result_pop (dm
);
2210 if (peek_char (dm
) == 'F')
2211 /* A pointer-to-member function. We want output along the
2212 lines of `void (C::*) (int, int)'. Demangle the function
2213 type, which would in this case give `void () (int, int)'
2214 and set *insert_pos to the spot between the first
2216 status
= demangle_type_ptr (dm
, insert_pos
, substitution_start
);
2217 else if (peek_char (dm
) == 'A')
2218 /* A pointer-to-member array variable. We want output that
2219 looks like `int (Klass::*) [10]'. Demangle the array type
2220 as `int () [10]', and set *insert_pos to the spot between
2222 status
= demangle_array_type (dm
, insert_pos
);
2225 /* A pointer-to-member variable. Demangle the type of the
2226 pointed-to member. */
2227 status
= demangle_type (dm
);
2228 /* Make it pretty. */
2229 if (STATUS_NO_ERROR (status
)
2230 && !result_previous_char_is_space (dm
))
2231 status
= result_add_char (dm
, ' ');
2232 /* The pointer-to-member notation (e.g. `C::*') follows the
2234 *insert_pos
= result_caret_pos (dm
);
2237 /* Build the pointer-to-member notation. */
2238 if (STATUS_NO_ERROR (status
))
2239 status
= result_insert (dm
, *insert_pos
, "::*");
2240 if (STATUS_NO_ERROR (status
))
2241 status
= result_insert_string (dm
, *insert_pos
, class_type
);
2242 /* There may be additional levels of (pointer or reference)
2243 indirection in this type. If so, the `*' and `&' should be
2244 added after the pointer-to-member notation (e.g. `C::*&' for
2245 a reference to a pointer-to-member of class C). */
2246 *insert_pos
+= dyn_string_length (class_type
) + 3;
2249 dyn_string_delete (class_type
);
2251 RETURN_IF_ERROR (status
);
2256 /* Ooh, tricky, a pointer-to-function. When we demangle the
2257 function type, the return type should go at the very
2259 *insert_pos
= result_caret_pos (dm
);
2260 /* The parentheses indicate this is a function pointer or
2262 RETURN_IF_ERROR (result_add (dm
, "()"));
2263 /* Now demangle the function type. The return type will be
2264 inserted before the `()', and the argument list will go after
2266 RETURN_IF_ERROR (demangle_function_type (dm
, insert_pos
));
2267 /* We should now have something along the lines of
2268 `void () (int, int)'. The pointer or reference characters
2269 have to inside the first set of parentheses. *insert_pos has
2270 already been updated to point past the end of the return
2271 type. Move it one character over so it points inside the
2277 /* An array pointer or reference. demangle_array_type will figure
2278 out where the asterisks and ampersands go. */
2279 RETURN_IF_ERROR (demangle_array_type (dm
, insert_pos
));
2283 /* No more pointer or reference tokens; this is therefore a
2284 pointer to data. Finish up by demangling the underlying
2286 RETURN_IF_ERROR (demangle_type (dm
));
2287 /* The pointer or reference characters follow the underlying
2288 type, as in `int*&'. */
2289 *insert_pos
= result_caret_pos (dm
);
2290 /* Because of the production <type> ::= <substitution>,
2291 demangle_type will already have added the underlying type as
2292 a substitution candidate. Don't do it again. */
2293 is_substitution_candidate
= 0;
2297 if (is_substitution_candidate
)
2298 RETURN_IF_ERROR (substitution_add (dm
, substitution_start
, 0));
2303 /* Demangles and emits a <type>.
2305 <type> ::= <builtin-type>
2307 ::= <class-enum-type>
2309 ::= <pointer-to-member-type>
2310 ::= <template-param>
2311 ::= <template-template-param> <template-args>
2312 ::= <CV-qualifiers> <type>
2313 ::= P <type> # pointer-to
2314 ::= R <type> # reference-to
2315 ::= C <type> # complex pair (C 2000)
2316 ::= G <type> # imaginary (C 2000)
2317 ::= U <source-name> <type> # vendor extended type qualifier
2318 ::= <substitution> */
2324 int start
= substitution_start (dm
);
2325 char peek
= peek_char (dm
);
2327 int encode_return_type
= 0;
2328 template_arg_list_t old_arg_list
= current_template_arg_list (dm
);
2331 /* A <type> can be a <substitution>; therefore, this <type> is a
2332 substitution candidate unless a special condition holds (see
2334 int is_substitution_candidate
= 1;
2336 DEMANGLE_TRACE ("type", dm
);
2338 /* A <class-enum-type> can start with a digit (a <source-name>), an
2339 N (a <nested-name>), or a Z (a <local-name>). */
2340 if (IS_DIGIT ((unsigned char) peek
) || peek
== 'N' || peek
== 'Z')
2341 RETURN_IF_ERROR (demangle_class_enum_type (dm
, &encode_return_type
));
2342 /* Lower-case letters begin <builtin-type>s, except for `r', which
2343 denotes restrict. */
2344 else if (peek
>= 'a' && peek
<= 'z' && peek
!= 'r')
2346 RETURN_IF_ERROR (demangle_builtin_type (dm
));
2347 /* Built-in types are not substitution candidates. */
2348 is_substitution_candidate
= 0;
2356 /* CV-qualifiers (including restrict). We have to demangle
2357 them off to the side, since C++ syntax puts them in a funny
2358 place for qualified pointer and reference types. */
2361 dyn_string_t cv_qualifiers
= dyn_string_new (24);
2362 int old_caret_position
= result_get_caret (dm
);
2364 if (cv_qualifiers
== NULL
)
2365 return STATUS_ALLOCATION_FAILED
;
2367 /* Decode all adjacent CV qualifiers. */
2368 demangle_CV_qualifiers (dm
, cv_qualifiers
);
2369 /* Emit them, and shift the caret left so that the
2370 underlying type will be emitted before the qualifiers. */
2371 status
= result_add_string (dm
, cv_qualifiers
);
2372 result_shift_caret (dm
, -dyn_string_length (cv_qualifiers
));
2374 dyn_string_delete (cv_qualifiers
);
2375 RETURN_IF_ERROR (status
);
2376 /* Also prepend a blank, if needed. */
2377 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2378 result_shift_caret (dm
, -1);
2380 /* Demangle the underlying type. It will be emitted before
2381 the CV qualifiers, since we moved the caret. */
2382 RETURN_IF_ERROR (demangle_type (dm
));
2384 /* Put the caret back where it was previously. */
2385 result_set_caret (dm
, old_caret_position
);
2390 return "Non-pointer or -reference function type.";
2393 RETURN_IF_ERROR (demangle_array_type (dm
, NULL
));
2397 /* It's either a <template-param> or a
2398 <template-template-param>. In either case, demangle the
2400 RETURN_IF_ERROR (demangle_template_param (dm
));
2402 /* Check for a template argument list; if one is found, it's a
2403 <template-template-param> ::= <template-param>
2404 ::= <substitution> */
2405 if (peek_char (dm
) == 'I')
2407 /* Add a substitution candidate. The template parameter
2408 `T' token is a substitution candidate by itself,
2409 without the template argument list. */
2410 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2412 /* Now demangle the template argument list. */
2413 RETURN_IF_ERROR (demangle_template_args (dm
));
2414 /* The entire type, including the template template
2415 parameter and its argument list, will be added as a
2416 substitution candidate below. */
2422 /* First check if this is a special substitution. If it is,
2423 this is a <class-enum-type>. Special substitutions have a
2424 letter following the `S'; other substitutions have a digit
2426 peek_next
= peek_char_next (dm
);
2427 if (IS_DIGIT (peek_next
) || peek_next
== '_')
2429 RETURN_IF_ERROR (demangle_substitution (dm
, &encode_return_type
));
2431 /* The substituted name may have been a template name.
2432 Check if template arguments follow, and if so, demangle
2434 if (peek_char (dm
) == 'I')
2435 RETURN_IF_ERROR (demangle_template_args (dm
));
2437 /* A substitution token is not itself a substitution
2438 candidate. (However, if the substituted template is
2439 instantiated, the resulting type is.) */
2440 is_substitution_candidate
= 0;
2444 /* Now some trickiness. We have a special substitution
2445 here. Often, the special substitution provides the
2446 name of a template that's subsequently instantiated,
2447 for instance `SaIcE' => std::allocator<char>. In these
2448 cases we need to add a substitution candidate for the
2449 entire <class-enum-type> and thus don't want to clear
2450 the is_substitution_candidate flag.
2452 However, it's possible that what we have here is a
2453 substitution token representing an entire type, such as
2454 `Ss' => std::string. In this case, we mustn't add a
2455 new substitution candidate for this substitution token.
2456 To detect this case, remember where the start of the
2457 substitution token is. */
2458 const char *next
= dm
->next
;
2459 /* Now demangle the <class-enum-type>. */
2461 (demangle_class_enum_type (dm
, &encode_return_type
));
2462 /* If all that was just demangled is the two-character
2463 special substitution token, supress the addition of a
2464 new candidate for it. */
2465 if (dm
->next
== next
+ 2)
2466 is_substitution_candidate
= 0;
2474 RETURN_IF_ERROR (demangle_type_ptr (dm
, &insert_pos
, start
));
2475 /* demangle_type_ptr adds all applicable substitution
2477 is_substitution_candidate
= 0;
2481 /* A C99 complex type. */
2482 RETURN_IF_ERROR (result_add (dm
, "complex "));
2484 RETURN_IF_ERROR (demangle_type (dm
));
2488 /* A C99 imaginary type. */
2489 RETURN_IF_ERROR (result_add (dm
, "imaginary "));
2491 RETURN_IF_ERROR (demangle_type (dm
));
2495 /* Vendor-extended type qualifier. */
2497 RETURN_IF_ERROR (demangle_source_name (dm
));
2498 RETURN_IF_ERROR (result_add_char (dm
, ' '));
2499 RETURN_IF_ERROR (demangle_type (dm
));
2503 return "Unexpected character in <type>.";
2506 if (is_substitution_candidate
)
2507 /* Add a new substitution for the type. If this type was a
2508 <template-param>, pass its index since from the point of
2509 substitutions; a <template-param> token is a substitution
2510 candidate distinct from the type that is substituted for it. */
2511 RETURN_IF_ERROR (substitution_add (dm
, start
, encode_return_type
));
2513 /* Pop off template argument lists added during mangling of this
2515 pop_to_template_arg_list (dm
, old_arg_list
);
2520 /* C++ source names of builtin types, indexed by the mangled code
2521 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2522 static const char *const builtin_type_names
[26] =
2524 "signed char", /* a */
2528 "long double", /* e */
2530 "__float128", /* g */
2531 "unsigned char", /* h */
2536 "unsigned long", /* m */
2538 "unsigned __int128", /* o */
2543 "unsigned short", /* t */
2547 "long long", /* x */
2548 "unsigned long long", /* y */
2552 /* Java source names of builtin types. Types that arn't valid in Java
2553 are also included here - we don't fail if someone attempts to demangle a
2554 C++ symbol in Java style. */
2555 static const char *const java_builtin_type_names
[26] =
2557 "signed char", /* a */
2558 "boolean", /* C++ "bool" */ /* b */
2559 "byte", /* C++ "char" */ /* c */
2561 "long double", /* e */
2563 "__float128", /* g */
2564 "unsigned char", /* h */
2569 "unsigned long", /* m */
2571 "unsigned __int128", /* o */
2576 "unsigned short", /* t */
2579 "char", /* C++ "wchar_t" */ /* w */
2580 "long", /* C++ "long long" */ /* x */
2581 "unsigned long long", /* y */
2585 /* Demangles and emits a <builtin-type>.
2587 <builtin-type> ::= v # void
2592 ::= h # unsigned char
2594 ::= t # unsigned short
2596 ::= j # unsigned int
2598 ::= m # unsigned long
2599 ::= x # long long, __int64
2600 ::= y # unsigned long long, __int64
2602 ::= o # unsigned __int128
2605 ::= e # long double, __float80
2608 ::= u <source-name> # vendor extended type */
2611 demangle_builtin_type (dm
)
2615 char code
= peek_char (dm
);
2617 DEMANGLE_TRACE ("builtin-type", dm
);
2622 RETURN_IF_ERROR (demangle_source_name (dm
));
2625 else if (code
>= 'a' && code
<= 'z')
2627 const char *type_name
;
2628 /* Java uses different names for some built-in types. */
2629 if (dm
->style
== DMGL_JAVA
)
2630 type_name
= java_builtin_type_names
[code
- 'a'];
2632 type_name
= builtin_type_names
[code
- 'a'];
2633 if (type_name
== NULL
)
2634 return "Unrecognized <builtin-type> code.";
2636 RETURN_IF_ERROR (result_add (dm
, type_name
));
2641 return "Non-alphabetic <builtin-type> code.";
2644 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2645 restrict) at the current position. The qualifiers are appended to
2646 QUALIFIERS. Returns STATUS_OK. */
2649 demangle_CV_qualifiers (dm
, qualifiers
)
2651 dyn_string_t qualifiers
;
2653 DEMANGLE_TRACE ("CV-qualifiers", dm
);
2657 switch (peek_char (dm
))
2660 if (!dyn_string_append_space (qualifiers
))
2661 return STATUS_ALLOCATION_FAILED
;
2662 if (!dyn_string_append_cstr (qualifiers
, "restrict"))
2663 return STATUS_ALLOCATION_FAILED
;
2667 if (!dyn_string_append_space (qualifiers
))
2668 return STATUS_ALLOCATION_FAILED
;
2669 if (!dyn_string_append_cstr (qualifiers
, "volatile"))
2670 return STATUS_ALLOCATION_FAILED
;
2674 if (!dyn_string_append_space (qualifiers
))
2675 return STATUS_ALLOCATION_FAILED
;
2676 if (!dyn_string_append_cstr (qualifiers
, "const"))
2677 return STATUS_ALLOCATION_FAILED
;
2688 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2689 position in the result string of the start of the function
2690 identifier, at which the function's return type will be inserted;
2691 *FUNCTION_NAME_POS is updated to position past the end of the
2692 function's return type.
2694 <function-type> ::= F [Y] <bare-function-type> E */
2697 demangle_function_type (dm
, function_name_pos
)
2699 int *function_name_pos
;
2701 DEMANGLE_TRACE ("function-type", dm
);
2702 RETURN_IF_ERROR (demangle_char (dm
, 'F'));
2703 if (peek_char (dm
) == 'Y')
2705 /* Indicate this function has C linkage if in verbose mode. */
2707 RETURN_IF_ERROR (result_add (dm
, " [extern \"C\"] "));
2710 RETURN_IF_ERROR (demangle_bare_function_type (dm
, function_name_pos
));
2711 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
2715 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2716 position in the result string at which the function return type
2717 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2718 function's return type is assumed not to be encoded.
2720 <bare-function-type> ::= <signature type>+ */
2723 demangle_bare_function_type (dm
, return_type_pos
)
2725 int *return_type_pos
;
2727 /* Sequence is the index of the current function parameter, counting
2728 from zero. The value -1 denotes the return type. */
2730 (return_type_pos
== BFT_NO_RETURN_TYPE
? 0 : -1);
2732 DEMANGLE_TRACE ("bare-function-type", dm
);
2734 RETURN_IF_ERROR (result_add_char (dm
, '('));
2735 while (!end_of_name_p (dm
) && peek_char (dm
) != 'E')
2738 /* We're decoding the function's return type. */
2740 dyn_string_t return_type
;
2741 status_t status
= STATUS_OK
;
2743 /* Decode the return type off to the side. */
2744 RETURN_IF_ERROR (result_push (dm
));
2745 RETURN_IF_ERROR (demangle_type (dm
));
2746 return_type
= (dyn_string_t
) result_pop (dm
);
2748 /* Add a space to the end of the type. Insert the return
2749 type where we've been asked to. */
2750 if (!dyn_string_append_space (return_type
))
2751 status
= STATUS_ALLOCATION_FAILED
;
2752 if (STATUS_NO_ERROR (status
))
2754 if (!dyn_string_insert (result_string (dm
), *return_type_pos
,
2756 status
= STATUS_ALLOCATION_FAILED
;
2758 *return_type_pos
+= dyn_string_length (return_type
);
2761 dyn_string_delete (return_type
);
2762 RETURN_IF_ERROR (status
);
2766 /* Skip `void' parameter types. One should only occur as
2767 the only type in a parameter list; in that case, we want
2768 to print `foo ()' instead of `foo (void)'. */
2769 if (peek_char (dm
) == 'v')
2770 /* Consume the v. */
2774 /* Separate parameter types by commas. */
2776 RETURN_IF_ERROR (result_add (dm
, ", "));
2777 /* Demangle the type. */
2778 RETURN_IF_ERROR (demangle_type (dm
));
2784 RETURN_IF_ERROR (result_add_char (dm
, ')'));
2786 /* We should have demangled at least one parameter type (which would
2787 be void, for a function that takes no parameters), plus the
2788 return type, if we were supposed to demangle that. */
2790 return "Missing function return type.";
2791 else if (sequence
== 0)
2792 return "Missing function parameter.";
2797 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2798 non-zero if the type is a template-id, zero otherwise.
2800 <class-enum-type> ::= <name> */
2803 demangle_class_enum_type (dm
, encode_return_type
)
2805 int *encode_return_type
;
2807 DEMANGLE_TRACE ("class-enum-type", dm
);
2809 RETURN_IF_ERROR (demangle_name (dm
, encode_return_type
));
2813 /* Demangles and emits an <array-type>.
2815 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2816 pointer or reference to an array, except that asterisk and
2817 ampersand punctuation is omitted (since it's not know at this
2818 point). *PTR_INSERT_POS is set to the position in the demangled
2819 name at which this punctuation should be inserted. For example,
2820 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2821 between the parentheses.
2823 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2824 pointer- or reference-qualified. Then, for example, `A10_i' is
2825 demangled simply as `int[10]'.
2827 <array-type> ::= A [<dimension number>] _ <element type>
2828 ::= A <dimension expression> _ <element type> */
2831 demangle_array_type (dm
, ptr_insert_pos
)
2833 int *ptr_insert_pos
;
2835 status_t status
= STATUS_OK
;
2836 dyn_string_t array_size
= NULL
;
2839 DEMANGLE_TRACE ("array-type", dm
);
2841 RETURN_IF_ERROR (demangle_char (dm
, 'A'));
2843 /* Demangle the array size into array_size. */
2844 peek
= peek_char (dm
);
2846 /* Array bound is omitted. This is a C99-style VLA. */
2848 else if (IS_DIGIT (peek_char (dm
)))
2850 /* It looks like a constant array bound. */
2851 array_size
= dyn_string_new (10);
2852 if (array_size
== NULL
)
2853 return STATUS_ALLOCATION_FAILED
;
2854 status
= demangle_number_literally (dm
, array_size
, 10, 0);
2858 /* Anything is must be an expression for a nont-constant array
2859 bound. This happens if the array type occurs in a template
2860 and the array bound references a template parameter. */
2861 RETURN_IF_ERROR (result_push (dm
));
2862 RETURN_IF_ERROR (demangle_expression (dm
));
2863 array_size
= (dyn_string_t
) result_pop (dm
);
2865 /* array_size may have been allocated by now, so we can't use
2866 RETURN_IF_ERROR until it's been deallocated. */
2868 /* Demangle the base type of the array. */
2869 if (STATUS_NO_ERROR (status
))
2870 status
= demangle_char (dm
, '_');
2871 if (STATUS_NO_ERROR (status
))
2872 status
= demangle_type (dm
);
2874 if (ptr_insert_pos
!= NULL
)
2876 /* This array is actually part of an pointer- or
2877 reference-to-array type. Format appropriately, except we
2878 don't know which and how much punctuation to use. */
2879 if (STATUS_NO_ERROR (status
))
2880 status
= result_add (dm
, " () ");
2881 /* Let the caller know where to insert the punctuation. */
2882 *ptr_insert_pos
= result_caret_pos (dm
) - 2;
2885 /* Emit the array dimension syntax. */
2886 if (STATUS_NO_ERROR (status
))
2887 status
= result_add_char (dm
, '[');
2888 if (STATUS_NO_ERROR (status
) && array_size
!= NULL
)
2889 status
= result_add_string (dm
, array_size
);
2890 if (STATUS_NO_ERROR (status
))
2891 status
= result_add_char (dm
, ']');
2892 if (array_size
!= NULL
)
2893 dyn_string_delete (array_size
);
2895 RETURN_IF_ERROR (status
);
2900 /* Demangles and emits a <template-param>.
2902 <template-param> ::= T_ # first template parameter
2903 ::= T <parameter-2 number> _ */
2906 demangle_template_param (dm
)
2910 template_arg_list_t current_arg_list
= current_template_arg_list (dm
);
2913 DEMANGLE_TRACE ("template-param", dm
);
2915 /* Make sure there is a template argmust list in which to look up
2916 this parameter reference. */
2917 if (current_arg_list
== NULL
)
2918 return "Template parameter outside of template.";
2920 RETURN_IF_ERROR (demangle_char (dm
, 'T'));
2921 if (peek_char (dm
) == '_')
2925 RETURN_IF_ERROR (demangle_number (dm
, &parm_number
, 10, 0));
2928 RETURN_IF_ERROR (demangle_char (dm
, '_'));
2930 arg
= template_arg_list_get_arg (current_arg_list
, parm_number
);
2932 /* parm_number exceeded the number of arguments in the current
2933 template argument list. */
2934 return "Template parameter number out of bounds.";
2935 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2940 /* Demangles and emits a <template-args>.
2942 <template-args> ::= I <template-arg>+ E */
2945 demangle_template_args (dm
)
2949 dyn_string_t old_last_source_name
;
2950 template_arg_list_t arg_list
= template_arg_list_new ();
2952 if (arg_list
== NULL
)
2953 return STATUS_ALLOCATION_FAILED
;
2955 /* Preserve the most recently demangled source name. */
2956 old_last_source_name
= dm
->last_source_name
;
2957 dm
->last_source_name
= dyn_string_new (0);
2959 DEMANGLE_TRACE ("template-args", dm
);
2961 if (dm
->last_source_name
== NULL
)
2962 return STATUS_ALLOCATION_FAILED
;
2964 RETURN_IF_ERROR (demangle_char (dm
, 'I'));
2965 RETURN_IF_ERROR (result_open_template_list (dm
));
2973 RETURN_IF_ERROR (result_add (dm
, ", "));
2975 /* Capture the template arg. */
2976 RETURN_IF_ERROR (result_push (dm
));
2977 RETURN_IF_ERROR (demangle_template_arg (dm
));
2978 arg
= result_pop (dm
);
2980 /* Emit it in the demangled name. */
2981 RETURN_IF_ERROR (result_add_string (dm
, (dyn_string_t
) arg
));
2983 /* Save it for use in expanding <template-param>s. */
2984 template_arg_list_add_arg (arg_list
, arg
);
2986 while (peek_char (dm
) != 'E');
2987 /* Append the '>'. */
2988 RETURN_IF_ERROR (result_close_template_list (dm
));
2990 /* Consume the 'E'. */
2993 /* Restore the most recent demangled source name. */
2994 dyn_string_delete (dm
->last_source_name
);
2995 dm
->last_source_name
= old_last_source_name
;
2997 /* Push the list onto the top of the stack of template argument
2998 lists, so that arguments from it are used from now on when
2999 expanding <template-param>s. */
3000 push_template_arg_list (dm
, arg_list
);
3005 /* This function, which does not correspond to a production in the
3006 mangling spec, handles the `literal' production for both
3007 <template-arg> and <expr-primary>. It does not expect or consume
3008 the initial `L' or final `E'. The demangling is given by:
3010 <literal> ::= <type> </value/ number>
3012 and the emitted output is `(type)number'. */
3015 demangle_literal (dm
)
3018 char peek
= peek_char (dm
);
3019 dyn_string_t value_string
;
3022 DEMANGLE_TRACE ("literal", dm
);
3024 if (!flag_verbose
&& peek
>= 'a' && peek
<= 'z')
3026 /* If not in verbose mode and this is a builtin type, see if we
3027 can produce simpler numerical output. In particular, for
3028 integer types shorter than `long', just write the number
3029 without type information; for bools, write `true' or `false'.
3030 Other refinements could be made here too. */
3032 /* This constant string is used to map from <builtin-type> codes
3033 (26 letters of the alphabet) to codes that determine how the
3034 value will be displayed. The codes are:
3038 A space means the value will be represented using cast
3040 static const char *const code_map
= "ibi iii ll ii i ";
3042 char code
= code_map
[peek
- 'a'];
3043 /* FIXME: Implement demangling of floats and doubles. */
3045 return STATUS_UNIMPLEMENTED
;
3048 /* It's a boolean. */
3051 /* Consume the b. */
3053 /* Look at the next character. It should be 0 or 1,
3054 corresponding to false or true, respectively. */
3055 value
= peek_char (dm
);
3057 RETURN_IF_ERROR (result_add (dm
, "false"));
3058 else if (value
== '1')
3059 RETURN_IF_ERROR (result_add (dm
, "true"));
3061 return "Unrecognized bool constant.";
3062 /* Consume the 0 or 1. */
3066 else if (code
== 'i' || code
== 'l')
3068 /* It's an integer or long. */
3070 /* Consume the type character. */
3073 /* Demangle the number and write it out. */
3074 value_string
= dyn_string_new (0);
3075 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3076 if (STATUS_NO_ERROR (status
))
3077 status
= result_add_string (dm
, value_string
);
3078 /* For long integers, append an l. */
3079 if (code
== 'l' && STATUS_NO_ERROR (status
))
3080 status
= result_add_char (dm
, code
);
3081 dyn_string_delete (value_string
);
3083 RETURN_IF_ERROR (status
);
3086 /* ...else code == ' ', so fall through to represent this
3087 literal's type explicitly using cast syntax. */
3090 RETURN_IF_ERROR (result_add_char (dm
, '('));
3091 RETURN_IF_ERROR (demangle_type (dm
));
3092 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3094 value_string
= dyn_string_new (0);
3095 if (value_string
== NULL
)
3096 return STATUS_ALLOCATION_FAILED
;
3098 status
= demangle_number_literally (dm
, value_string
, 10, 1);
3099 if (STATUS_NO_ERROR (status
))
3100 status
= result_add_string (dm
, value_string
);
3101 dyn_string_delete (value_string
);
3102 RETURN_IF_ERROR (status
);
3107 /* Demangles and emits a <template-arg>.
3109 <template-arg> ::= <type> # type
3110 ::= L <type> <value number> E # literal
3111 ::= LZ <encoding> E # external name
3112 ::= X <expression> E # expression */
3115 demangle_template_arg (dm
)
3118 DEMANGLE_TRACE ("template-arg", dm
);
3120 switch (peek_char (dm
))
3125 if (peek_char (dm
) == 'Z')
3127 /* External name. */
3129 /* FIXME: Standard is contradictory here. */
3130 RETURN_IF_ERROR (demangle_encoding (dm
));
3133 RETURN_IF_ERROR (demangle_literal (dm
));
3134 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3140 RETURN_IF_ERROR (demangle_expression (dm
));
3141 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3145 RETURN_IF_ERROR (demangle_type (dm
));
3152 /* Demangles and emits an <expression>.
3154 <expression> ::= <unary operator-name> <expression>
3155 ::= <binary operator-name> <expression> <expression>
3157 ::= <scope-expression> */
3160 demangle_expression (dm
)
3163 char peek
= peek_char (dm
);
3165 DEMANGLE_TRACE ("expression", dm
);
3167 if (peek
== 'L' || peek
== 'T')
3168 RETURN_IF_ERROR (demangle_expr_primary (dm
));
3169 else if (peek
== 's' && peek_char_next (dm
) == 'r')
3170 RETURN_IF_ERROR (demangle_scope_expression (dm
));
3172 /* An operator expression. */
3176 status_t status
= STATUS_OK
;
3177 dyn_string_t operator_name
;
3179 /* We have an operator name. Since we want to output binary
3180 operations in infix notation, capture the operator name
3182 RETURN_IF_ERROR (result_push (dm
));
3183 RETURN_IF_ERROR (demangle_operator_name (dm
, 1, &num_args
,
3185 operator_name
= (dyn_string_t
) result_pop (dm
);
3187 /* If it's binary, do an operand first. */
3190 status
= result_add_char (dm
, '(');
3191 if (STATUS_NO_ERROR (status
))
3192 status
= demangle_expression (dm
);
3193 if (STATUS_NO_ERROR (status
))
3194 status
= result_add_char (dm
, ')');
3197 /* Emit the operator. */
3198 if (STATUS_NO_ERROR (status
))
3199 status
= result_add_string (dm
, operator_name
);
3200 dyn_string_delete (operator_name
);
3201 RETURN_IF_ERROR (status
);
3203 /* Emit its second (if binary) or only (if unary) operand. */
3204 RETURN_IF_ERROR (result_add_char (dm
, '('));
3206 RETURN_IF_ERROR (demangle_type (dm
));
3208 RETURN_IF_ERROR (demangle_expression (dm
));
3209 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3211 /* The ternary operator takes a third operand. */
3214 RETURN_IF_ERROR (result_add (dm
, ":("));
3215 RETURN_IF_ERROR (demangle_expression (dm
));
3216 RETURN_IF_ERROR (result_add_char (dm
, ')'));
3223 /* Demangles and emits a <scope-expression>.
3225 <scope-expression> ::= sr <qualifying type> <source-name>
3226 ::= sr <qualifying type> <encoding> */
3229 demangle_scope_expression (dm
)
3232 RETURN_IF_ERROR (demangle_char (dm
, 's'));
3233 RETURN_IF_ERROR (demangle_char (dm
, 'r'));
3234 RETURN_IF_ERROR (demangle_type (dm
));
3235 RETURN_IF_ERROR (result_add (dm
, "::"));
3236 RETURN_IF_ERROR (demangle_encoding (dm
));
3240 /* Demangles and emits an <expr-primary>.
3242 <expr-primary> ::= <template-param>
3243 ::= L <type> <value number> E # literal
3244 ::= L <mangled-name> E # external name */
3247 demangle_expr_primary (dm
)
3250 char peek
= peek_char (dm
);
3252 DEMANGLE_TRACE ("expr-primary", dm
);
3255 RETURN_IF_ERROR (demangle_template_param (dm
));
3256 else if (peek
== 'L')
3258 /* Consume the `L'. */
3260 peek
= peek_char (dm
);
3263 RETURN_IF_ERROR (demangle_mangled_name (dm
));
3265 RETURN_IF_ERROR (demangle_literal (dm
));
3267 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3270 return STATUS_ERROR
;
3275 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3276 if the substitution is the name of a template, zero otherwise.
3278 <substitution> ::= S <seq-id> _
3282 ::= Sa # ::std::allocator
3283 ::= Sb # ::std::basic_string
3284 ::= Ss # ::std::basic_string<char,
3285 ::std::char_traits<char>,
3286 ::std::allocator<char> >
3287 ::= Si # ::std::basic_istream<char,
3288 std::char_traits<char> >
3289 ::= So # ::std::basic_ostream<char,
3290 std::char_traits<char> >
3291 ::= Sd # ::std::basic_iostream<char,
3292 std::char_traits<char> >
3296 demangle_substitution (dm
, template_p
)
3304 DEMANGLE_TRACE ("substitution", dm
);
3306 RETURN_IF_ERROR (demangle_char (dm
, 'S'));
3308 /* Scan the substitution sequence index. A missing number denotes
3310 peek
= peek_char (dm
);
3313 /* If the following character is 0-9 or a capital letter, interpret
3314 the sequence up to the next underscore as a base-36 substitution
3316 else if (IS_DIGIT ((unsigned char) peek
)
3317 || (peek
>= 'A' && peek
<= 'Z'))
3318 RETURN_IF_ERROR (demangle_number (dm
, &seq_id
, 36, 0));
3321 const char *new_last_source_name
= NULL
;
3326 RETURN_IF_ERROR (result_add (dm
, "std"));
3330 RETURN_IF_ERROR (result_add (dm
, "std::allocator"));
3331 new_last_source_name
= "allocator";
3336 RETURN_IF_ERROR (result_add (dm
, "std::basic_string"));
3337 new_last_source_name
= "basic_string";
3344 RETURN_IF_ERROR (result_add (dm
, "std::string"));
3345 new_last_source_name
= "string";
3349 RETURN_IF_ERROR (result_add (dm
, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3350 new_last_source_name
= "basic_string";
3358 RETURN_IF_ERROR (result_add (dm
, "std::istream"));
3359 new_last_source_name
= "istream";
3363 RETURN_IF_ERROR (result_add (dm
, "std::basic_istream<char, std::char_traints<char> >"));
3364 new_last_source_name
= "basic_istream";
3372 RETURN_IF_ERROR (result_add (dm
, "std::ostream"));
3373 new_last_source_name
= "ostream";
3377 RETURN_IF_ERROR (result_add (dm
, "std::basic_ostream<char, std::char_traits<char> >"));
3378 new_last_source_name
= "basic_ostream";
3386 RETURN_IF_ERROR (result_add (dm
, "std::iostream"));
3387 new_last_source_name
= "iostream";
3391 RETURN_IF_ERROR (result_add (dm
, "std::basic_iostream<char, std::char_traits<char> >"));
3392 new_last_source_name
= "basic_iostream";
3398 return "Unrecognized <substitution>.";
3401 /* Consume the character we just processed. */
3404 if (new_last_source_name
!= NULL
)
3406 if (!dyn_string_copy_cstr (dm
->last_source_name
,
3407 new_last_source_name
))
3408 return STATUS_ALLOCATION_FAILED
;
3414 /* Look up the substitution text. Since `S_' is the most recent
3415 substitution, `S0_' is the second-most-recent, etc., shift the
3416 numbering by one. */
3417 text
= substitution_get (dm
, seq_id
+ 1, template_p
);
3419 return "Substitution number out of range.";
3421 /* Emit the substitution text. */
3422 RETURN_IF_ERROR (result_add_string (dm
, text
));
3424 RETURN_IF_ERROR (demangle_char (dm
, '_'));
3428 /* Demangles and emits a <local-name>.
3430 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3431 := Z <function encoding> E s [<discriminator>] */
3434 demangle_local_name (dm
)
3437 DEMANGLE_TRACE ("local-name", dm
);
3439 RETURN_IF_ERROR (demangle_char (dm
, 'Z'));
3440 RETURN_IF_ERROR (demangle_encoding (dm
));
3441 RETURN_IF_ERROR (demangle_char (dm
, 'E'));
3442 RETURN_IF_ERROR (result_add (dm
, "::"));
3444 if (peek_char (dm
) == 's')
3446 /* Local character string literal. */
3447 RETURN_IF_ERROR (result_add (dm
, "string literal"));
3448 /* Consume the s. */
3450 RETURN_IF_ERROR (demangle_discriminator (dm
, 0));
3455 /* Local name for some other entity. Demangle its name. */
3456 RETURN_IF_ERROR (demangle_name (dm
, &unused
));
3457 RETURN_IF_ERROR (demangle_discriminator (dm
, 1));
3463 /* Optimonally demangles and emits a <discriminator>. If there is no
3464 <discriminator> at the current position in the mangled string, the
3465 descriminator is assumed to be zero. Emit the discriminator number
3466 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3467 discriminator is zero.
3469 <discriminator> ::= _ <number> */
3472 demangle_discriminator (dm
, suppress_first
)
3476 /* Output for <discriminator>s to the demangled name is completely
3477 suppressed if not in verbose mode. */
3479 if (peek_char (dm
) == '_')
3481 /* Consume the underscore. */
3484 RETURN_IF_ERROR (result_add (dm
, " [#"));
3485 /* Check if there's a number following the underscore. */
3486 if (IS_DIGIT ((unsigned char) peek_char (dm
)))
3489 /* Demangle the number. */
3490 RETURN_IF_ERROR (demangle_number (dm
, &discriminator
, 10, 0));
3492 /* Write the discriminator. The mangled number is two
3493 less than the discriminator ordinal, counting from
3495 RETURN_IF_ERROR (int_to_dyn_string (discriminator
+ 1,
3496 (dyn_string_t
) dm
->result
));
3499 return STATUS_ERROR
;
3501 RETURN_IF_ERROR (result_add_char (dm
, ']'));
3503 else if (!suppress_first
)
3506 RETURN_IF_ERROR (result_add (dm
, " [#0]"));
3512 /* Demangle NAME into RESULT, which must be an initialized
3513 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3514 an error message, and the contents of RESULT are unchanged. */
3517 cp_demangle (name
, result
, style
)
3519 dyn_string_t result
;
3523 int length
= strlen (name
);
3525 if (length
> 2 && name
[0] == '_' && name
[1] == 'Z')
3527 demangling_t dm
= demangling_new (name
, style
);
3529 return STATUS_ALLOCATION_FAILED
;
3531 status
= result_push (dm
);
3532 if (status
!= STATUS_OK
)
3534 demangling_delete (dm
);
3538 status
= demangle_mangled_name (dm
);
3539 if (STATUS_NO_ERROR (status
))
3541 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3542 if (!dyn_string_copy (result
, demangled
))
3543 return STATUS_ALLOCATION_FAILED
;
3544 dyn_string_delete (demangled
);
3547 demangling_delete (dm
);
3551 /* It's evidently not a mangled C++ name. It could be the name
3552 of something with C linkage, though, so just copy NAME into
3554 if (!dyn_string_copy_cstr (result
, name
))
3555 return STATUS_ALLOCATION_FAILED
;
3562 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3563 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3564 an error message, and the contents of RESULT are unchanged. */
3567 cp_demangle_type (type_name
, result
)
3568 const char* type_name
;
3569 dyn_string_t result
;
3572 demangling_t dm
= demangling_new (type_name
, DMGL_GNU_V3
);
3575 return STATUS_ALLOCATION_FAILED
;
3577 /* Demangle the type name. The demangled name is stored in dm. */
3578 status
= result_push (dm
);
3579 if (status
!= STATUS_OK
)
3581 demangling_delete (dm
);
3585 status
= demangle_type (dm
);
3587 if (STATUS_NO_ERROR (status
))
3589 /* The demangling succeeded. Pop the result out of dm and copy
3591 dyn_string_t demangled
= (dyn_string_t
) result_pop (dm
);
3592 if (!dyn_string_copy (result
, demangled
))
3593 return STATUS_ALLOCATION_FAILED
;
3594 dyn_string_delete (demangled
);
3598 demangling_delete (dm
);
3603 #if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
3604 extern char *__cxa_demangle
PARAMS ((const char *, char *, size_t *, int *));
3606 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3607 demangling. MANGLED_NAME is a NUL-terminated character string
3608 containing the name to be demangled.
3610 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3611 *LENGTH bytes, into which the demangled name is stored. If
3612 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3613 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3614 is placed in a region of memory allocated with malloc.
3616 If LENGTH is non-NULL, the length of the buffer conaining the
3617 demangled name, is placed in *LENGTH.
3619 The return value is a pointer to the start of the NUL-terminated
3620 demangled name, or NULL if the demangling fails. The caller is
3621 responsible for deallocating this memory using free.
3623 *STATUS is set to one of the following values:
3624 0: The demangling operation succeeded.
3625 -1: A memory allocation failiure occurred.
3626 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3627 -3: One of the arguments is invalid.
3629 The demagling is performed using the C++ ABI mangling rules, with
3633 __cxa_demangle (mangled_name
, output_buffer
, length
, status
)
3634 const char *mangled_name
;
3635 char *output_buffer
;
3639 struct dyn_string demangled_name
;
3645 if (mangled_name
== NULL
) {
3650 /* Did the caller provide a buffer for the demangled name? */
3651 if (output_buffer
== NULL
) {
3652 /* No; dyn_string will malloc a buffer for us. */
3653 if (!dyn_string_init (&demangled_name
, 0))
3660 /* Yes. Check that the length was provided. */
3661 if (length
== NULL
) {
3665 /* Install the buffer into a dyn_string. */
3666 demangled_name
.allocated
= *length
;
3667 demangled_name
.length
= 0;
3668 demangled_name
.s
= output_buffer
;
3671 if (mangled_name
[0] == '_' && mangled_name
[1] == 'Z')
3672 /* MANGLED_NAME apprears to be a function or variable name.
3673 Demangle it accordingly. */
3674 result
= cp_demangle (mangled_name
, &demangled_name
, 0);
3676 /* Try to demangled MANGLED_NAME as the name of a type. */
3677 result
= cp_demangle_type (mangled_name
, &demangled_name
);
3679 if (result
== STATUS_OK
)
3680 /* The demangling succeeded. */
3682 /* If LENGTH isn't NULL, store the allocated buffer length
3683 there; the buffer may have been realloced by dyn_string
3686 *length
= demangled_name
.allocated
;
3687 /* The operation was a success. */
3689 return dyn_string_buf (&demangled_name
);
3691 else if (result
== STATUS_ALLOCATION_FAILED
)
3692 /* A call to malloc or realloc failed during the demangling
3699 /* The demangling failed for another reason, most probably because
3700 MANGLED_NAME isn't a valid mangled name. */
3702 /* If the buffer containing the demangled name wasn't provided
3703 by the caller, free it. */
3704 if (output_buffer
== NULL
)
3705 free (dyn_string_buf (&demangled_name
));
3711 #else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
3713 /* Variant entry point for integration with the existing cplus-dem
3714 demangler. Attempts to demangle MANGLED. If the demangling
3715 succeeds, returns a buffer, allocated with malloc, containing the
3716 demangled name. The caller must deallocate the buffer using free.
3717 If the demangling failes, returns NULL. */
3720 cplus_demangle_v3 (mangled
, options
)
3721 const char* mangled
;
3724 dyn_string_t demangled
;
3726 int type
= !!(options
& DMGL_TYPES
);
3728 if (mangled
[0] == '_' && mangled
[1] == 'Z')
3729 /* It is not a type. */
3733 /* It is a type. Stop if we don't want to demangle types. */
3738 flag_verbose
= !!(options
& DMGL_VERBOSE
);
3740 /* Create a dyn_string to hold the demangled name. */
3741 demangled
= dyn_string_new (0);
3742 /* Attempt the demangling. */
3744 /* Appears to be a function or variable name. */
3745 status
= cp_demangle (mangled
, demangled
, 0);
3747 /* Try to demangle it as the name of a type. */
3748 status
= cp_demangle_type (mangled
, demangled
);
3750 if (STATUS_NO_ERROR (status
))
3751 /* Demangling succeeded. */
3753 /* Grab the demangled result from the dyn_string. It was
3754 allocated with malloc, so we can return it directly. */
3755 char *return_value
= dyn_string_release (demangled
);
3756 /* Hand back the demangled name. */
3757 return return_value
;
3759 else if (status
== STATUS_ALLOCATION_FAILED
)
3761 fprintf (stderr
, "Memory allocation failed.\n");
3765 /* Demangling failed. */
3767 dyn_string_delete (demangled
);
3772 /* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3773 conventions, but the output formatting is a little different.
3774 This instructs the C++ demangler not to emit pointer characters ("*"), and
3775 to use Java's namespace separator symbol ("." instead of "::"). It then
3776 does an additional pass over the demangled output to replace instances
3777 of JArray<TYPE> with TYPE[]. */
3780 java_demangle_v3 (mangled
)
3781 const char* mangled
;
3783 dyn_string_t demangled
;
3789 char *cplus_demangled
;
3792 /* Create a dyn_string to hold the demangled name. */
3793 demangled
= dyn_string_new (0);
3795 /* Attempt the demangling. */
3796 status
= cp_demangle ((char *) mangled
, demangled
, DMGL_JAVA
);
3798 if (STATUS_NO_ERROR (status
))
3799 /* Demangling succeeded. */
3801 /* Grab the demangled result from the dyn_string. */
3802 cplus_demangled
= dyn_string_release (demangled
);
3804 else if (status
== STATUS_ALLOCATION_FAILED
)
3806 fprintf (stderr
, "Memory allocation failed.\n");
3810 /* Demangling failed. */
3812 dyn_string_delete (demangled
);
3816 len
= strlen (cplus_demangled
);
3817 next
= cplus_demangled
;
3821 /* Replace occurances of JArray<TYPE> with TYPE[]. */
3824 char *open_str
= strstr (next
, "JArray<");
3825 char *close_str
= NULL
;
3827 close_str
= strchr (next
, '>');
3829 if (open_str
!= NULL
&& (close_str
== NULL
|| close_str
> open_str
))
3834 demangled
= dyn_string_new(len
);
3836 /* Copy prepending symbols, if any. */
3837 if (open_str
> next
)
3840 dyn_string_append_cstr (demangled
, next
);
3842 next
= open_str
+ 7;
3844 else if (close_str
!= NULL
)
3848 /* Copy prepending type symbol, if any. Squash any spurious
3850 if (close_str
> next
&& next
[0] != ' ')
3853 dyn_string_append_cstr (demangled
, next
);
3855 dyn_string_append_cstr (demangled
, "[]");
3856 next
= close_str
+ 1;
3860 /* There are no more arrays. Copy the rest of the symbol, or
3861 simply return the original symbol if no changes were made. */
3862 if (next
== cplus_demangled
)
3863 return cplus_demangled
;
3865 dyn_string_append_cstr (demangled
, next
);
3870 free (cplus_demangled
);
3873 return_value
= dyn_string_release (demangled
);
3875 return_value
= NULL
;
3877 return return_value
;
3880 #endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
3883 /* Demangle NAME in the G++ V3 ABI demangling style, and return either
3884 zero, indicating that some error occurred, or a demangling_t
3885 holding the results. */
3887 demangle_v3_with_details (name
)
3893 if (strncmp (name
, "_Z", 2))
3896 dm
= demangling_new (name
, DMGL_GNU_V3
);
3899 fprintf (stderr
, "Memory allocation failed.\n");
3903 status
= result_push (dm
);
3904 if (! STATUS_NO_ERROR (status
))
3906 demangling_delete (dm
);
3907 fprintf (stderr
, "%s\n", status
);
3911 status
= demangle_mangled_name (dm
);
3912 if (STATUS_NO_ERROR (status
))
3915 demangling_delete (dm
);
3920 #ifndef IN_GLIBCPP_V3
3921 /* Return non-zero iff NAME is the mangled form of a constructor name
3922 in the G++ V3 ABI demangling style. Specifically, return:
3923 - '1' if NAME is a complete object constructor,
3924 - '2' if NAME is a base object constructor, or
3925 - '3' if NAME is a complete object allocating constructor. */
3926 enum gnu_v3_ctor_kinds
3927 is_gnu_v3_mangled_ctor (name
)
3930 demangling_t dm
= demangle_v3_with_details (name
);
3934 enum gnu_v3_ctor_kinds result
= dm
->is_constructor
;
3935 demangling_delete (dm
);
3943 /* Return non-zero iff NAME is the mangled form of a destructor name
3944 in the G++ V3 ABI demangling style. Specifically, return:
3945 - '0' if NAME is a deleting destructor,
3946 - '1' if NAME is a complete object destructor, or
3947 - '2' if NAME is a base object destructor. */
3948 enum gnu_v3_dtor_kinds
3949 is_gnu_v3_mangled_dtor (name
)
3952 demangling_t dm
= demangle_v3_with_details (name
);
3956 enum gnu_v3_dtor_kinds result
= dm
->is_destructor
;
3957 demangling_delete (dm
);
3963 #endif /* IN_GLIBCPP_V3 */
3966 #ifdef STANDALONE_DEMANGLER
3970 static void print_usage
3971 PARAMS ((FILE* fp
, int exit_value
));
3973 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3974 #define is_mangled_char(CHAR) \
3975 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3976 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3978 /* The name of this program, as invoked. */
3979 const char* program_name
;
3981 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3984 print_usage (fp
, exit_value
)
3988 fprintf (fp
, "Usage: %s [options] [names ...]\n", program_name
);
3989 fprintf (fp
, "Options:\n");
3990 fprintf (fp
, " -h,--help Display this message.\n");
3991 fprintf (fp
, " -s,--strict Demangle standard names only.\n");
3992 fprintf (fp
, " -v,--verbose Produce verbose demanglings.\n");
3993 fprintf (fp
, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3998 /* Option specification for getopt_long. */
3999 static const struct option long_options
[] =
4001 { "help", no_argument
, NULL
, 'h' },
4002 { "strict", no_argument
, NULL
, 's' },
4003 { "verbose", no_argument
, NULL
, 'v' },
4004 { NULL
, no_argument
, NULL
, 0 },
4007 /* Main entry for a demangling filter executable. It will demangle
4008 its command line arguments, if any. If none are provided, it will
4009 filter stdin to stdout, replacing any recognized mangled C++ names
4010 with their demangled equivalents. */
4021 /* Use the program name of this program, as invoked. */
4022 program_name
= argv
[0];
4024 /* Parse options. */
4027 opt_char
= getopt_long (argc
, argv
, "hsv", long_options
, NULL
);
4030 case '?': /* Unrecognized option. */
4031 print_usage (stderr
, 1);
4035 print_usage (stdout
, 0);
4047 while (opt_char
!= -1);
4050 /* No command line arguments were provided. Filter stdin. */
4052 dyn_string_t mangled
= dyn_string_new (3);
4053 dyn_string_t demangled
= dyn_string_new (0);
4056 /* Read all of input. */
4057 while (!feof (stdin
))
4059 char c
= getchar ();
4061 /* The first character of a mangled name is an underscore. */
4066 /* It's not a mangled name. Print the character and go
4073 /* The second character of a mangled name is a capital `Z'. */
4078 /* It's not a mangled name. Print the previous
4079 underscore, the `Z', and go on. */
4085 /* Start keeping track of the candidate mangled name. */
4086 dyn_string_append_char (mangled
, '_');
4087 dyn_string_append_char (mangled
, 'Z');
4089 /* Pile characters into mangled until we hit one that can't
4090 occur in a mangled name. */
4092 while (!feof (stdin
) && is_mangled_char (c
))
4094 dyn_string_append_char (mangled
, c
);
4100 /* Attempt to demangle the name. */
4101 status
= cp_demangle (dyn_string_buf (mangled
), demangled
, 0);
4103 /* If the demangling succeeded, great! Print out the
4104 demangled version. */
4105 if (STATUS_NO_ERROR (status
))
4106 fputs (dyn_string_buf (demangled
), stdout
);
4107 /* Abort on allocation failures. */
4108 else if (status
== STATUS_ALLOCATION_FAILED
)
4110 fprintf (stderr
, "Memory allocation failed.\n");
4113 /* Otherwise, it might not have been a mangled name. Just
4114 print out the original text. */
4116 fputs (dyn_string_buf (mangled
), stdout
);
4118 /* If we haven't hit EOF yet, we've read one character that
4119 can't occur in a mangled name, so print it out. */
4123 /* Clear the candidate mangled name, to start afresh next
4124 time we hit a `_Z'. */
4125 dyn_string_clear (mangled
);
4128 dyn_string_delete (mangled
);
4129 dyn_string_delete (demangled
);
4132 /* Demangle command line arguments. */
4134 dyn_string_t result
= dyn_string_new (0);
4136 /* Loop over command line arguments. */
4137 for (i
= optind
; i
< argc
; ++i
)
4139 /* Attempt to demangle. */
4140 status
= cp_demangle (argv
[i
], result
, 0);
4142 /* If it worked, print the demangled name. */
4143 if (STATUS_NO_ERROR (status
))
4144 printf ("%s\n", dyn_string_buf (result
));
4145 /* Abort on allocaiton failures. */
4146 else if (status
== STATUS_ALLOCATION_FAILED
)
4148 fprintf (stderr
, "Memory allocation failed.\n");
4151 /* If not, print the error message to stderr instead. */
4153 fprintf (stderr
, "%s\n", status
);
4155 dyn_string_delete (result
);
4161 #endif /* STANDALONE_DEMANGLER */