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>
57
#include "libiberty.h"
58
#include "dyn-string.h"
61
/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
62
and other debugging output, will be generated. */
63
#ifdef CP_DEMANGLE_DEBUG
64
#define DEMANGLE_TRACE(PRODUCTION, DM) \
65
fprintf (stderr, " -> %-24s at position %3d\n", \
66
(PRODUCTION), current_position (DM));
68
#define DEMANGLE_TRACE(PRODUCTION, DM)
71
/* Don't include <ctype.h>, to prevent additional unresolved symbols
72
from being dragged into the C++ runtime library. */
73
#define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
74
#define IS_ALPHA(CHAR) \
75
(((CHAR) >= 'a' && (CHAR) <= 'z') \
76
|| ((CHAR) >= 'A' && (CHAR) <= 'Z'))
78
/* The prefix prepended by GCC to an identifier represnting the
79
anonymous namespace. */
80
#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
82
/* Character(s) to use for namespace separation in demangled output */
83
#define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
85
/* If flag_verbose is zero, some simplifications will be made to the
86
output to make it easier to read and supress details that are
87
generally not of interest to the average C++ programmer.
88
Otherwise, the demangled representation will attempt to convey as
89
much information as the mangled form. */
90
static int flag_verbose;
92
/* If flag_strict is non-zero, demangle strictly according to the
93
specification -- don't demangle special g++ manglings. */
94
static int flag_strict;
96
/* String_list_t is an extended form of dyn_string_t which provides a
97
link field and a caret position for additions to the string. A
98
string_list_t may safely be cast to and used as a dyn_string_t. */
100
struct string_list_def
102
/* The dyn_string; must be first. */
103
struct dyn_string string;
105
/* The position at which additional text is added to this string
106
(using the result_add* macros). This value is an offset from the
107
end of the string, not the beginning (and should be
111
/* The next string in the list. */
112
struct string_list_def *next;
115
typedef struct string_list_def *string_list_t;
117
/* Data structure representing a potential substitution. */
119
struct substitution_def
121
/* The demangled text of the substitution. */
124
/* Whether this substitution represents a template item. */
128
/* Data structure representing a template argument list. */
130
struct template_arg_list_def
132
/* The next (lower) template argument list in the stack of currently
133
active template arguments. */
134
struct template_arg_list_def *next;
136
/* The first element in the list of template arguments in
137
left-to-right order. */
138
string_list_t first_argument;
140
/* The last element in the arguments lists. */
141
string_list_t last_argument;
144
typedef struct template_arg_list_def *template_arg_list_t;
146
/* Data structure to maintain the state of the current demangling. */
148
struct demangling_def
150
/* The full mangled name being mangled. */
153
/* Pointer into name at the current position. */
156
/* Stack for strings containing demangled result generated so far.
157
Text is emitted to the topmost (first) string. */
158
string_list_t result;
160
/* The number of presently available substitutions. */
161
int num_substitutions;
163
/* The allocated size of the substitutions array. */
164
int substitutions_allocated;
166
/* An array of available substitutions. The number of elements in
167
the array is given by num_substitions, and the allocated array
168
size in substitutions_size.
170
The most recent substition is at the end, so
172
- `S_' corresponds to substititutions[num_substitutions - 1]
173
- `S0_' corresponds to substititutions[num_substitutions - 2]
176
struct substitution_def *substitutions;
178
/* The stack of template argument lists. */
179
template_arg_list_t template_arg_lists;
181
/* The most recently demangled source-name. */
182
dyn_string_t last_source_name;
184
/* Language style to use for demangled output. */
187
/* Set to non-zero iff this name is a constructor. The actual value
188
indicates what sort of constructor this is; see demangle.h. */
189
enum gnu_v3_ctor_kinds is_constructor;
191
/* Set to non-zero iff this name is a destructor. The actual value
192
indicates what sort of destructor this is; see demangle.h. */
193
enum gnu_v3_dtor_kinds is_destructor;
197
typedef struct demangling_def *demangling_t;
199
/* This type is the standard return code from most functions. Values
200
other than STATUS_OK contain descriptive messages. */
201
typedef const char *status_t;
203
/* Special values that can be used as a status_t. */
204
#define STATUS_OK NULL
205
#define STATUS_ERROR "Error."
206
#define STATUS_UNIMPLEMENTED "Unimplemented."
207
#define STATUS_INTERNAL_ERROR "Internal error."
209
/* This status code indicates a failure in malloc or realloc. */
210
static const char *const status_allocation_failed = "Allocation failed.";
211
#define STATUS_ALLOCATION_FAILED status_allocation_failed
213
/* Non-zero if STATUS indicates that no error has occurred. */
214
#define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
216
/* Evaluate EXPR, which must produce a status_t. If the status code
217
indicates an error, return from the current function with that
219
#define RETURN_IF_ERROR(EXPR) \
223
if (!STATUS_NO_ERROR (s)) \
228
static status_t int_to_dyn_string
229
PARAMS ((int, dyn_string_t));
230
static string_list_t string_list_new
232
static void string_list_delete
233
PARAMS ((string_list_t));
234
static status_t result_add_separated_char
235
PARAMS ((demangling_t, int));
236
static status_t result_push
237
PARAMS ((demangling_t));
238
static string_list_t result_pop
239
PARAMS ((demangling_t));
240
static int substitution_start
241
PARAMS ((demangling_t));
242
static status_t substitution_add
243
PARAMS ((demangling_t, int, int));
244
static dyn_string_t substitution_get
245
PARAMS ((demangling_t, int, int *));
246
#ifdef CP_DEMANGLE_DEBUG
247
static void substitutions_print
248
PARAMS ((demangling_t, FILE *));
250
static template_arg_list_t template_arg_list_new
252
static void template_arg_list_delete
253
PARAMS ((template_arg_list_t));
254
static void template_arg_list_add_arg
255
PARAMS ((template_arg_list_t, string_list_t));
256
static string_list_t template_arg_list_get_arg
257
PARAMS ((template_arg_list_t, int));
258
static void push_template_arg_list
259
PARAMS ((demangling_t, template_arg_list_t));
260
static void pop_to_template_arg_list
261
PARAMS ((demangling_t, template_arg_list_t));
262
#ifdef CP_DEMANGLE_DEBUG
263
static void template_arg_list_print
264
PARAMS ((template_arg_list_t, FILE *));
266
static template_arg_list_t current_template_arg_list
267
PARAMS ((demangling_t));
268
static demangling_t demangling_new
269
PARAMS ((const char *, int));
270
static void demangling_delete
271
PARAMS ((demangling_t));
273
/* The last character of DS. Warning: DS is evaluated twice. */
274
#define dyn_string_last_char(DS) \
275
(dyn_string_buf (DS)[dyn_string_length (DS) - 1])
277
/* Append a space character (` ') to DS if it does not already end
278
with one. Evaluates to 1 on success, or 0 on allocation failure. */
279
#define dyn_string_append_space(DS) \
280
((dyn_string_length (DS) > 0 \
281
&& dyn_string_last_char (DS) != ' ') \
282
? dyn_string_append_char ((DS), ' ') \
285
/* Returns the index of the current position in the mangled name. */
286
#define current_position(DM) ((DM)->next - (DM)->name)
288
/* Returns the character at the current position of the mangled name. */
289
#define peek_char(DM) (*((DM)->next))
291
/* Returns the character one past the current position of the mangled
293
#define peek_char_next(DM) \
294
(peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
296
/* Returns the character at the current position, and advances the
297
current position to the next character. */
298
#define next_char(DM) (*((DM)->next)++)
300
/* Returns non-zero if the current position is the end of the mangled
301
name, i.e. one past the last character. */
302
#define end_of_name_p(DM) (peek_char (DM) == '\0')
304
/* Advances the current position by one character. */
305
#define advance_char(DM) (++(DM)->next)
307
/* Returns the string containing the current demangled result. */
308
#define result_string(DM) (&(DM)->result->string)
310
/* Returns the position at which new text is inserted into the
312
#define result_caret_pos(DM) \
313
(result_length (DM) + \
314
((string_list_t) result_string (DM))->caret_position)
316
/* Adds a dyn_string_t to the demangled result. */
317
#define result_add_string(DM, STRING) \
318
(dyn_string_insert (&(DM)->result->string, \
319
result_caret_pos (DM), (STRING)) \
320
? STATUS_OK : STATUS_ALLOCATION_FAILED)
322
/* Adds NUL-terminated string CSTR to the demangled result. */
323
#define result_add(DM, CSTR) \
324
(dyn_string_insert_cstr (&(DM)->result->string, \
325
result_caret_pos (DM), (CSTR)) \
326
? STATUS_OK : STATUS_ALLOCATION_FAILED)
328
/* Adds character CHAR to the demangled result. */
329
#define result_add_char(DM, CHAR) \
330
(dyn_string_insert_char (&(DM)->result->string, \
331
result_caret_pos (DM), (CHAR)) \
332
? STATUS_OK : STATUS_ALLOCATION_FAILED)
334
/* Inserts a dyn_string_t to the demangled result at position POS. */
335
#define result_insert_string(DM, POS, STRING) \
336
(dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
337
? STATUS_OK : STATUS_ALLOCATION_FAILED)
339
/* Inserts NUL-terminated string CSTR to the demangled result at
341
#define result_insert(DM, POS, CSTR) \
342
(dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
343
? STATUS_OK : STATUS_ALLOCATION_FAILED)
345
/* Inserts character CHAR to the demangled result at position POS. */
346
#define result_insert_char(DM, POS, CHAR) \
347
(dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
348
? STATUS_OK : STATUS_ALLOCATION_FAILED)
350
/* The length of the current demangled result. */
351
#define result_length(DM) \
352
dyn_string_length (&(DM)->result->string)
354
/* Appends a (less-than, greater-than) character to the result in DM
355
to (open, close) a template argument or parameter list. Appends a
356
space first if necessary to prevent spurious elision of angle
357
brackets with the previous character. */
358
#define result_open_template_list(DM) result_add_separated_char(DM, '<')
359
#define result_close_template_list(DM) result_add_separated_char(DM, '>')
361
/* Appends a base 10 representation of VALUE to DS. STATUS_OK on
362
success. On failure, deletes DS and returns an error code. */
365
int_to_dyn_string (value, ds)
372
/* Handle zero up front. */
375
if (!dyn_string_append_char (ds, '0'))
376
return STATUS_ALLOCATION_FAILED;
380
/* For negative numbers, emit a minus sign. */
383
if (!dyn_string_append_char (ds, '-'))
384
return STATUS_ALLOCATION_FAILED;
388
/* Find the power of 10 of the first digit. */
396
/* Write the digits. */
399
int digit = value / mask;
401
if (!dyn_string_append_char (ds, '0' + digit))
402
return STATUS_ALLOCATION_FAILED;
404
value -= digit * mask;
411
/* Creates a new string list node. The contents of the string are
412
empty, but the initial buffer allocation is LENGTH. The string
413
list node should be deleted with string_list_delete. Returns NULL
414
if allocation fails. */
417
string_list_new (length)
420
string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
421
s->caret_position = 0;
424
if (!dyn_string_init ((dyn_string_t) s, length))
429
/* Deletes the entire string list starting at NODE. */
432
string_list_delete (node)
437
string_list_t next = node->next;
438
dyn_string_delete ((dyn_string_t) node);
443
/* Appends CHARACTER to the demangled result. If the current trailing
444
character of the result is CHARACTER, a space is inserted first. */
447
result_add_separated_char (dm, character)
451
char *result = dyn_string_buf (result_string (dm));
452
int caret_pos = result_caret_pos (dm);
454
/* Add a space if the last character is already the character we
456
if (caret_pos > 0 && result[caret_pos - 1] == character)
457
RETURN_IF_ERROR (result_add_char (dm, ' '));
458
/* Add the character. */
459
RETURN_IF_ERROR (result_add_char (dm, character));
464
/* Allocates and pushes a new string onto the demangled results stack
465
for DM. Subsequent demangling with DM will emit to the new string.
466
Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
467
allocation failure. */
473
string_list_t new_string = string_list_new (0);
474
if (new_string == NULL)
475
/* Allocation failed. */
476
return STATUS_ALLOCATION_FAILED;
478
/* Link the new string to the front of the list of result strings. */
479
new_string->next = (string_list_t) dm->result;
480
dm->result = new_string;
484
/* Removes and returns the topmost element on the demangled results
485
stack for DM. The caller assumes ownership for the returned
492
string_list_t top = dm->result;
493
dm->result = top->next;
497
/* Returns the current value of the caret for the result string. The
498
value is an offet from the end of the result string. */
501
result_get_caret (dm)
504
return ((string_list_t) result_string (dm))->caret_position;
507
/* Sets the value of the caret for the result string, counted as an
508
offet from the end of the result string. */
511
result_set_caret (dm, position)
515
((string_list_t) result_string (dm))->caret_position = position;
518
/* Shifts the position of the next addition to the result by
519
POSITION_OFFSET. A negative value shifts the caret to the left. */
522
result_shift_caret (dm, position_offset)
526
((string_list_t) result_string (dm))->caret_position += position_offset;
529
/* Returns non-zero if the character that comes right before the place
530
where text will be added to the result is a space. In this case,
531
the caller should supress adding another space. */
534
result_previous_char_is_space (dm)
537
char *result = dyn_string_buf (result_string (dm));
538
int pos = result_caret_pos (dm);
539
return pos > 0 && result[pos - 1] == ' ';
542
/* Returns the start position of a fragment of the demangled result
543
that will be a substitution candidate. Should be called at the
544
start of productions that can add substitutions. */
547
substitution_start (dm)
550
return result_caret_pos (dm);
553
/* Adds the suffix of the current demangled result of DM starting at
554
START_POSITION as a potential substitution. If TEMPLATE_P is
555
non-zero, this potential substitution is a template-id. */
558
substitution_add (dm, start_position, template_p)
563
dyn_string_t result = result_string (dm);
564
dyn_string_t substitution = dyn_string_new (0);
567
if (substitution == NULL)
568
return STATUS_ALLOCATION_FAILED;
570
/* Extract the substring of the current demangling result that
571
represents the subsitution candidate. */
572
if (!dyn_string_substring (substitution,
573
result, start_position, result_caret_pos (dm)))
575
dyn_string_delete (substitution);
576
return STATUS_ALLOCATION_FAILED;
579
/* If there's no room for the new entry, grow the array. */
580
if (dm->substitutions_allocated == dm->num_substitutions)
582
size_t new_array_size;
583
if (dm->substitutions_allocated > 0)
584
dm->substitutions_allocated *= 2;
586
dm->substitutions_allocated = 2;
588
sizeof (struct substitution_def) * dm->substitutions_allocated;
590
dm->substitutions = (struct substitution_def *)
591
realloc (dm->substitutions, new_array_size);
592
if (dm->substitutions == NULL)
593
/* Realloc failed. */
595
dyn_string_delete (substitution);
596
return STATUS_ALLOCATION_FAILED;
600
/* Add the substitution to the array. */
601
i = dm->num_substitutions++;
602
dm->substitutions[i].text = substitution;
603
dm->substitutions[i].template_p = template_p;
605
#ifdef CP_DEMANGLE_DEBUG
606
substitutions_print (dm, stderr);
612
/* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
613
non-zero if the substitution is a template-id, zero otherwise.
614
N is numbered from zero. DM retains ownership of the returned
615
string. If N is negative, or equal to or greater than the current
616
number of substitution candidates, returns NULL. */
619
substitution_get (dm, n, template_p)
624
struct substitution_def *sub;
626
/* Make sure N is in the valid range. */
627
if (n < 0 || n >= dm->num_substitutions)
630
sub = &(dm->substitutions[n]);
631
*template_p = sub->template_p;
635
#ifdef CP_DEMANGLE_DEBUG
636
/* Debugging routine to print the current substitutions to FP. */
639
substitutions_print (dm, fp)
644
int num = dm->num_substitutions;
646
fprintf (fp, "SUBSTITUTIONS:\n");
647
for (seq_id = -1; seq_id < num - 1; ++seq_id)
650
dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
653
fprintf (fp, " S_ ");
655
fprintf (fp, " S%d_", seq_id);
656
fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
660
#endif /* CP_DEMANGLE_DEBUG */
662
/* Creates a new template argument list. Returns NULL if allocation
665
static template_arg_list_t
666
template_arg_list_new ()
668
template_arg_list_t new_list =
669
(template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
670
if (new_list == NULL)
672
/* Initialize the new list to have no arguments. */
673
new_list->first_argument = NULL;
674
new_list->last_argument = NULL;
675
/* Return the new list. */
679
/* Deletes a template argument list and the template arguments it
683
template_arg_list_delete (list)
684
template_arg_list_t list;
686
/* If there are any arguments on LIST, delete them. */
687
if (list->first_argument != NULL)
688
string_list_delete (list->first_argument);
693
/* Adds ARG to the template argument list ARG_LIST. */
696
template_arg_list_add_arg (arg_list, arg)
697
template_arg_list_t arg_list;
700
if (arg_list->first_argument == NULL)
701
/* If there were no arguments before, ARG is the first one. */
702
arg_list->first_argument = arg;
704
/* Make ARG the last argument on the list. */
705
arg_list->last_argument->next = arg;
706
/* Make ARG the last on the list. */
707
arg_list->last_argument = arg;
711
/* Returns the template arugment at position INDEX in template
712
argument list ARG_LIST. */
715
template_arg_list_get_arg (arg_list, index)
716
template_arg_list_t arg_list;
719
string_list_t arg = arg_list->first_argument;
720
/* Scan down the list of arguments to find the one at position
726
/* Ran out of arguments before INDEX hit zero. That's an
730
/* Return the argument at position INDEX. */
734
/* Pushes ARG_LIST onto the top of the template argument list stack. */
737
push_template_arg_list (dm, arg_list)
739
template_arg_list_t arg_list;
741
arg_list->next = dm->template_arg_lists;
742
dm->template_arg_lists = arg_list;
743
#ifdef CP_DEMANGLE_DEBUG
744
fprintf (stderr, " ** pushing template arg list\n");
745
template_arg_list_print (arg_list, stderr);
749
/* Pops and deletes elements on the template argument list stack until
750
arg_list is the topmost element. If arg_list is NULL, all elements
751
are popped and deleted. */
754
pop_to_template_arg_list (dm, arg_list)
756
template_arg_list_t arg_list;
758
while (dm->template_arg_lists != arg_list)
760
template_arg_list_t top = dm->template_arg_lists;
761
/* Disconnect the topmost element from the list. */
762
dm->template_arg_lists = top->next;
763
/* Delete the popped element. */
764
template_arg_list_delete (top);
765
#ifdef CP_DEMANGLE_DEBUG
766
fprintf (stderr, " ** removing template arg list\n");
771
#ifdef CP_DEMANGLE_DEBUG
773
/* Prints the contents of ARG_LIST to FP. */
776
template_arg_list_print (arg_list, fp)
777
template_arg_list_t arg_list;
783
fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
784
for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
787
fprintf (fp, " T_ : ");
789
fprintf (fp, " T%d_ : ", index);
791
fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
795
#endif /* CP_DEMANGLE_DEBUG */
797
/* Returns the topmost element on the stack of template argument
798
lists. If there is no list of template arguments, returns NULL. */
800
static template_arg_list_t
801
current_template_arg_list (dm)
804
return dm->template_arg_lists;
807
/* Allocates a demangling_t object for demangling mangled NAME. A new
808
result must be pushed before the returned object can be used.
809
Returns NULL if allocation fails. */
812
demangling_new (name, style)
817
dm = (demangling_t) malloc (sizeof (struct demangling_def));
824
dm->num_substitutions = 0;
825
dm->substitutions_allocated = 10;
826
dm->template_arg_lists = NULL;
827
dm->last_source_name = dyn_string_new (0);
828
if (dm->last_source_name == NULL)
830
dm->substitutions = (struct substitution_def *)
831
malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
832
if (dm->substitutions == NULL)
834
dyn_string_delete (dm->last_source_name);
838
dm->is_constructor = 0;
839
dm->is_destructor = 0;
844
/* Deallocates a demangling_t object and all memory associated with
848
demangling_delete (dm)
852
template_arg_list_t arg_list = dm->template_arg_lists;
854
/* Delete the stack of template argument lists. */
855
while (arg_list != NULL)
857
template_arg_list_t next = arg_list->next;
858
template_arg_list_delete (arg_list);
861
/* Delete the list of substitutions. */
862
for (i = dm->num_substitutions; --i >= 0; )
863
dyn_string_delete (dm->substitutions[i].text);
864
free (dm->substitutions);
865
/* Delete the demangled result. */
866
string_list_delete (dm->result);
867
/* Delete the stored identifier name. */
868
dyn_string_delete (dm->last_source_name);
869
/* Delete the context object itself. */
873
/* These functions demangle an alternative of the corresponding
874
production in the mangling spec. The first argument of each is a
875
demangling context structure for the current demangling
876
operation. Most emit demangled text directly to the topmost result
877
string on the result string stack in the demangling context
880
static status_t demangle_char
881
PARAMS ((demangling_t, int));
882
static status_t demangle_mangled_name
883
PARAMS ((demangling_t));
884
static status_t demangle_encoding
885
PARAMS ((demangling_t));
886
static status_t demangle_name
887
PARAMS ((demangling_t, int *));
888
static status_t demangle_nested_name
889
PARAMS ((demangling_t, int *));
890
static status_t demangle_prefix
891
PARAMS ((demangling_t, int *));
892
static status_t demangle_unqualified_name
893
PARAMS ((demangling_t, int *));
894
static status_t demangle_source_name
895
PARAMS ((demangling_t));
896
static status_t demangle_number
897
PARAMS ((demangling_t, int *, int, int));
898
static status_t demangle_number_literally
899
PARAMS ((demangling_t, dyn_string_t, int, int));
900
static status_t demangle_identifier
901
PARAMS ((demangling_t, int, dyn_string_t));
902
static status_t demangle_operator_name
903
PARAMS ((demangling_t, int, int *, int *));
904
static status_t demangle_nv_offset
905
PARAMS ((demangling_t));
906
static status_t demangle_v_offset
907
PARAMS ((demangling_t));
908
static status_t demangle_call_offset
909
PARAMS ((demangling_t));
910
static status_t demangle_special_name
911
PARAMS ((demangling_t));
912
static status_t demangle_ctor_dtor_name
913
PARAMS ((demangling_t));
914
static status_t demangle_type_ptr
915
PARAMS ((demangling_t, int *, int));
916
static status_t demangle_type
917
PARAMS ((demangling_t));
918
static status_t demangle_CV_qualifiers
919
PARAMS ((demangling_t, dyn_string_t));
920
static status_t demangle_builtin_type
921
PARAMS ((demangling_t));
922
static status_t demangle_function_type
923
PARAMS ((demangling_t, int *));
924
static status_t demangle_bare_function_type
925
PARAMS ((demangling_t, int *));
926
static status_t demangle_class_enum_type
927
PARAMS ((demangling_t, int *));
928
static status_t demangle_array_type
929
PARAMS ((demangling_t, int *));
930
static status_t demangle_template_param
931
PARAMS ((demangling_t));
932
static status_t demangle_template_args
933
PARAMS ((demangling_t));
934
static status_t demangle_literal
935
PARAMS ((demangling_t));
936
static status_t demangle_template_arg
937
PARAMS ((demangling_t));
938
static status_t demangle_expression
939
PARAMS ((demangling_t));
940
static status_t demangle_scope_expression
941
PARAMS ((demangling_t));
942
static status_t demangle_expr_primary
943
PARAMS ((demangling_t));
944
static status_t demangle_substitution
945
PARAMS ((demangling_t, int *));
946
static status_t demangle_local_name
947
PARAMS ((demangling_t));
948
static status_t demangle_discriminator
949
PARAMS ((demangling_t, int));
950
static status_t cp_demangle
951
PARAMS ((const char *, dyn_string_t, int));
952
static status_t cp_demangle_type
953
PARAMS ((const char*, dyn_string_t));
955
/* When passed to demangle_bare_function_type, indicates that the
956
function's return type is not encoded before its parameter types. */
957
#define BFT_NO_RETURN_TYPE NULL
959
/* Check that the next character is C. If so, consume it. If not,
963
demangle_char (dm, c)
967
static char *error_message = NULL;
969
if (peek_char (dm) == c)
976
if (error_message == NULL)
977
error_message = strdup ("Expected ?");
978
error_message[9] = c;
979
return error_message;
983
/* Demangles and emits a <mangled-name>.
985
<mangled-name> ::= _Z <encoding> */
988
demangle_mangled_name (dm)
991
DEMANGLE_TRACE ("mangled-name", dm);
992
RETURN_IF_ERROR (demangle_char (dm, '_'));
993
RETURN_IF_ERROR (demangle_char (dm, 'Z'));
994
RETURN_IF_ERROR (demangle_encoding (dm));
998
/* Demangles and emits an <encoding>.
1000
<encoding> ::= <function name> <bare-function-type>
1002
::= <special-name> */
1005
demangle_encoding (dm)
1008
int encode_return_type;
1010
template_arg_list_t old_arg_list = current_template_arg_list (dm);
1011
char peek = peek_char (dm);
1013
DEMANGLE_TRACE ("encoding", dm);
1015
/* Remember where the name starts. If it turns out to be a template
1016
function, we'll have to insert the return type here. */
1017
start_position = result_caret_pos (dm);
1019
if (peek == 'G' || peek == 'T')
1020
RETURN_IF_ERROR (demangle_special_name (dm));
1023
/* Now demangle the name. */
1024
RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
1026
/* If there's anything left, the name was a function name, with
1027
maybe its return type, and its parameter types, following. */
1028
if (!end_of_name_p (dm)
1029
&& peek_char (dm) != 'E')
1031
if (encode_return_type)
1032
/* Template functions have their return type encoded. The
1033
return type should be inserted at start_position. */
1035
(demangle_bare_function_type (dm, &start_position));
1037
/* Non-template functions don't have their return type
1040
(demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
1044
/* Pop off template argument lists that were built during the
1045
mangling of this name, to restore the old template context. */
1046
pop_to_template_arg_list (dm, old_arg_list);
1051
/* Demangles and emits a <name>.
1053
<name> ::= <unscoped-name>
1054
::= <unscoped-template-name> <template-args>
1058
<unscoped-name> ::= <unqualified-name>
1059
::= St <unqualified-name> # ::std::
1061
<unscoped-template-name>
1063
::= <substitution> */
1066
demangle_name (dm, encode_return_type)
1068
int *encode_return_type;
1070
int start = substitution_start (dm);
1071
char peek = peek_char (dm);
1072
int is_std_substitution = 0;
1074
/* Generally, the return type is encoded if the function is a
1075
template-id, and suppressed otherwise. There are a few cases,
1076
though, in which the return type is not encoded even for a
1077
templated function. In these cases, this flag is set. */
1078
int suppress_return_type = 0;
1080
DEMANGLE_TRACE ("name", dm);
1085
/* This is a <nested-name>. */
1086
RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type));
1090
RETURN_IF_ERROR (demangle_local_name (dm));
1091
*encode_return_type = 0;
1095
/* The `St' substitution allows a name nested in std:: to appear
1096
without being enclosed in a nested name. */
1097
if (peek_char_next (dm) == 't')
1099
(void) next_char (dm);
1100
(void) next_char (dm);
1101
RETURN_IF_ERROR (result_add (dm, "std::"));
1103
(demangle_unqualified_name (dm, &suppress_return_type));
1104
is_std_substitution = 1;
1107
RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1108
/* Check if a template argument list immediately follows.
1109
If so, then we just demangled an <unqualified-template-name>. */
1110
if (peek_char (dm) == 'I')
1112
/* A template name of the form std::<unqualified-name> is a
1113
substitution candidate. */
1114
if (is_std_substitution)
1115
RETURN_IF_ERROR (substitution_add (dm, start, 0));
1116
/* Demangle the <template-args> here. */
1117
RETURN_IF_ERROR (demangle_template_args (dm));
1118
*encode_return_type = !suppress_return_type;
1121
*encode_return_type = 0;
1126
/* This is an <unscoped-name> or <unscoped-template-name>. */
1127
RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type));
1129
/* If the <unqualified-name> is followed by template args, this
1130
is an <unscoped-template-name>. */
1131
if (peek_char (dm) == 'I')
1133
/* Add a substitution for the unqualified template name. */
1134
RETURN_IF_ERROR (substitution_add (dm, start, 0));
1136
RETURN_IF_ERROR (demangle_template_args (dm));
1137
*encode_return_type = !suppress_return_type;
1140
*encode_return_type = 0;
1148
/* Demangles and emits a <nested-name>.
1150
<nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1153
demangle_nested_name (dm, encode_return_type)
1155
int *encode_return_type;
1159
DEMANGLE_TRACE ("nested-name", dm);
1161
RETURN_IF_ERROR (demangle_char (dm, 'N'));
1163
peek = peek_char (dm);
1164
if (peek == 'r' || peek == 'V' || peek == 'K')
1166
dyn_string_t cv_qualifiers;
1169
/* Snarf up CV qualifiers. */
1170
cv_qualifiers = dyn_string_new (24);
1171
if (cv_qualifiers == NULL)
1172
return STATUS_ALLOCATION_FAILED;
1173
demangle_CV_qualifiers (dm, cv_qualifiers);
1175
/* Emit them, preceded by a space. */
1176
status = result_add_char (dm, ' ');
1177
if (STATUS_NO_ERROR (status))
1178
status = result_add_string (dm, cv_qualifiers);
1179
/* The CV qualifiers that occur in a <nested-name> will be
1180
qualifiers for member functions. These are placed at the end
1181
of the function. Therefore, shift the caret to the left by
1182
the length of the qualifiers, so other text is inserted
1183
before them and they stay at the end. */
1184
result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1);
1186
dyn_string_delete (cv_qualifiers);
1187
RETURN_IF_ERROR (status);
1190
RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
1191
/* No need to demangle the final <unqualified-name>; demangle_prefix
1193
RETURN_IF_ERROR (demangle_char (dm, 'E'));
1198
/* Demangles and emits a <prefix>.
1200
<prefix> ::= <prefix> <unqualified-name>
1201
::= <template-prefix> <template-args>
1205
<template-prefix> ::= <prefix>
1206
::= <substitution> */
1209
demangle_prefix (dm, encode_return_type)
1211
int *encode_return_type;
1213
int start = substitution_start (dm);
1216
/* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1217
After <template-args>, it is set to non-zero; after everything
1218
else it is set to zero. */
1220
/* Generally, the return type is encoded if the function is a
1221
template-id, and suppressed otherwise. There are a few cases,
1222
though, in which the return type is not encoded even for a
1223
templated function. In these cases, this flag is set. */
1224
int suppress_return_type = 0;
1226
DEMANGLE_TRACE ("prefix", dm);
1232
if (end_of_name_p (dm))
1233
return "Unexpected end of name in <compound-name>.";
1235
peek = peek_char (dm);
1237
/* We'll initialize suppress_return_type to false, and set it to true
1238
if we end up demangling a constructor name. However, make
1239
sure we're not actually about to demangle template arguments
1240
-- if so, this is the <template-args> following a
1241
<template-prefix>, so we'll want the previous flag value
1244
suppress_return_type = 0;
1246
if (IS_DIGIT ((unsigned char) peek)
1247
|| (peek >= 'a' && peek <= 'z')
1248
|| peek == 'C' || peek == 'D'
1251
/* We have another level of scope qualification. */
1253
RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR));
1258
/* The substitution determines whether this is a
1260
RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1263
/* It's just a name. */
1265
(demangle_unqualified_name (dm, &suppress_return_type));
1266
*encode_return_type = 0;
1269
else if (peek == 'Z')
1270
RETURN_IF_ERROR (demangle_local_name (dm));
1271
else if (peek == 'I')
1273
RETURN_IF_ERROR (demangle_template_args (dm));
1275
/* Now we want to indicate to the caller that we've
1276
demangled template arguments, thus the prefix was a
1277
<template-prefix>. That's so that the caller knows to
1278
demangle the function's return type, if this turns out to
1279
be a function name. But, if it's a member template
1280
constructor or a templated conversion operator, report it
1281
as untemplated. Those never get encoded return types. */
1282
*encode_return_type = !suppress_return_type;
1284
else if (peek == 'E')
1288
return "Unexpected character in <compound-name>.";
1291
&& peek_char (dm) != 'E')
1292
/* Add a new substitution for the prefix thus far. */
1293
RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type));
1297
/* Demangles and emits an <unqualified-name>. If this
1298
<unqualified-name> is for a special function type that should never
1299
have its return type encoded (particularly, a constructor or
1300
conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1303
<unqualified-name> ::= <operator-name>
1305
::= <source-name> */
1308
demangle_unqualified_name (dm, suppress_return_type)
1310
int *suppress_return_type;
1312
char peek = peek_char (dm);
1314
DEMANGLE_TRACE ("unqualified-name", dm);
1316
/* By default, don't force suppression of the return type (though
1317
non-template functions still don't get a return type encoded). */
1318
*suppress_return_type = 0;
1320
if (IS_DIGIT ((unsigned char) peek))
1321
RETURN_IF_ERROR (demangle_source_name (dm));
1322
else if (peek >= 'a' && peek <= 'z')
1326
/* Conversion operators never have a return type encoded. */
1327
if (peek == 'c' && peek_char_next (dm) == 'v')
1328
*suppress_return_type = 1;
1330
RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
1332
else if (peek == 'C' || peek == 'D')
1334
/* Constructors never have a return type encoded. */
1336
*suppress_return_type = 1;
1338
RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1341
return "Unexpected character in <unqualified-name>.";
1346
/* Demangles and emits <source-name>.
1348
<source-name> ::= <length number> <identifier> */
1351
demangle_source_name (dm)
1356
DEMANGLE_TRACE ("source-name", dm);
1358
/* Decode the length of the identifier. */
1359
RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1361
return "Zero length in <source-name>.";
1363
/* Now the identifier itself. It's placed into last_source_name,
1364
where it can be used to build a constructor or destructor name. */
1365
RETURN_IF_ERROR (demangle_identifier (dm, length,
1366
dm->last_source_name));
1369
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
1374
/* Demangles a number, either a <number> or a <positive-number> at the
1375
current position, consuming all consecutive digit characters. Sets
1376
*VALUE to the resulting numberand returns STATUS_OK. The number is
1377
interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1378
is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1380
<number> ::= [n] <positive-number>
1382
<positive-number> ::= <decimal integer> */
1385
demangle_number (dm, value, base, is_signed)
1391
dyn_string_t number = dyn_string_new (10);
1393
DEMANGLE_TRACE ("number", dm);
1396
return STATUS_ALLOCATION_FAILED;
1398
demangle_number_literally (dm, number, base, is_signed);
1399
*value = strtol (dyn_string_buf (number), NULL, base);
1400
dyn_string_delete (number);
1405
/* Demangles a number at the current position. The digits (and minus
1406
sign, if present) that make up the number are appended to STR.
1407
Only base-BASE digits are accepted; BASE must be either 10 or 36.
1408
If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1409
accepted. Does not consume a trailing underscore or other
1410
terminating character. */
1413
demangle_number_literally (dm, str, base, is_signed)
1419
DEMANGLE_TRACE ("number*", dm);
1421
if (base != 10 && base != 36)
1422
return STATUS_INTERNAL_ERROR;
1424
/* An `n' denotes a negative number. */
1425
if (is_signed && peek_char (dm) == 'n')
1427
/* Skip past the n. */
1429
/* The normal way to write a negative number is with a minus
1431
if (!dyn_string_append_char (str, '-'))
1432
return STATUS_ALLOCATION_FAILED;
1435
/* Loop until we hit a non-digit. */
1438
char peek = peek_char (dm);
1439
if (IS_DIGIT ((unsigned char) peek)
1440
|| (base == 36 && peek >= 'A' && peek <= 'Z'))
1442
/* Accumulate digits. */
1443
if (!dyn_string_append_char (str, next_char (dm)))
1444
return STATUS_ALLOCATION_FAILED;
1447
/* Not a digit? All done. */
1454
/* Demangles an identifier at the current position of LENGTH
1455
characters and places it in IDENTIFIER. */
1458
demangle_identifier (dm, length, identifier)
1461
dyn_string_t identifier;
1463
DEMANGLE_TRACE ("identifier", dm);
1465
dyn_string_clear (identifier);
1466
if (!dyn_string_resize (identifier, length))
1467
return STATUS_ALLOCATION_FAILED;
1469
while (length-- > 0)
1472
if (end_of_name_p (dm))
1473
return "Unexpected end of name in <identifier>.";
1474
ch = next_char (dm);
1476
/* Handle extended Unicode characters. We encode them as __U{hex}_,
1477
where {hex} omits leading 0's. For instance, '$' is encoded as
1480
&& peek_char (dm) == '_'
1481
&& peek_char_next (dm) == 'U')
1485
advance_char (dm); advance_char (dm); length -= 2;
1486
while (length-- > 0)
1488
ch = next_char (dm);
1493
if (ch != '_' || length < 0)
1494
return STATUS_ERROR;
1497
/* __U_ just means __U. */
1498
if (!dyn_string_append_cstr (identifier, "__U"))
1499
return STATUS_ALLOCATION_FAILED;
1505
ch = strtol (buf, 0, 16);
1509
if (!dyn_string_append_char (identifier, ch))
1510
return STATUS_ALLOCATION_FAILED;
1513
/* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1514
followed by the source file name and some random characters.
1515
Unless we're in strict mode, decipher these names appropriately. */
1518
char *name = dyn_string_buf (identifier);
1519
int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
1521
/* Compare the first, fixed part. */
1522
if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
1524
name += prefix_length;
1525
/* The next character might be a period, an underscore, or
1526
dollar sign, depending on the target architecture's
1527
assembler's capabilities. After that comes an `N'. */
1528
if ((*name == '.' || *name == '_' || *name == '$')
1529
&& *(name + 1) == 'N')
1530
/* This looks like the anonymous namespace identifier.
1531
Replace it with something comprehensible. */
1532
dyn_string_copy_cstr (identifier, "(anonymous namespace)");
1539
/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1540
the short form is emitted; otherwise the full source form
1541
(`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1542
operands that the operator takes. If TYPE_ARG is non-NULL,
1543
*TYPE_ARG is set to 1 if the first argument is a type and 0
1594
::= st # sizeof (a type)
1595
::= sz # sizeof (an expression)
1596
::= cv <type> # cast
1597
::= v [0-9] <source-name> # vendor extended operator */
1600
demangle_operator_name (dm, short_name, num_args, type_arg)
1606
struct operator_code
1608
/* The mangled code for this operator. */
1609
const char *const code;
1610
/* The source name of this operator. */
1611
const char *const name;
1612
/* The number of arguments this operator takes. */
1616
static const struct operator_code operators[] =
1627
{ "da", " delete[]", 1 },
1629
{ "dl", " delete" , 1 },
1637
{ "lS", "<<=" , 2 },
1646
{ "na", " new[]" , 1 },
1650
{ "nw", " new" , 1 },
1656
{ "pm", "->*" , 2 },
1662
{ "rS", ">>=" , 2 },
1665
{ "sz", " sizeof" , 1 }
1668
const int num_operators =
1669
sizeof (operators) / sizeof (struct operator_code);
1671
int c0 = next_char (dm);
1672
int c1 = next_char (dm);
1673
const struct operator_code* p1 = operators;
1674
const struct operator_code* p2 = operators + num_operators;
1676
DEMANGLE_TRACE ("operator-name", dm);
1678
/* Assume the first argument is not a type. */
1682
/* Is this a vendor-extended operator? */
1683
if (c0 == 'v' && IS_DIGIT (c1))
1685
RETURN_IF_ERROR (result_add (dm, "operator "));
1686
RETURN_IF_ERROR (demangle_source_name (dm));
1691
/* Is this a conversion operator? */
1692
if (c0 == 'c' && c1 == 'v')
1694
RETURN_IF_ERROR (result_add (dm, "operator "));
1695
/* Demangle the converted-to type. */
1696
RETURN_IF_ERROR (demangle_type (dm));
1701
/* Is it the sizeof variant that takes a type? */
1702
if (c0 == 's' && c1 == 't')
1704
RETURN_IF_ERROR (result_add (dm, " sizeof"));
1711
/* Perform a binary search for the operator code. */
1714
const struct operator_code* p = p1 + (p2 - p1) / 2;
1715
char match0 = p->code[0];
1716
char match1 = p->code[1];
1718
if (c0 == match0 && c1 == match1)
1722
RETURN_IF_ERROR (result_add (dm, "operator"));
1723
RETURN_IF_ERROR (result_add (dm, p->name));
1724
*num_args = p->num_args;
1730
/* Couldn't find it. */
1731
return "Unknown code in <operator-name>.";
1734
if (c0 < match0 || (c0 == match0 && c1 < match1))
1741
/* Demangles and omits an <nv-offset>.
1743
<nv-offset> ::= <offset number> # non-virtual base override */
1746
demangle_nv_offset (dm)
1749
dyn_string_t number;
1750
status_t status = STATUS_OK;
1752
DEMANGLE_TRACE ("h-offset", dm);
1754
/* Demangle the offset. */
1755
number = dyn_string_new (4);
1757
return STATUS_ALLOCATION_FAILED;
1758
demangle_number_literally (dm, number, 10, 1);
1760
/* Don't display the offset unless in verbose mode. */
1763
status = result_add (dm, " [nv:");
1764
if (STATUS_NO_ERROR (status))
1765
status = result_add_string (dm, number);
1766
if (STATUS_NO_ERROR (status))
1767
status = result_add_char (dm, ']');
1771
dyn_string_delete (number);
1772
RETURN_IF_ERROR (status);
1776
/* Demangles and emits a <v-offset>.
1778
<v-offset> ::= <offset number> _ <virtual offset number>
1779
# virtual base override, with vcall offset */
1782
demangle_v_offset (dm)
1785
dyn_string_t number;
1786
status_t status = STATUS_OK;
1788
DEMANGLE_TRACE ("v-offset", dm);
1790
/* Demangle the offset. */
1791
number = dyn_string_new (4);
1793
return STATUS_ALLOCATION_FAILED;
1794
demangle_number_literally (dm, number, 10, 1);
1796
/* Don't display the offset unless in verbose mode. */
1799
status = result_add (dm, " [v:");
1800
if (STATUS_NO_ERROR (status))
1801
status = result_add_string (dm, number);
1802
if (STATUS_NO_ERROR (status))
1803
result_add_char (dm, ',');
1805
dyn_string_delete (number);
1806
RETURN_IF_ERROR (status);
1808
/* Demangle the separator. */
1809
RETURN_IF_ERROR (demangle_char (dm, '_'));
1811
/* Demangle the vcall offset. */
1812
number = dyn_string_new (4);
1814
return STATUS_ALLOCATION_FAILED;
1815
demangle_number_literally (dm, number, 10, 1);
1817
/* Don't display the vcall offset unless in verbose mode. */
1820
status = result_add_string (dm, number);
1821
if (STATUS_NO_ERROR (status))
1822
status = result_add_char (dm, ']');
1824
dyn_string_delete (number);
1825
RETURN_IF_ERROR (status);
1830
/* Demangles and emits a <call-offset>.
1832
<call-offset> ::= h <nv-offset> _
1833
::= v <v-offset> _ */
1836
demangle_call_offset (dm)
1839
DEMANGLE_TRACE ("call-offset", dm);
1841
switch (peek_char (dm))
1845
/* Demangle the offset. */
1846
RETURN_IF_ERROR (demangle_nv_offset (dm));
1847
/* Demangle the separator. */
1848
RETURN_IF_ERROR (demangle_char (dm, '_'));
1853
/* Demangle the offset. */
1854
RETURN_IF_ERROR (demangle_v_offset (dm));
1855
/* Demangle the separator. */
1856
RETURN_IF_ERROR (demangle_char (dm, '_'));
1860
return "Unrecognized <call-offset>.";
1866
/* Demangles and emits a <special-name>.
1868
<special-name> ::= GV <object name> # Guard variable
1869
::= TV <type> # virtual table
1871
::= TI <type> # typeinfo structure
1872
::= TS <type> # typeinfo name
1874
Other relevant productions include thunks:
1876
<special-name> ::= T <call-offset> <base encoding>
1877
# base is the nominal target function of thunk
1879
<special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1880
# base is the nominal target function of thunk
1881
# first call-offset is 'this' adjustment
1882
# second call-offset is result adjustment
1886
<call-offset> ::= h <nv-offset> _
1889
Also demangles the special g++ manglings,
1891
<special-name> ::= TC <type> <offset number> _ <base type>
1892
# construction vtable
1893
::= TF <type> # typeinfo function (old ABI only)
1894
::= TJ <type> # java Class structure */
1897
demangle_special_name (dm)
1900
dyn_string_t number;
1902
char peek = peek_char (dm);
1904
DEMANGLE_TRACE ("special-name", dm);
1908
/* Consume the G. */
1910
switch (peek_char (dm))
1913
/* A guard variable name. */
1915
RETURN_IF_ERROR (result_add (dm, "guard variable for "));
1916
RETURN_IF_ERROR (demangle_name (dm, &unused));
1920
/* A reference temporary. */
1922
RETURN_IF_ERROR (result_add (dm, "reference temporary for "));
1923
RETURN_IF_ERROR (demangle_name (dm, &unused));
1927
return "Unrecognized <special-name>.";
1930
else if (peek == 'T')
1932
status_t status = STATUS_OK;
1934
/* Other C++ implementation miscellania. Consume the T. */
1937
switch (peek_char (dm))
1940
/* Virtual table. */
1942
RETURN_IF_ERROR (result_add (dm, "vtable for "));
1943
RETURN_IF_ERROR (demangle_type (dm));
1947
/* VTT structure. */
1949
RETURN_IF_ERROR (result_add (dm, "VTT for "));
1950
RETURN_IF_ERROR (demangle_type (dm));
1954
/* Typeinfo structure. */
1956
RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
1957
RETURN_IF_ERROR (demangle_type (dm));
1961
/* Typeinfo function. Used only in old ABI with new mangling. */
1963
RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
1964
RETURN_IF_ERROR (demangle_type (dm));
1968
/* Character string containing type name, used in typeinfo. */
1970
RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
1971
RETURN_IF_ERROR (demangle_type (dm));
1975
/* The java Class variable corresponding to a C++ class. */
1977
RETURN_IF_ERROR (result_add (dm, "java Class for "));
1978
RETURN_IF_ERROR (demangle_type (dm));
1982
/* Non-virtual thunk. */
1984
RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
1985
RETURN_IF_ERROR (demangle_nv_offset (dm));
1986
/* Demangle the separator. */
1987
RETURN_IF_ERROR (demangle_char (dm, '_'));
1988
/* Demangle and emit the target name and function type. */
1989
RETURN_IF_ERROR (result_add (dm, " to "));
1990
RETURN_IF_ERROR (demangle_encoding (dm));
1994
/* Virtual thunk. */
1996
RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
1997
RETURN_IF_ERROR (demangle_v_offset (dm));
1998
/* Demangle the separator. */
1999
RETURN_IF_ERROR (demangle_char (dm, '_'));
2000
/* Demangle and emit the target function. */
2001
RETURN_IF_ERROR (result_add (dm, " to "));
2002
RETURN_IF_ERROR (demangle_encoding (dm));
2006
/* Covariant return thunk. */
2008
RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
2009
RETURN_IF_ERROR (demangle_call_offset (dm));
2010
RETURN_IF_ERROR (demangle_call_offset (dm));
2011
/* Demangle and emit the target function. */
2012
RETURN_IF_ERROR (result_add (dm, " to "));
2013
RETURN_IF_ERROR (demangle_encoding (dm));
2017
/* TC is a special g++ mangling for a construction vtable. */
2020
dyn_string_t derived_type;
2023
RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
2025
/* Demangle the derived type off to the side. */
2026
RETURN_IF_ERROR (result_push (dm));
2027
RETURN_IF_ERROR (demangle_type (dm));
2028
derived_type = (dyn_string_t) result_pop (dm);
2030
/* Demangle the offset. */
2031
number = dyn_string_new (4);
2034
dyn_string_delete (derived_type);
2035
return STATUS_ALLOCATION_FAILED;
2037
demangle_number_literally (dm, number, 10, 1);
2038
/* Demangle the underscore separator. */
2039
status = demangle_char (dm, '_');
2041
/* Demangle the base type. */
2042
if (STATUS_NO_ERROR (status))
2043
status = demangle_type (dm);
2045
/* Emit the derived type. */
2046
if (STATUS_NO_ERROR (status))
2047
status = result_add (dm, "-in-");
2048
if (STATUS_NO_ERROR (status))
2049
status = result_add_string (dm, derived_type);
2050
dyn_string_delete (derived_type);
2052
/* Don't display the offset unless in verbose mode. */
2055
status = result_add_char (dm, ' ');
2056
if (STATUS_NO_ERROR (status))
2057
result_add_string (dm, number);
2059
dyn_string_delete (number);
2060
RETURN_IF_ERROR (status);
2063
/* If flag_strict, fall through. */
2066
return "Unrecognized <special-name>.";
2070
return STATUS_ERROR;
2075
/* Demangles and emits a <ctor-dtor-name>.
2078
::= C1 # complete object (in-charge) ctor
2079
::= C2 # base object (not-in-charge) ctor
2080
::= C3 # complete object (in-charge) allocating ctor
2081
::= D0 # deleting (in-charge) dtor
2082
::= D1 # complete object (in-charge) dtor
2083
::= D2 # base object (not-in-charge) dtor */
2086
demangle_ctor_dtor_name (dm)
2089
static const char *const ctor_flavors[] =
2095
static const char *const dtor_flavors[] =
2097
"in-charge deleting",
2103
char peek = peek_char (dm);
2105
DEMANGLE_TRACE ("ctor-dtor-name", dm);
2109
/* A constructor name. Consume the C. */
2111
flavor = next_char (dm);
2112
if (flavor < '1' || flavor > '3')
2113
return "Unrecognized constructor.";
2114
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
2117
case '1': dm->is_constructor = gnu_v3_complete_object_ctor;
2119
case '2': dm->is_constructor = gnu_v3_base_object_ctor;
2121
case '3': dm->is_constructor = gnu_v3_complete_object_allocating_ctor;
2124
/* Print the flavor of the constructor if in verbose mode. */
2127
RETURN_IF_ERROR (result_add (dm, "["));
2128
RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor - '1']));
2129
RETURN_IF_ERROR (result_add_char (dm, ']'));
2132
else if (peek == 'D')
2134
/* A destructor name. Consume the D. */
2136
flavor = next_char (dm);
2137
if (flavor < '0' || flavor > '2')
2138
return "Unrecognized destructor.";
2139
RETURN_IF_ERROR (result_add_char (dm, '~'));
2140
RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
2143
case '0': dm->is_destructor = gnu_v3_deleting_dtor;
2145
case '1': dm->is_destructor = gnu_v3_complete_object_dtor;
2147
case '2': dm->is_destructor = gnu_v3_base_object_dtor;
2150
/* Print the flavor of the destructor if in verbose mode. */
2153
RETURN_IF_ERROR (result_add (dm, " ["));
2154
RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor - '0']));
2155
RETURN_IF_ERROR (result_add_char (dm, ']'));
2159
return STATUS_ERROR;
2164
/* Handle pointer, reference, and pointer-to-member cases for
2165
demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2166
build a pointer/reference type. We snarf all these, plus the
2167
following <type>, all at once since we need to know whether we have
2168
a pointer to data or pointer to function to construct the right
2169
output syntax. C++'s pointer syntax is hairy.
2171
This function adds substitution candidates for every nested
2172
pointer/reference type it processes, including the outermost, final
2173
type, assuming the substitution starts at SUBSTITUTION_START in the
2174
demangling result. For example, if this function demangles
2175
`PP3Foo', it will add a substitution for `Foo', `Foo*', and
2176
`Foo**', in that order.
2178
*INSERT_POS is a quantity used internally, when this function calls
2179
itself recursively, to figure out where to insert pointer
2180
punctuation on the way up. On entry to this function, INSERT_POS
2181
should point to a temporary value, but that value need not be
2186
::= <pointer-to-member-type>
2188
<pointer-to-member-type> ::= M </class/ type> </member/ type> */
2191
demangle_type_ptr (dm, insert_pos, substitution_start)
2194
int substitution_start;
2197
int is_substitution_candidate = 1;
2199
DEMANGLE_TRACE ("type*", dm);
2201
/* Scan forward, collecting pointers and references into symbols,
2202
until we hit something else. Then emit the type. */
2203
switch (peek_char (dm))
2206
/* A pointer. Snarf the `P'. */
2208
/* Demangle the underlying type. */
2209
RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2210
substitution_start));
2211
/* Insert an asterisk where we're told to; it doesn't
2212
necessarily go at the end. If we're doing Java style output,
2213
there is no pointer symbol. */
2214
if (dm->style != DMGL_JAVA)
2215
RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
2216
/* The next (outermost) pointer or reference character should go
2222
/* A reference. Snarf the `R'. */
2224
/* Demangle the underlying type. */
2225
RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2226
substitution_start));
2227
/* Insert an ampersand where we're told to; it doesn't
2228
necessarily go at the end. */
2229
RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
2230
/* The next (outermost) pointer or reference character should go
2237
/* A pointer-to-member. */
2238
dyn_string_t class_type;
2243
/* Capture the type of which this is a pointer-to-member. */
2244
RETURN_IF_ERROR (result_push (dm));
2245
RETURN_IF_ERROR (demangle_type (dm));
2246
class_type = (dyn_string_t) result_pop (dm);
2248
if (peek_char (dm) == 'F')
2249
/* A pointer-to-member function. We want output along the
2250
lines of `void (C::*) (int, int)'. Demangle the function
2251
type, which would in this case give `void () (int, int)'
2252
and set *insert_pos to the spot between the first
2254
status = demangle_type_ptr (dm, insert_pos, substitution_start);
2255
else if (peek_char (dm) == 'A')
2256
/* A pointer-to-member array variable. We want output that
2257
looks like `int (Klass::*) [10]'. Demangle the array type
2258
as `int () [10]', and set *insert_pos to the spot between
2260
status = demangle_array_type (dm, insert_pos);
2263
/* A pointer-to-member variable. Demangle the type of the
2264
pointed-to member. */
2265
status = demangle_type (dm);
2266
/* Make it pretty. */
2267
if (STATUS_NO_ERROR (status)
2268
&& !result_previous_char_is_space (dm))
2269
status = result_add_char (dm, ' ');
2270
/* The pointer-to-member notation (e.g. `C::*') follows the
2272
*insert_pos = result_caret_pos (dm);
2275
/* Build the pointer-to-member notation. */
2276
if (STATUS_NO_ERROR (status))
2277
status = result_insert (dm, *insert_pos, "::*");
2278
if (STATUS_NO_ERROR (status))
2279
status = result_insert_string (dm, *insert_pos, class_type);
2280
/* There may be additional levels of (pointer or reference)
2281
indirection in this type. If so, the `*' and `&' should be
2282
added after the pointer-to-member notation (e.g. `C::*&' for
2283
a reference to a pointer-to-member of class C). */
2284
*insert_pos += dyn_string_length (class_type) + 3;
2287
dyn_string_delete (class_type);
2289
RETURN_IF_ERROR (status);
2294
/* Ooh, tricky, a pointer-to-function. When we demangle the
2295
function type, the return type should go at the very
2297
*insert_pos = result_caret_pos (dm);
2298
/* The parentheses indicate this is a function pointer or
2300
RETURN_IF_ERROR (result_add (dm, "()"));
2301
/* Now demangle the function type. The return type will be
2302
inserted before the `()', and the argument list will go after
2304
RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
2305
/* We should now have something along the lines of
2306
`void () (int, int)'. The pointer or reference characters
2307
have to inside the first set of parentheses. *insert_pos has
2308
already been updated to point past the end of the return
2309
type. Move it one character over so it points inside the
2315
/* An array pointer or reference. demangle_array_type will figure
2316
out where the asterisks and ampersands go. */
2317
RETURN_IF_ERROR (demangle_array_type (dm, insert_pos));
2321
/* No more pointer or reference tokens; this is therefore a
2322
pointer to data. Finish up by demangling the underlying
2324
RETURN_IF_ERROR (demangle_type (dm));
2325
/* The pointer or reference characters follow the underlying
2326
type, as in `int*&'. */
2327
*insert_pos = result_caret_pos (dm);
2328
/* Because of the production <type> ::= <substitution>,
2329
demangle_type will already have added the underlying type as
2330
a substitution candidate. Don't do it again. */
2331
is_substitution_candidate = 0;
2335
if (is_substitution_candidate)
2336
RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
2341
/* Demangles and emits a <type>.
2343
<type> ::= <builtin-type>
2345
::= <class-enum-type>
2347
::= <pointer-to-member-type>
2348
::= <template-param>
2349
::= <template-template-param> <template-args>
2350
::= <CV-qualifiers> <type>
2351
::= P <type> # pointer-to
2352
::= R <type> # reference-to
2353
::= C <type> # complex pair (C 2000)
2354
::= G <type> # imaginary (C 2000)
2355
::= U <source-name> <type> # vendor extended type qualifier
2356
::= <substitution> */
2362
int start = substitution_start (dm);
2363
char peek = peek_char (dm);
2365
int encode_return_type = 0;
2366
template_arg_list_t old_arg_list = current_template_arg_list (dm);
2369
/* A <type> can be a <substitution>; therefore, this <type> is a
2370
substitution candidate unless a special condition holds (see
2372
int is_substitution_candidate = 1;
2374
DEMANGLE_TRACE ("type", dm);
2376
/* A <class-enum-type> can start with a digit (a <source-name>), an
2377
N (a <nested-name>), or a Z (a <local-name>). */
2378
if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
2379
RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type));
2380
/* Lower-case letters begin <builtin-type>s, except for `r', which
2381
denotes restrict. */
2382
else if (peek >= 'a' && peek <= 'z' && peek != 'r')
2384
RETURN_IF_ERROR (demangle_builtin_type (dm));
2385
/* Built-in types are not substitution candidates. */
2386
is_substitution_candidate = 0;
2394
/* CV-qualifiers (including restrict). We have to demangle
2395
them off to the side, since C++ syntax puts them in a funny
2396
place for qualified pointer and reference types. */
2399
dyn_string_t cv_qualifiers = dyn_string_new (24);
2400
int old_caret_position = result_get_caret (dm);
2402
if (cv_qualifiers == NULL)
2403
return STATUS_ALLOCATION_FAILED;
2405
/* Decode all adjacent CV qualifiers. */
2406
demangle_CV_qualifiers (dm, cv_qualifiers);
2407
/* Emit them, and shift the caret left so that the
2408
underlying type will be emitted before the qualifiers. */
2409
status = result_add_string (dm, cv_qualifiers);
2410
result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
2412
dyn_string_delete (cv_qualifiers);
2413
RETURN_IF_ERROR (status);
2414
/* Also prepend a blank, if needed. */
2415
RETURN_IF_ERROR (result_add_char (dm, ' '));
2416
result_shift_caret (dm, -1);
2418
/* Demangle the underlying type. It will be emitted before
2419
the CV qualifiers, since we moved the caret. */
2420
RETURN_IF_ERROR (demangle_type (dm));
2422
/* Put the caret back where it was previously. */
2423
result_set_caret (dm, old_caret_position);
2428
return "Non-pointer or -reference function type.";
2431
RETURN_IF_ERROR (demangle_array_type (dm, NULL));
2435
/* It's either a <template-param> or a
2436
<template-template-param>. In either case, demangle the
2438
RETURN_IF_ERROR (demangle_template_param (dm));
2440
/* Check for a template argument list; if one is found, it's a
2441
<template-template-param> ::= <template-param>
2442
::= <substitution> */
2443
if (peek_char (dm) == 'I')
2445
/* Add a substitution candidate. The template parameter
2446
`T' token is a substitution candidate by itself,
2447
without the template argument list. */
2448
RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2450
/* Now demangle the template argument list. */
2451
RETURN_IF_ERROR (demangle_template_args (dm));
2452
/* The entire type, including the template template
2453
parameter and its argument list, will be added as a
2454
substitution candidate below. */
2460
/* First check if this is a special substitution. If it is,
2461
this is a <class-enum-type>. Special substitutions have a
2462
letter following the `S'; other substitutions have a digit
2464
peek_next = peek_char_next (dm);
2465
if (IS_DIGIT (peek_next) || peek_next == '_')
2467
RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type));
2469
/* The substituted name may have been a template name.
2470
Check if template arguments follow, and if so, demangle
2472
if (peek_char (dm) == 'I')
2473
RETURN_IF_ERROR (demangle_template_args (dm));
2475
/* A substitution token is not itself a substitution
2476
candidate. (However, if the substituted template is
2477
instantiated, the resulting type is.) */
2478
is_substitution_candidate = 0;
2482
/* Now some trickiness. We have a special substitution
2483
here. Often, the special substitution provides the
2484
name of a template that's subsequently instantiated,
2485
for instance `SaIcE' => std::allocator<char>. In these
2486
cases we need to add a substitution candidate for the
2487
entire <class-enum-type> and thus don't want to clear
2488
the is_substitution_candidate flag.
2490
However, it's possible that what we have here is a
2491
substitution token representing an entire type, such as
2492
`Ss' => std::string. In this case, we mustn't add a
2493
new substitution candidate for this substitution token.
2494
To detect this case, remember where the start of the
2495
substitution token is. */
2496
const char *next = dm->next;
2497
/* Now demangle the <class-enum-type>. */
2499
(demangle_class_enum_type (dm, &encode_return_type));
2500
/* If all that was just demangled is the two-character
2501
special substitution token, supress the addition of a
2502
new candidate for it. */
2503
if (dm->next == next + 2)
2504
is_substitution_candidate = 0;
2512
RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
2513
/* demangle_type_ptr adds all applicable substitution
2515
is_substitution_candidate = 0;
2519
/* A C99 complex type. */
2520
RETURN_IF_ERROR (result_add (dm, "complex "));
2522
RETURN_IF_ERROR (demangle_type (dm));
2526
/* A C99 imaginary type. */
2527
RETURN_IF_ERROR (result_add (dm, "imaginary "));
2529
RETURN_IF_ERROR (demangle_type (dm));
2533
/* Vendor-extended type qualifier. */
2535
RETURN_IF_ERROR (demangle_source_name (dm));
2536
RETURN_IF_ERROR (result_add_char (dm, ' '));
2537
RETURN_IF_ERROR (demangle_type (dm));
2541
return "Unexpected character in <type>.";
2544
if (is_substitution_candidate)
2545
/* Add a new substitution for the type. If this type was a
2546
<template-param>, pass its index since from the point of
2547
substitutions; a <template-param> token is a substitution
2548
candidate distinct from the type that is substituted for it. */
2549
RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2551
/* Pop off template argument lists added during mangling of this
2553
pop_to_template_arg_list (dm, old_arg_list);
2558
/* C++ source names of builtin types, indexed by the mangled code
2559
letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2560
static const char *const builtin_type_names[26] =
2562
"signed char", /* a */
2566
"long double", /* e */
2568
"__float128", /* g */
2569
"unsigned char", /* h */
2574
"unsigned long", /* m */
2576
"unsigned __int128", /* o */
2581
"unsigned short", /* t */
2585
"long long", /* x */
2586
"unsigned long long", /* y */
2590
/* Java source names of builtin types. Types that arn't valid in Java
2591
are also included here - we don't fail if someone attempts to demangle a
2592
C++ symbol in Java style. */
2593
static const char *const java_builtin_type_names[26] =
2595
"signed char", /* a */
2596
"boolean", /* C++ "bool" */ /* b */
2597
"byte", /* C++ "char" */ /* c */
2599
"long double", /* e */
2601
"__float128", /* g */
2602
"unsigned char", /* h */
2607
"unsigned long", /* m */
2609
"unsigned __int128", /* o */
2614
"unsigned short", /* t */
2617
"char", /* C++ "wchar_t" */ /* w */
2618
"long", /* C++ "long long" */ /* x */
2619
"unsigned long long", /* y */
2623
/* Demangles and emits a <builtin-type>.
2625
<builtin-type> ::= v # void
2630
::= h # unsigned char
2632
::= t # unsigned short
2634
::= j # unsigned int
2636
::= m # unsigned long
2637
::= x # long long, __int64
2638
::= y # unsigned long long, __int64
2640
::= o # unsigned __int128
2643
::= e # long double, __float80
2646
::= u <source-name> # vendor extended type */
2649
demangle_builtin_type (dm)
2653
char code = peek_char (dm);
2655
DEMANGLE_TRACE ("builtin-type", dm);
2660
RETURN_IF_ERROR (demangle_source_name (dm));
2663
else if (code >= 'a' && code <= 'z')
2665
const char *type_name;
2666
/* Java uses different names for some built-in types. */
2667
if (dm->style == DMGL_JAVA)
2668
type_name = java_builtin_type_names[code - 'a'];
2670
type_name = builtin_type_names[code - 'a'];
2671
if (type_name == NULL)
2672
return "Unrecognized <builtin-type> code.";
2674
RETURN_IF_ERROR (result_add (dm, type_name));
2679
return "Non-alphabetic <builtin-type> code.";
2682
/* Demangles all consecutive CV-qualifiers (const, volatile, and
2683
restrict) at the current position. The qualifiers are appended to
2684
QUALIFIERS. Returns STATUS_OK. */
2687
demangle_CV_qualifiers (dm, qualifiers)
2689
dyn_string_t qualifiers;
2691
DEMANGLE_TRACE ("CV-qualifiers", dm);
2695
switch (peek_char (dm))
2698
if (!dyn_string_append_space (qualifiers))
2699
return STATUS_ALLOCATION_FAILED;
2700
if (!dyn_string_append_cstr (qualifiers, "restrict"))
2701
return STATUS_ALLOCATION_FAILED;
2705
if (!dyn_string_append_space (qualifiers))
2706
return STATUS_ALLOCATION_FAILED;
2707
if (!dyn_string_append_cstr (qualifiers, "volatile"))
2708
return STATUS_ALLOCATION_FAILED;
2712
if (!dyn_string_append_space (qualifiers))
2713
return STATUS_ALLOCATION_FAILED;
2714
if (!dyn_string_append_cstr (qualifiers, "const"))
2715
return STATUS_ALLOCATION_FAILED;
2726
/* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2727
position in the result string of the start of the function
2728
identifier, at which the function's return type will be inserted;
2729
*FUNCTION_NAME_POS is updated to position past the end of the
2730
function's return type.
2732
<function-type> ::= F [Y] <bare-function-type> E */
2735
demangle_function_type (dm, function_name_pos)
2737
int *function_name_pos;
2739
DEMANGLE_TRACE ("function-type", dm);
2740
RETURN_IF_ERROR (demangle_char (dm, 'F'));
2741
if (peek_char (dm) == 'Y')
2743
/* Indicate this function has C linkage if in verbose mode. */
2745
RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
2748
RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2749
RETURN_IF_ERROR (demangle_char (dm, 'E'));
2753
/* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2754
position in the result string at which the function return type
2755
should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2756
function's return type is assumed not to be encoded.
2758
<bare-function-type> ::= <signature type>+ */
2761
demangle_bare_function_type (dm, return_type_pos)
2763
int *return_type_pos;
2765
/* Sequence is the index of the current function parameter, counting
2766
from zero. The value -1 denotes the return type. */
2768
(return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2770
DEMANGLE_TRACE ("bare-function-type", dm);
2772
RETURN_IF_ERROR (result_add_char (dm, '('));
2773
while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2776
/* We're decoding the function's return type. */
2778
dyn_string_t return_type;
2779
status_t status = STATUS_OK;
2781
/* Decode the return type off to the side. */
2782
RETURN_IF_ERROR (result_push (dm));
2783
RETURN_IF_ERROR (demangle_type (dm));
2784
return_type = (dyn_string_t) result_pop (dm);
2786
/* Add a space to the end of the type. Insert the return
2787
type where we've been asked to. */
2788
if (!dyn_string_append_space (return_type))
2789
status = STATUS_ALLOCATION_FAILED;
2790
if (STATUS_NO_ERROR (status))
2792
if (!dyn_string_insert (result_string (dm), *return_type_pos,
2794
status = STATUS_ALLOCATION_FAILED;
2796
*return_type_pos += dyn_string_length (return_type);
2799
dyn_string_delete (return_type);
2800
RETURN_IF_ERROR (status);
2804
/* Skip `void' parameter types. One should only occur as
2805
the only type in a parameter list; in that case, we want
2806
to print `foo ()' instead of `foo (void)'. */
2807
if (peek_char (dm) == 'v')
2808
/* Consume the v. */
2812
/* Separate parameter types by commas. */
2814
RETURN_IF_ERROR (result_add (dm, ", "));
2815
/* Demangle the type. */
2816
RETURN_IF_ERROR (demangle_type (dm));
2822
RETURN_IF_ERROR (result_add_char (dm, ')'));
2824
/* We should have demangled at least one parameter type (which would
2825
be void, for a function that takes no parameters), plus the
2826
return type, if we were supposed to demangle that. */
2828
return "Missing function return type.";
2829
else if (sequence == 0)
2830
return "Missing function parameter.";
2835
/* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2836
non-zero if the type is a template-id, zero otherwise.
2838
<class-enum-type> ::= <name> */
2841
demangle_class_enum_type (dm, encode_return_type)
2843
int *encode_return_type;
2845
DEMANGLE_TRACE ("class-enum-type", dm);
2847
RETURN_IF_ERROR (demangle_name (dm, encode_return_type));
2851
/* Demangles and emits an <array-type>.
2853
If PTR_INSERT_POS is not NULL, the array type is formatted as a
2854
pointer or reference to an array, except that asterisk and
2855
ampersand punctuation is omitted (since it's not know at this
2856
point). *PTR_INSERT_POS is set to the position in the demangled
2857
name at which this punctuation should be inserted. For example,
2858
`A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2859
between the parentheses.
2861
If PTR_INSERT_POS is NULL, the array type is assumed not to be
2862
pointer- or reference-qualified. Then, for example, `A10_i' is
2863
demangled simply as `int[10]'.
2865
<array-type> ::= A [<dimension number>] _ <element type>
2866
::= A <dimension expression> _ <element type> */
2869
demangle_array_type (dm, ptr_insert_pos)
2871
int *ptr_insert_pos;
2873
status_t status = STATUS_OK;
2874
dyn_string_t array_size = NULL;
2877
DEMANGLE_TRACE ("array-type", dm);
2879
RETURN_IF_ERROR (demangle_char (dm, 'A'));
2881
/* Demangle the array size into array_size. */
2882
peek = peek_char (dm);
2884
/* Array bound is omitted. This is a C99-style VLA. */
2886
else if (IS_DIGIT (peek_char (dm)))
2888
/* It looks like a constant array bound. */
2889
array_size = dyn_string_new (10);
2890
if (array_size == NULL)
2891
return STATUS_ALLOCATION_FAILED;
2892
status = demangle_number_literally (dm, array_size, 10, 0);
2896
/* Anything is must be an expression for a nont-constant array
2897
bound. This happens if the array type occurs in a template
2898
and the array bound references a template parameter. */
2899
RETURN_IF_ERROR (result_push (dm));
2900
RETURN_IF_ERROR (demangle_expression (dm));
2901
array_size = (dyn_string_t) result_pop (dm);
2903
/* array_size may have been allocated by now, so we can't use
2904
RETURN_IF_ERROR until it's been deallocated. */
2906
/* Demangle the base type of the array. */
2907
if (STATUS_NO_ERROR (status))
2908
status = demangle_char (dm, '_');
2909
if (STATUS_NO_ERROR (status))
2910
status = demangle_type (dm);
2912
if (ptr_insert_pos != NULL)
2914
/* This array is actually part of an pointer- or
2915
reference-to-array type. Format appropriately, except we
2916
don't know which and how much punctuation to use. */
2917
if (STATUS_NO_ERROR (status))
2918
status = result_add (dm, " () ");
2919
/* Let the caller know where to insert the punctuation. */
2920
*ptr_insert_pos = result_caret_pos (dm) - 2;
2923
/* Emit the array dimension syntax. */
2924
if (STATUS_NO_ERROR (status))
2925
status = result_add_char (dm, '[');
2926
if (STATUS_NO_ERROR (status) && array_size != NULL)
2927
status = result_add_string (dm, array_size);
2928
if (STATUS_NO_ERROR (status))
2929
status = result_add_char (dm, ']');
2930
if (array_size != NULL)
2931
dyn_string_delete (array_size);
2933
RETURN_IF_ERROR (status);
2938
/* Demangles and emits a <template-param>.
2940
<template-param> ::= T_ # first template parameter
2941
::= T <parameter-2 number> _ */
2944
demangle_template_param (dm)
2948
template_arg_list_t current_arg_list = current_template_arg_list (dm);
2951
DEMANGLE_TRACE ("template-param", dm);
2953
/* Make sure there is a template argmust list in which to look up
2954
this parameter reference. */
2955
if (current_arg_list == NULL)
2956
return "Template parameter outside of template.";
2958
RETURN_IF_ERROR (demangle_char (dm, 'T'));
2959
if (peek_char (dm) == '_')
2963
RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2966
RETURN_IF_ERROR (demangle_char (dm, '_'));
2968
arg = template_arg_list_get_arg (current_arg_list, parm_number);
2970
/* parm_number exceeded the number of arguments in the current
2971
template argument list. */
2972
return "Template parameter number out of bounds.";
2973
RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
2978
/* Demangles and emits a <template-args>.
2980
<template-args> ::= I <template-arg>+ E */
2983
demangle_template_args (dm)
2987
dyn_string_t old_last_source_name;
2988
template_arg_list_t arg_list = template_arg_list_new ();
2990
if (arg_list == NULL)
2991
return STATUS_ALLOCATION_FAILED;
2993
/* Preserve the most recently demangled source name. */
2994
old_last_source_name = dm->last_source_name;
2995
dm->last_source_name = dyn_string_new (0);
2997
DEMANGLE_TRACE ("template-args", dm);
2999
if (dm->last_source_name == NULL)
3000
return STATUS_ALLOCATION_FAILED;
3002
RETURN_IF_ERROR (demangle_char (dm, 'I'));
3003
RETURN_IF_ERROR (result_open_template_list (dm));
3011
RETURN_IF_ERROR (result_add (dm, ", "));
3013
/* Capture the template arg. */
3014
RETURN_IF_ERROR (result_push (dm));
3015
RETURN_IF_ERROR (demangle_template_arg (dm));
3016
arg = result_pop (dm);
3018
/* Emit it in the demangled name. */
3019
RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
3021
/* Save it for use in expanding <template-param>s. */
3022
template_arg_list_add_arg (arg_list, arg);
3024
while (peek_char (dm) != 'E');
3025
/* Append the '>'. */
3026
RETURN_IF_ERROR (result_close_template_list (dm));
3028
/* Consume the 'E'. */
3031
/* Restore the most recent demangled source name. */
3032
dyn_string_delete (dm->last_source_name);
3033
dm->last_source_name = old_last_source_name;
3035
/* Push the list onto the top of the stack of template argument
3036
lists, so that arguments from it are used from now on when
3037
expanding <template-param>s. */
3038
push_template_arg_list (dm, arg_list);
3043
/* This function, which does not correspond to a production in the
3044
mangling spec, handles the `literal' production for both
3045
<template-arg> and <expr-primary>. It does not expect or consume
3046
the initial `L' or final `E'. The demangling is given by:
3048
<literal> ::= <type> </value/ number>
3050
and the emitted output is `(type)number'. */
3053
demangle_literal (dm)
3056
char peek = peek_char (dm);
3057
dyn_string_t value_string;
3060
DEMANGLE_TRACE ("literal", dm);
3062
if (!flag_verbose && peek >= 'a' && peek <= 'z')
3064
/* If not in verbose mode and this is a builtin type, see if we
3065
can produce simpler numerical output. In particular, for
3066
integer types shorter than `long', just write the number
3067
without type information; for bools, write `true' or `false'.
3068
Other refinements could be made here too. */
3070
/* This constant string is used to map from <builtin-type> codes
3071
(26 letters of the alphabet) to codes that determine how the
3072
value will be displayed. The codes are:
3076
A space means the value will be represented using cast
3078
static const char *const code_map = "ibi iii ll ii i ";
3080
char code = code_map[peek - 'a'];
3081
/* FIXME: Implement demangling of floats and doubles. */
3083
return STATUS_UNIMPLEMENTED;
3086
/* It's a boolean. */
3089
/* Consume the b. */
3091
/* Look at the next character. It should be 0 or 1,
3092
corresponding to false or true, respectively. */
3093
value = peek_char (dm);
3095
RETURN_IF_ERROR (result_add (dm, "false"));
3096
else if (value == '1')
3097
RETURN_IF_ERROR (result_add (dm, "true"));
3099
return "Unrecognized bool constant.";
3100
/* Consume the 0 or 1. */
3104
else if (code == 'i' || code == 'l')
3106
/* It's an integer or long. */
3108
/* Consume the type character. */
3111
/* Demangle the number and write it out. */
3112
value_string = dyn_string_new (0);
3113
status = demangle_number_literally (dm, value_string, 10, 1);
3114
if (STATUS_NO_ERROR (status))
3115
status = result_add_string (dm, value_string);
3116
/* For long integers, append an l. */
3117
if (code == 'l' && STATUS_NO_ERROR (status))
3118
status = result_add_char (dm, code);
3119
dyn_string_delete (value_string);
3121
RETURN_IF_ERROR (status);
3124
/* ...else code == ' ', so fall through to represent this
3125
literal's type explicitly using cast syntax. */
3128
RETURN_IF_ERROR (result_add_char (dm, '('));
3129
RETURN_IF_ERROR (demangle_type (dm));
3130
RETURN_IF_ERROR (result_add_char (dm, ')'));
3132
value_string = dyn_string_new (0);
3133
if (value_string == NULL)
3134
return STATUS_ALLOCATION_FAILED;
3136
status = demangle_number_literally (dm, value_string, 10, 1);
3137
if (STATUS_NO_ERROR (status))
3138
status = result_add_string (dm, value_string);
3139
dyn_string_delete (value_string);
3140
RETURN_IF_ERROR (status);
3145
/* Demangles and emits a <template-arg>.
3147
<template-arg> ::= <type> # type
3148
::= L <type> <value number> E # literal
3149
::= LZ <encoding> E # external name
3150
::= X <expression> E # expression */
3153
demangle_template_arg (dm)
3156
DEMANGLE_TRACE ("template-arg", dm);
3158
switch (peek_char (dm))
3163
if (peek_char (dm) == 'Z')
3165
/* External name. */
3167
/* FIXME: Standard is contradictory here. */
3168
RETURN_IF_ERROR (demangle_encoding (dm));
3171
RETURN_IF_ERROR (demangle_literal (dm));
3172
RETURN_IF_ERROR (demangle_char (dm, 'E'));
3178
RETURN_IF_ERROR (demangle_expression (dm));
3179
RETURN_IF_ERROR (demangle_char (dm, 'E'));
3183
RETURN_IF_ERROR (demangle_type (dm));
3190
/* Demangles and emits an <expression>.
3192
<expression> ::= <unary operator-name> <expression>
3193
::= <binary operator-name> <expression> <expression>
3195
::= <scope-expression> */
3198
demangle_expression (dm)
3201
char peek = peek_char (dm);
3203
DEMANGLE_TRACE ("expression", dm);
3205
if (peek == 'L' || peek == 'T')
3206
RETURN_IF_ERROR (demangle_expr_primary (dm));
3207
else if (peek == 's' && peek_char_next (dm) == 'r')
3208
RETURN_IF_ERROR (demangle_scope_expression (dm));
3210
/* An operator expression. */
3214
status_t status = STATUS_OK;
3215
dyn_string_t operator_name;
3217
/* We have an operator name. Since we want to output binary
3218
operations in infix notation, capture the operator name
3220
RETURN_IF_ERROR (result_push (dm));
3221
RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
3223
operator_name = (dyn_string_t) result_pop (dm);
3225
/* If it's binary, do an operand first. */
3228
status = result_add_char (dm, '(');
3229
if (STATUS_NO_ERROR (status))
3230
status = demangle_expression (dm);
3231
if (STATUS_NO_ERROR (status))
3232
status = result_add_char (dm, ')');
3235
/* Emit the operator. */
3236
if (STATUS_NO_ERROR (status))
3237
status = result_add_string (dm, operator_name);
3238
dyn_string_delete (operator_name);
3239
RETURN_IF_ERROR (status);
3241
/* Emit its second (if binary) or only (if unary) operand. */
3242
RETURN_IF_ERROR (result_add_char (dm, '('));
3244
RETURN_IF_ERROR (demangle_type (dm));
3246
RETURN_IF_ERROR (demangle_expression (dm));
3247
RETURN_IF_ERROR (result_add_char (dm, ')'));
3249
/* The ternary operator takes a third operand. */
3252
RETURN_IF_ERROR (result_add (dm, ":("));
3253
RETURN_IF_ERROR (demangle_expression (dm));
3254
RETURN_IF_ERROR (result_add_char (dm, ')'));
3261
/* Demangles and emits a <scope-expression>.
3263
<scope-expression> ::= sr <qualifying type> <source-name>
3264
::= sr <qualifying type> <encoding> */
3267
demangle_scope_expression (dm)
3270
RETURN_IF_ERROR (demangle_char (dm, 's'));
3271
RETURN_IF_ERROR (demangle_char (dm, 'r'));
3272
RETURN_IF_ERROR (demangle_type (dm));
3273
RETURN_IF_ERROR (result_add (dm, "::"));
3274
RETURN_IF_ERROR (demangle_encoding (dm));
3278
/* Demangles and emits an <expr-primary>.
3280
<expr-primary> ::= <template-param>
3281
::= L <type> <value number> E # literal
3282
::= L <mangled-name> E # external name */
3285
demangle_expr_primary (dm)
3288
char peek = peek_char (dm);
3290
DEMANGLE_TRACE ("expr-primary", dm);
3293
RETURN_IF_ERROR (demangle_template_param (dm));
3294
else if (peek == 'L')
3296
/* Consume the `L'. */
3298
peek = peek_char (dm);
3301
RETURN_IF_ERROR (demangle_mangled_name (dm));
3303
RETURN_IF_ERROR (demangle_literal (dm));
3305
RETURN_IF_ERROR (demangle_char (dm, 'E'));
3308
return STATUS_ERROR;
3313
/* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3314
if the substitution is the name of a template, zero otherwise.
3316
<substitution> ::= S <seq-id> _
3320
::= Sa # ::std::allocator
3321
::= Sb # ::std::basic_string
3322
::= Ss # ::std::basic_string<char,
3323
::std::char_traits<char>,
3324
::std::allocator<char> >
3325
::= Si # ::std::basic_istream<char,
3326
std::char_traits<char> >
3327
::= So # ::std::basic_ostream<char,
3328
std::char_traits<char> >
3329
::= Sd # ::std::basic_iostream<char,
3330
std::char_traits<char> >
3334
demangle_substitution (dm, template_p)
3342
DEMANGLE_TRACE ("substitution", dm);
3344
RETURN_IF_ERROR (demangle_char (dm, 'S'));
3346
/* Scan the substitution sequence index. A missing number denotes
3348
peek = peek_char (dm);
3351
/* If the following character is 0-9 or a capital letter, interpret
3352
the sequence up to the next underscore as a base-36 substitution
3354
else if (IS_DIGIT ((unsigned char) peek)
3355
|| (peek >= 'A' && peek <= 'Z'))
3356
RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
3359
const char *new_last_source_name = NULL;
3364
RETURN_IF_ERROR (result_add (dm, "std"));
3368
RETURN_IF_ERROR (result_add (dm, "std::allocator"));
3369
new_last_source_name = "allocator";
3374
RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
3375
new_last_source_name = "basic_string";
3382
RETURN_IF_ERROR (result_add (dm, "std::string"));
3383
new_last_source_name = "string";
3387
RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3388
new_last_source_name = "basic_string";
3396
RETURN_IF_ERROR (result_add (dm, "std::istream"));
3397
new_last_source_name = "istream";
3401
RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traints<char> >"));
3402
new_last_source_name = "basic_istream";
3410
RETURN_IF_ERROR (result_add (dm, "std::ostream"));
3411
new_last_source_name = "ostream";
3415
RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
3416
new_last_source_name = "basic_ostream";
3424
RETURN_IF_ERROR (result_add (dm, "std::iostream"));
3425
new_last_source_name = "iostream";
3429
RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
3430
new_last_source_name = "basic_iostream";
3436
return "Unrecognized <substitution>.";
3439
/* Consume the character we just processed. */
3442
if (new_last_source_name != NULL)
3444
if (!dyn_string_copy_cstr (dm->last_source_name,
3445
new_last_source_name))
3446
return STATUS_ALLOCATION_FAILED;
3452
/* Look up the substitution text. Since `S_' is the most recent
3453
substitution, `S0_' is the second-most-recent, etc., shift the
3454
numbering by one. */
3455
text = substitution_get (dm, seq_id + 1, template_p);
3457
return "Substitution number out of range.";
3459
/* Emit the substitution text. */
3460
RETURN_IF_ERROR (result_add_string (dm, text));
3462
RETURN_IF_ERROR (demangle_char (dm, '_'));
3466
/* Demangles and emits a <local-name>.
3468
<local-name> := Z <function encoding> E <entity name> [<discriminator>]
3469
:= Z <function encoding> E s [<discriminator>] */
3472
demangle_local_name (dm)
3475
DEMANGLE_TRACE ("local-name", dm);
3477
RETURN_IF_ERROR (demangle_char (dm, 'Z'));
3478
RETURN_IF_ERROR (demangle_encoding (dm));
3479
RETURN_IF_ERROR (demangle_char (dm, 'E'));
3480
RETURN_IF_ERROR (result_add (dm, "::"));
3482
if (peek_char (dm) == 's')
3484
/* Local character string literal. */
3485
RETURN_IF_ERROR (result_add (dm, "string literal"));
3486
/* Consume the s. */
3488
RETURN_IF_ERROR (demangle_discriminator (dm, 0));
3493
/* Local name for some other entity. Demangle its name. */
3494
RETURN_IF_ERROR (demangle_name (dm, &unused));
3495
RETURN_IF_ERROR (demangle_discriminator (dm, 1));
3501
/* Optimonally demangles and emits a <discriminator>. If there is no
3502
<discriminator> at the current position in the mangled string, the
3503
descriminator is assumed to be zero. Emit the discriminator number
3504
in parentheses, unless SUPPRESS_FIRST is non-zero and the
3505
discriminator is zero.
3507
<discriminator> ::= _ <number> */
3510
demangle_discriminator (dm, suppress_first)
3514
/* Output for <discriminator>s to the demangled name is completely
3515
suppressed if not in verbose mode. */
3517
if (peek_char (dm) == '_')
3519
/* Consume the underscore. */
3522
RETURN_IF_ERROR (result_add (dm, " [#"));
3523
/* Check if there's a number following the underscore. */
3524
if (IS_DIGIT ((unsigned char) peek_char (dm)))
3527
/* Demangle the number. */
3528
RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
3530
/* Write the discriminator. The mangled number is two
3531
less than the discriminator ordinal, counting from
3533
RETURN_IF_ERROR (int_to_dyn_string (discriminator + 1,
3534
(dyn_string_t) dm->result));
3537
return STATUS_ERROR;
3539
RETURN_IF_ERROR (result_add_char (dm, ']'));
3541
else if (!suppress_first)
3544
RETURN_IF_ERROR (result_add (dm, " [#0]"));
3550
/* Demangle NAME into RESULT, which must be an initialized
3551
dyn_string_t. On success, returns STATUS_OK. On failure, returns
3552
an error message, and the contents of RESULT are unchanged. */
3555
cp_demangle (name, result, style)
3557
dyn_string_t result;
3561
int length = strlen (name);
3563
if (length > 2 && name[0] == '_' && name[1] == 'Z')
3565
demangling_t dm = demangling_new (name, style);
3567
return STATUS_ALLOCATION_FAILED;
3569
status = result_push (dm);
3570
if (status != STATUS_OK)
3572
demangling_delete (dm);
3576
status = demangle_mangled_name (dm);
3577
if (STATUS_NO_ERROR (status))
3579
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3580
if (!dyn_string_copy (result, demangled))
3581
return STATUS_ALLOCATION_FAILED;
3582
dyn_string_delete (demangled);
3585
demangling_delete (dm);
3589
/* It's evidently not a mangled C++ name. It could be the name
3590
of something with C linkage, though, so just copy NAME into
3592
if (!dyn_string_copy_cstr (result, name))
3593
return STATUS_ALLOCATION_FAILED;
3600
/* Demangle TYPE_NAME into RESULT, which must be an initialized
3601
dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3602
an error message, and the contents of RESULT are unchanged. */
3605
cp_demangle_type (type_name, result)
3606
const char* type_name;
3607
dyn_string_t result;
3610
demangling_t dm = demangling_new (type_name, DMGL_GNU_V3);
3613
return STATUS_ALLOCATION_FAILED;
3615
/* Demangle the type name. The demangled name is stored in dm. */
3616
status = result_push (dm);
3617
if (status != STATUS_OK)
3619
demangling_delete (dm);
3623
status = demangle_type (dm);
3625
if (STATUS_NO_ERROR (status))
3627
/* The demangling succeeded. Pop the result out of dm and copy
3629
dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3630
if (!dyn_string_copy (result, demangled))
3631
return STATUS_ALLOCATION_FAILED;
3632
dyn_string_delete (demangled);
3636
demangling_delete (dm);
3641
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
3642
extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
3644
/* ia64 ABI-mandated entry point in the C++ runtime library for performing
3645
demangling. MANGLED_NAME is a NUL-terminated character string
3646
containing the name to be demangled.
3648
OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3649
*LENGTH bytes, into which the demangled name is stored. If
3650
OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3651
OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3652
is placed in a region of memory allocated with malloc.
3654
If LENGTH is non-NULL, the length of the buffer conaining the
3655
demangled name, is placed in *LENGTH.
3657
The return value is a pointer to the start of the NUL-terminated
3658
demangled name, or NULL if the demangling fails. The caller is
3659
responsible for deallocating this memory using free.
3661
*STATUS is set to one of the following values:
3662
0: The demangling operation succeeded.
3663
-1: A memory allocation failiure occurred.
3664
-2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3665
-3: One of the arguments is invalid.
3667
The demagling is performed using the C++ ABI mangling rules, with
3671
__cxa_demangle (mangled_name, output_buffer, length, status)
3672
const char *mangled_name;
3673
char *output_buffer;
3677
struct dyn_string demangled_name;
3683
if (mangled_name == NULL) {
3688
/* Did the caller provide a buffer for the demangled name? */
3689
if (output_buffer == NULL) {
3690
/* No; dyn_string will malloc a buffer for us. */
3691
if (!dyn_string_init (&demangled_name, 0))
3698
/* Yes. Check that the length was provided. */
3699
if (length == NULL) {
3703
/* Install the buffer into a dyn_string. */
3704
demangled_name.allocated = *length;
3705
demangled_name.length = 0;
3706
demangled_name.s = output_buffer;
3709
if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
3710
/* MANGLED_NAME apprears to be a function or variable name.
3711
Demangle it accordingly. */
3712
result = cp_demangle (mangled_name, &demangled_name, 0);
3714
/* Try to demangled MANGLED_NAME as the name of a type. */
3715
result = cp_demangle_type (mangled_name, &demangled_name);
3717
if (result == STATUS_OK)
3718
/* The demangling succeeded. */
3720
/* If LENGTH isn't NULL, store the allocated buffer length
3721
there; the buffer may have been realloced by dyn_string
3724
*length = demangled_name.allocated;
3725
/* The operation was a success. */
3727
return dyn_string_buf (&demangled_name);
3729
else if (result == STATUS_ALLOCATION_FAILED)
3730
/* A call to malloc or realloc failed during the demangling
3737
/* The demangling failed for another reason, most probably because
3738
MANGLED_NAME isn't a valid mangled name. */
3740
/* If the buffer containing the demangled name wasn't provided
3741
by the caller, free it. */
3742
if (output_buffer == NULL)
3743
free (dyn_string_buf (&demangled_name));
3749
#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
3751
/* Variant entry point for integration with the existing cplus-dem
3752
demangler. Attempts to demangle MANGLED. If the demangling
3753
succeeds, returns a buffer, allocated with malloc, containing the
3754
demangled name. The caller must deallocate the buffer using free.
3755
If the demangling failes, returns NULL. */
3758
cplus_demangle_v3 (mangled, options)
3759
const char* mangled;
3762
dyn_string_t demangled;
3764
int type = !!(options & DMGL_TYPES);
3766
if (mangled[0] == '_' && mangled[1] == 'Z')
3767
/* It is not a type. */
3771
/* It is a type. Stop if we don't want to demangle types. */
3776
flag_verbose = !!(options & DMGL_VERBOSE);
3778
/* Create a dyn_string to hold the demangled name. */
3779
demangled = dyn_string_new (0);
3780
/* Attempt the demangling. */
3782
/* Appears to be a function or variable name. */
3783
status = cp_demangle (mangled, demangled, 0);
3785
/* Try to demangle it as the name of a type. */
3786
status = cp_demangle_type (mangled, demangled);
3788
if (STATUS_NO_ERROR (status))
3789
/* Demangling succeeded. */
3791
/* Grab the demangled result from the dyn_string. It was
3792
allocated with malloc, so we can return it directly. */
3793
char *return_value = dyn_string_release (demangled);
3794
/* Hand back the demangled name. */
3795
return return_value;
3797
else if (status == STATUS_ALLOCATION_FAILED)
3799
fprintf (stderr, "Memory allocation failed.\n");
3803
/* Demangling failed. */
3805
dyn_string_delete (demangled);
3810
/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3811
conventions, but the output formatting is a little different.
3812
This instructs the C++ demangler not to emit pointer characters ("*"), and
3813
to use Java's namespace separator symbol ("." instead of "::"). It then
3814
does an additional pass over the demangled output to replace instances
3815
of JArray<TYPE> with TYPE[]. */
3818
java_demangle_v3 (mangled)
3819
const char* mangled;
3821
dyn_string_t demangled;
3827
char *cplus_demangled;
3830
/* Create a dyn_string to hold the demangled name. */
3831
demangled = dyn_string_new (0);
3833
/* Attempt the demangling. */
3834
status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA);
3836
if (STATUS_NO_ERROR (status))
3837
/* Demangling succeeded. */
3839
/* Grab the demangled result from the dyn_string. */
3840
cplus_demangled = dyn_string_release (demangled);
3842
else if (status == STATUS_ALLOCATION_FAILED)
3844
fprintf (stderr, "Memory allocation failed.\n");
3848
/* Demangling failed. */
3850
dyn_string_delete (demangled);
3854
len = strlen (cplus_demangled);
3855
next = cplus_demangled;
3859
/* Replace occurances of JArray<TYPE> with TYPE[]. */
3862
char *open_str = strstr (next, "JArray<");
3863
char *close_str = NULL;
3865
close_str = strchr (next, '>');
3867
if (open_str != NULL && (close_str == NULL || close_str > open_str))
3872
demangled = dyn_string_new(len);
3874
/* Copy prepending symbols, if any. */
3875
if (open_str > next)
3878
dyn_string_append_cstr (demangled, next);
3880
next = open_str + 7;
3882
else if (close_str != NULL)
3886
/* Copy prepending type symbol, if any. Squash any spurious
3888
if (close_str > next && next[0] != ' ')
3891
dyn_string_append_cstr (demangled, next);
3893
dyn_string_append_cstr (demangled, "[]");
3894
next = close_str + 1;
3898
/* There are no more arrays. Copy the rest of the symbol, or
3899
simply return the original symbol if no changes were made. */
3900
if (next == cplus_demangled)
3901
return cplus_demangled;
3903
dyn_string_append_cstr (demangled, next);
3908
free (cplus_demangled);
3911
return_value = dyn_string_release (demangled);
3913
return_value = NULL;
3915
return return_value;
3918
#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
3921
#ifndef IN_GLIBCPP_V3
3922
/* Demangle NAME in the G++ V3 ABI demangling style, and return either
3923
zero, indicating that some error occurred, or a demangling_t
3924
holding the results. */
3926
demangle_v3_with_details (name)
3932
if (strncmp (name, "_Z", 2))
3935
dm = demangling_new (name, DMGL_GNU_V3);
3938
fprintf (stderr, "Memory allocation failed.\n");
3942
status = result_push (dm);
3943
if (! STATUS_NO_ERROR (status))
3945
demangling_delete (dm);
3946
fprintf (stderr, "%s\n", status);
3950
status = demangle_mangled_name (dm);
3951
if (STATUS_NO_ERROR (status))
3954
demangling_delete (dm);
3959
/* Return non-zero iff NAME is the mangled form of a constructor name
3960
in the G++ V3 ABI demangling style. Specifically, return:
3961
- '1' if NAME is a complete object constructor,
3962
- '2' if NAME is a base object constructor, or
3963
- '3' if NAME is a complete object allocating constructor. */
3964
enum gnu_v3_ctor_kinds
3965
is_gnu_v3_mangled_ctor (name)
3968
demangling_t dm = demangle_v3_with_details (name);
3972
enum gnu_v3_ctor_kinds result = dm->is_constructor;
3973
demangling_delete (dm);
3981
/* Return non-zero iff NAME is the mangled form of a destructor name
3982
in the G++ V3 ABI demangling style. Specifically, return:
3983
- '0' if NAME is a deleting destructor,
3984
- '1' if NAME is a complete object destructor, or
3985
- '2' if NAME is a base object destructor. */
3986
enum gnu_v3_dtor_kinds
3987
is_gnu_v3_mangled_dtor (name)
3990
demangling_t dm = demangle_v3_with_details (name);
3994
enum gnu_v3_dtor_kinds result = dm->is_destructor;
3995
demangling_delete (dm);
4001
#endif /* IN_GLIBCPP_V3 */
4004
#ifdef STANDALONE_DEMANGLER
4008
static void print_usage
4009
PARAMS ((FILE* fp, int exit_value));
4011
/* Non-zero if CHAR is a character than can occur in a mangled name. */
4012
#define is_mangled_char(CHAR) \
4013
(IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
4014
|| (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
4016
/* The name of this program, as invoked. */
4017
const char* program_name;
4019
/* Prints usage summary to FP and then exits with EXIT_VALUE. */
4022
print_usage (fp, exit_value)
4026
fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
4027
fprintf (fp, "Options:\n");
4028
fprintf (fp, " -h,--help Display this message.\n");
4029
fprintf (fp, " -s,--strict Demangle standard names only.\n");
4030
fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
4031
fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
4036
/* Option specification for getopt_long. */
4037
static const struct option long_options[] =
4039
{ "help", no_argument, NULL, 'h' },
4040
{ "strict", no_argument, NULL, 's' },
4041
{ "verbose", no_argument, NULL, 'v' },
4042
{ NULL, no_argument, NULL, 0 },
4045
/* Main entry for a demangling filter executable. It will demangle
4046
its command line arguments, if any. If none are provided, it will
4047
filter stdin to stdout, replacing any recognized mangled C++ names
4048
with their demangled equivalents. */
4059
/* Use the program name of this program, as invoked. */
4060
program_name = argv[0];
4062
/* Parse options. */
4065
opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
4068
case '?': /* Unrecognized option. */
4069
print_usage (stderr, 1);
4073
print_usage (stdout, 0);
4085
while (opt_char != -1);
4088
/* No command line arguments were provided. Filter stdin. */
4090
dyn_string_t mangled = dyn_string_new (3);
4091
dyn_string_t demangled = dyn_string_new (0);
4094
/* Read all of input. */
4095
while (!feof (stdin))
4097
char c = getchar ();
4099
/* The first character of a mangled name is an underscore. */
4104
/* It's not a mangled name. Print the character and go
4111
/* The second character of a mangled name is a capital `Z'. */
4116
/* It's not a mangled name. Print the previous
4117
underscore, the `Z', and go on. */
4123
/* Start keeping track of the candidate mangled name. */
4124
dyn_string_append_char (mangled, '_');
4125
dyn_string_append_char (mangled, 'Z');
4127
/* Pile characters into mangled until we hit one that can't
4128
occur in a mangled name. */
4130
while (!feof (stdin) && is_mangled_char (c))
4132
dyn_string_append_char (mangled, c);
4138
/* Attempt to demangle the name. */
4139
status = cp_demangle (dyn_string_buf (mangled), demangled, 0);
4141
/* If the demangling succeeded, great! Print out the
4142
demangled version. */
4143
if (STATUS_NO_ERROR (status))
4144
fputs (dyn_string_buf (demangled), stdout);
4145
/* Abort on allocation failures. */
4146
else if (status == STATUS_ALLOCATION_FAILED)
4148
fprintf (stderr, "Memory allocation failed.\n");
4151
/* Otherwise, it might not have been a mangled name. Just
4152
print out the original text. */
4154
fputs (dyn_string_buf (mangled), stdout);
4156
/* If we haven't hit EOF yet, we've read one character that
4157
can't occur in a mangled name, so print it out. */
4161
/* Clear the candidate mangled name, to start afresh next
4162
time we hit a `_Z'. */
4163
dyn_string_clear (mangled);
4166
dyn_string_delete (mangled);
4167
dyn_string_delete (demangled);
4170
/* Demangle command line arguments. */
4172
dyn_string_t result = dyn_string_new (0);
4174
/* Loop over command line arguments. */
4175
for (i = optind; i < argc; ++i)
4177
/* Attempt to demangle. */
4178
status = cp_demangle (argv[i], result, 0);
4180
/* If it worked, print the demangled name. */
4181
if (STATUS_NO_ERROR (status))
4182
printf ("%s\n", dyn_string_buf (result));
4183
/* Abort on allocaiton failures. */
4184
else if (status == STATUS_ALLOCATION_FAILED)
4186
fprintf (stderr, "Memory allocation failed.\n");
4189
/* If not, print the error message to stderr instead. */
4191
fprintf (stderr, "%s\n", status);
4193
dyn_string_delete (result);
4199
#endif /* STANDALONE_DEMANGLER */