merge from gcc
[deliverable/binutils-gdb.git] / libiberty / cp-demangle.c
1 /* Demangler for IA64 / g++ V3 ABI.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3 Written by Alex Samuel <samuel@codesourcery.com>.
4
5 This file is part of GNU CC.
6
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.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 /* This file implements demangling of C++ names mangled according to
23 the IA64 / g++ V3 ABI. Use the cp_demangle function to
24 demangle a mangled name, or compile with the preprocessor macro
25 STANDALONE_DEMANGLER defined to create a demangling filter
26 executable (functionally similar to c++filt, but includes this
27 demangler only). */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <sys/types.h>
34
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38
39 #include <stdio.h>
40
41 #ifdef HAVE_STRING_H
42 #include <string.h>
43 #endif
44
45 #include "ansidecl.h"
46 #include "libiberty.h"
47 #include "dyn-string.h"
48 #include "demangle.h"
49
50 /* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
51 and other debugging output, will be generated. */
52 #ifdef CP_DEMANGLE_DEBUG
53 #define DEMANGLE_TRACE(PRODUCTION, DM) \
54 fprintf (stderr, " -> %-24s at position %3d\n", \
55 (PRODUCTION), current_position (DM));
56 #else
57 #define DEMANGLE_TRACE(PRODUCTION, DM)
58 #endif
59
60 /* Don't include <ctype.h>, to prevent additional unresolved symbols
61 from being dragged into the C++ runtime library. */
62 #define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
63 #define IS_ALPHA(CHAR) \
64 (((CHAR) >= 'a' && (CHAR) <= 'z') \
65 || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
66
67 /* The prefix prepended by GCC to an identifier represnting the
68 anonymous namespace. */
69 #define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
70
71 /* Character(s) to use for namespace separation in demangled output */
72 #define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
73
74 /* If flag_verbose is zero, some simplifications will be made to the
75 output to make it easier to read and supress details that are
76 generally not of interest to the average C++ programmer.
77 Otherwise, the demangled representation will attempt to convey as
78 much information as the mangled form. */
79 static int flag_verbose;
80
81 /* If flag_strict is non-zero, demangle strictly according to the
82 specification -- don't demangle special g++ manglings. */
83 static int flag_strict;
84
85 /* String_list_t is an extended form of dyn_string_t which provides a
86 link field and a caret position for additions to the string. A
87 string_list_t may safely be cast to and used as a dyn_string_t. */
88
89 struct string_list_def
90 {
91 /* The dyn_string; must be first. */
92 struct dyn_string string;
93
94 /* The position at which additional text is added to this string
95 (using the result_add* macros). This value is an offset from the
96 end of the string, not the beginning (and should be
97 non-positive). */
98 int caret_position;
99
100 /* The next string in the list. */
101 struct string_list_def *next;
102 };
103
104 typedef struct string_list_def *string_list_t;
105
106 /* Data structure representing a potential substitution. */
107
108 struct substitution_def
109 {
110 /* The demangled text of the substitution. */
111 dyn_string_t text;
112
113 /* Whether this substitution represents a template item. */
114 int template_p : 1;
115 };
116
117 /* Data structure representing a template argument list. */
118
119 struct template_arg_list_def
120 {
121 /* The next (lower) template argument list in the stack of currently
122 active template arguments. */
123 struct template_arg_list_def *next;
124
125 /* The first element in the list of template arguments in
126 left-to-right order. */
127 string_list_t first_argument;
128
129 /* The last element in the arguments lists. */
130 string_list_t last_argument;
131 };
132
133 typedef struct template_arg_list_def *template_arg_list_t;
134
135 /* Data structure to maintain the state of the current demangling. */
136
137 struct demangling_def
138 {
139 /* The full mangled name being mangled. */
140 const char *name;
141
142 /* Pointer into name at the current position. */
143 const char *next;
144
145 /* Stack for strings containing demangled result generated so far.
146 Text is emitted to the topmost (first) string. */
147 string_list_t result;
148
149 /* The number of presently available substitutions. */
150 int num_substitutions;
151
152 /* The allocated size of the substitutions array. */
153 int substitutions_allocated;
154
155 /* An array of available substitutions. The number of elements in
156 the array is given by num_substitions, and the allocated array
157 size in substitutions_size.
158
159 The most recent substition is at the end, so
160
161 - `S_' corresponds to substititutions[num_substitutions - 1]
162 - `S0_' corresponds to substititutions[num_substitutions - 2]
163
164 etc. */
165 struct substitution_def *substitutions;
166
167 /* The stack of template argument lists. */
168 template_arg_list_t template_arg_lists;
169
170 /* The most recently demangled source-name. */
171 dyn_string_t last_source_name;
172
173 /* Language style to use for demangled output. */
174 int style;
175 };
176
177 typedef struct demangling_def *demangling_t;
178
179 /* This type is the standard return code from most functions. Values
180 other than STATUS_OK contain descriptive messages. */
181 typedef const char *status_t;
182
183 /* Special values that can be used as a status_t. */
184 #define STATUS_OK NULL
185 #define STATUS_ERROR "Error."
186 #define STATUS_UNIMPLEMENTED "Unimplemented."
187 #define STATUS_INTERNAL_ERROR "Internal error."
188
189 /* This status code indicates a failure in malloc or realloc. */
190 static const char *const status_allocation_failed = "Allocation failed.";
191 #define STATUS_ALLOCATION_FAILED status_allocation_failed
192
193 /* Non-zero if STATUS indicates that no error has occurred. */
194 #define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
195
196 /* Evaluate EXPR, which must produce a status_t. If the status code
197 indicates an error, return from the current function with that
198 status code. */
199 #define RETURN_IF_ERROR(EXPR) \
200 do \
201 { \
202 status_t s = EXPR; \
203 if (!STATUS_NO_ERROR (s)) \
204 return s; \
205 } \
206 while (0)
207
208 static status_t int_to_dyn_string
209 PARAMS ((int, dyn_string_t));
210 static string_list_t string_list_new
211 PARAMS ((int));
212 static void string_list_delete
213 PARAMS ((string_list_t));
214 static status_t result_add_separated_char
215 PARAMS ((demangling_t, int));
216 static status_t result_push
217 PARAMS ((demangling_t));
218 static string_list_t result_pop
219 PARAMS ((demangling_t));
220 static int substitution_start
221 PARAMS ((demangling_t));
222 static status_t substitution_add
223 PARAMS ((demangling_t, int, int));
224 static dyn_string_t substitution_get
225 PARAMS ((demangling_t, int, int *));
226 #ifdef CP_DEMANGLE_DEBUG
227 static void substitutions_print
228 PARAMS ((demangling_t, FILE *));
229 #endif
230 static template_arg_list_t template_arg_list_new
231 PARAMS ((void));
232 static void template_arg_list_delete
233 PARAMS ((template_arg_list_t));
234 static void template_arg_list_add_arg
235 PARAMS ((template_arg_list_t, string_list_t));
236 static string_list_t template_arg_list_get_arg
237 PARAMS ((template_arg_list_t, int));
238 static void push_template_arg_list
239 PARAMS ((demangling_t, template_arg_list_t));
240 static void pop_to_template_arg_list
241 PARAMS ((demangling_t, template_arg_list_t));
242 #ifdef CP_DEMANGLE_DEBUG
243 static void template_arg_list_print
244 PARAMS ((template_arg_list_t, FILE *));
245 #endif
246 static template_arg_list_t current_template_arg_list
247 PARAMS ((demangling_t));
248 static demangling_t demangling_new
249 PARAMS ((const char *, int));
250 static void demangling_delete
251 PARAMS ((demangling_t));
252
253 /* The last character of DS. Warning: DS is evaluated twice. */
254 #define dyn_string_last_char(DS) \
255 (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
256
257 /* Append a space character (` ') to DS if it does not already end
258 with one. Evaluates to 1 on success, or 0 on allocation failure. */
259 #define dyn_string_append_space(DS) \
260 ((dyn_string_length (DS) > 0 \
261 && dyn_string_last_char (DS) != ' ') \
262 ? dyn_string_append_char ((DS), ' ') \
263 : 1)
264
265 /* Returns the index of the current position in the mangled name. */
266 #define current_position(DM) ((DM)->next - (DM)->name)
267
268 /* Returns the character at the current position of the mangled name. */
269 #define peek_char(DM) (*((DM)->next))
270
271 /* Returns the character one past the current position of the mangled
272 name. */
273 #define peek_char_next(DM) \
274 (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
275
276 /* Returns the character at the current position, and advances the
277 current position to the next character. */
278 #define next_char(DM) (*((DM)->next)++)
279
280 /* Returns non-zero if the current position is the end of the mangled
281 name, i.e. one past the last character. */
282 #define end_of_name_p(DM) (peek_char (DM) == '\0')
283
284 /* Advances the current position by one character. */
285 #define advance_char(DM) (++(DM)->next)
286
287 /* Returns the string containing the current demangled result. */
288 #define result_string(DM) (&(DM)->result->string)
289
290 /* Returns the position at which new text is inserted into the
291 demangled result. */
292 #define result_caret_pos(DM) \
293 (result_length (DM) + \
294 ((string_list_t) result_string (DM))->caret_position)
295
296 /* Adds a dyn_string_t to the demangled result. */
297 #define result_add_string(DM, STRING) \
298 (dyn_string_insert (&(DM)->result->string, \
299 result_caret_pos (DM), (STRING)) \
300 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
301
302 /* Adds NUL-terminated string CSTR to the demangled result. */
303 #define result_add(DM, CSTR) \
304 (dyn_string_insert_cstr (&(DM)->result->string, \
305 result_caret_pos (DM), (CSTR)) \
306 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
307
308 /* Adds character CHAR to the demangled result. */
309 #define result_add_char(DM, CHAR) \
310 (dyn_string_insert_char (&(DM)->result->string, \
311 result_caret_pos (DM), (CHAR)) \
312 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
313
314 /* Inserts a dyn_string_t to the demangled result at position POS. */
315 #define result_insert_string(DM, POS, STRING) \
316 (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
317 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
318
319 /* Inserts NUL-terminated string CSTR to the demangled result at
320 position POS. */
321 #define result_insert(DM, POS, CSTR) \
322 (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
323 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
324
325 /* Inserts character CHAR to the demangled result at position POS. */
326 #define result_insert_char(DM, POS, CHAR) \
327 (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
328 ? STATUS_OK : STATUS_ALLOCATION_FAILED)
329
330 /* The length of the current demangled result. */
331 #define result_length(DM) \
332 dyn_string_length (&(DM)->result->string)
333
334 /* Appends a (less-than, greater-than) character to the result in DM
335 to (open, close) a template argument or parameter list. Appends a
336 space first if necessary to prevent spurious elision of angle
337 brackets with the previous character. */
338 #define result_open_template_list(DM) result_add_separated_char(DM, '<')
339 #define result_close_template_list(DM) result_add_separated_char(DM, '>')
340
341 /* Appends a base 10 representation of VALUE to DS. STATUS_OK on
342 success. On failure, deletes DS and returns an error code. */
343
344 static status_t
345 int_to_dyn_string (value, ds)
346 int value;
347 dyn_string_t ds;
348 {
349 int i;
350 int mask = 1;
351
352 /* Handle zero up front. */
353 if (value == 0)
354 {
355 if (!dyn_string_append_char (ds, '0'))
356 return STATUS_ALLOCATION_FAILED;
357 return STATUS_OK;
358 }
359
360 /* For negative numbers, emit a minus sign. */
361 if (value < 0)
362 {
363 if (!dyn_string_append_char (ds, '-'))
364 return STATUS_ALLOCATION_FAILED;
365 value = -value;
366 }
367
368 /* Find the power of 10 of the first digit. */
369 i = value;
370 while (i > 9)
371 {
372 mask *= 10;
373 i /= 10;
374 }
375
376 /* Write the digits. */
377 while (mask > 0)
378 {
379 int digit = value / mask;
380
381 if (!dyn_string_append_char (ds, '0' + digit))
382 return STATUS_ALLOCATION_FAILED;
383
384 value -= digit * mask;
385 mask /= 10;
386 }
387
388 return STATUS_OK;
389 }
390
391 /* Creates a new string list node. The contents of the string are
392 empty, but the initial buffer allocation is LENGTH. The string
393 list node should be deleted with string_list_delete. Returns NULL
394 if allocation fails. */
395
396 static string_list_t
397 string_list_new (length)
398 int length;
399 {
400 string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
401 s->caret_position = 0;
402 if (s == NULL)
403 return NULL;
404 if (!dyn_string_init ((dyn_string_t) s, length))
405 return NULL;
406 return s;
407 }
408
409 /* Deletes the entire string list starting at NODE. */
410
411 static void
412 string_list_delete (node)
413 string_list_t node;
414 {
415 while (node != NULL)
416 {
417 string_list_t next = node->next;
418 free (node);
419 node = next;
420 }
421 }
422
423 /* Appends CHARACTER to the demangled result. If the current trailing
424 character of the result is CHARACTER, a space is inserted first. */
425
426 static status_t
427 result_add_separated_char (dm, character)
428 demangling_t dm;
429 int character;
430 {
431 char *result = dyn_string_buf (result_string (dm));
432 int caret_pos = result_caret_pos (dm);
433
434 /* Add a space if the last character is already the character we
435 want to add. */
436 if (caret_pos > 0 && result[caret_pos - 1] == character)
437 RETURN_IF_ERROR (result_add_char (dm, ' '));
438 /* Add the character. */
439 RETURN_IF_ERROR (result_add_char (dm, character));
440
441 return STATUS_OK;
442 }
443
444 /* Allocates and pushes a new string onto the demangled results stack
445 for DM. Subsequent demangling with DM will emit to the new string.
446 Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
447 allocation failure. */
448
449 static status_t
450 result_push (dm)
451 demangling_t dm;
452 {
453 string_list_t new_string = string_list_new (0);
454 if (new_string == NULL)
455 /* Allocation failed. */
456 return STATUS_ALLOCATION_FAILED;
457
458 /* Link the new string to the front of the list of result strings. */
459 new_string->next = (string_list_t) dm->result;
460 dm->result = new_string;
461 return STATUS_OK;
462 }
463
464 /* Removes and returns the topmost element on the demangled results
465 stack for DM. The caller assumes ownership for the returned
466 string. */
467
468 static string_list_t
469 result_pop (dm)
470 demangling_t dm;
471 {
472 string_list_t top = dm->result;
473 dm->result = top->next;
474 return top;
475 }
476
477 /* Returns the current value of the caret for the result string. The
478 value is an offet from the end of the result string. */
479
480 static int
481 result_get_caret (dm)
482 demangling_t dm;
483 {
484 return ((string_list_t) result_string (dm))->caret_position;
485 }
486
487 /* Sets the value of the caret for the result string, counted as an
488 offet from the end of the result string. */
489
490 static void
491 result_set_caret (dm, position)
492 demangling_t dm;
493 int position;
494 {
495 ((string_list_t) result_string (dm))->caret_position = position;
496 }
497
498 /* Shifts the position of the next addition to the result by
499 POSITION_OFFSET. A negative value shifts the caret to the left. */
500
501 static void
502 result_shift_caret (dm, position_offset)
503 demangling_t dm;
504 int position_offset;
505 {
506 ((string_list_t) result_string (dm))->caret_position += position_offset;
507 }
508
509 /* Returns non-zero if the character that comes right before the place
510 where text will be added to the result is a space. In this case,
511 the caller should supress adding another space. */
512
513 static int
514 result_previous_char_is_space (dm)
515 demangling_t dm;
516 {
517 char *result = dyn_string_buf (result_string (dm));
518 int pos = result_caret_pos (dm);
519 return pos > 0 && result[pos - 1] == ' ';
520 }
521
522 /* Returns the start position of a fragment of the demangled result
523 that will be a substitution candidate. Should be called at the
524 start of productions that can add substitutions. */
525
526 static int
527 substitution_start (dm)
528 demangling_t dm;
529 {
530 return result_caret_pos (dm);
531 }
532
533 /* Adds the suffix of the current demangled result of DM starting at
534 START_POSITION as a potential substitution. If TEMPLATE_P is
535 non-zero, this potential substitution is a template-id. */
536
537 static status_t
538 substitution_add (dm, start_position, template_p)
539 demangling_t dm;
540 int start_position;
541 int template_p;
542 {
543 dyn_string_t result = result_string (dm);
544 dyn_string_t substitution = dyn_string_new (0);
545 int i;
546
547 if (substitution == NULL)
548 return STATUS_ALLOCATION_FAILED;
549
550 /* Extract the substring of the current demangling result that
551 represents the subsitution candidate. */
552 if (!dyn_string_substring (substitution,
553 result, start_position, result_caret_pos (dm)))
554 {
555 dyn_string_delete (substitution);
556 return STATUS_ALLOCATION_FAILED;
557 }
558
559 /* If there's no room for the new entry, grow the array. */
560 if (dm->substitutions_allocated == dm->num_substitutions)
561 {
562 size_t new_array_size;
563 if (dm->substitutions_allocated > 0)
564 dm->substitutions_allocated *= 2;
565 else
566 dm->substitutions_allocated = 2;
567 new_array_size =
568 sizeof (struct substitution_def) * dm->substitutions_allocated;
569
570 dm->substitutions = (struct substitution_def *)
571 realloc (dm->substitutions, new_array_size);
572 if (dm->substitutions == NULL)
573 /* Realloc failed. */
574 {
575 dyn_string_delete (substitution);
576 return STATUS_ALLOCATION_FAILED;
577 }
578 }
579
580 /* Add the substitution to the array. */
581 i = dm->num_substitutions++;
582 dm->substitutions[i].text = substitution;
583 dm->substitutions[i].template_p = template_p;
584
585 #ifdef CP_DEMANGLE_DEBUG
586 substitutions_print (dm, stderr);
587 #endif
588
589 return STATUS_OK;
590 }
591
592 /* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
593 non-zero if the substitution is a template-id, zero otherwise.
594 N is numbered from zero. DM retains ownership of the returned
595 string. If N is negative, or equal to or greater than the current
596 number of substitution candidates, returns NULL. */
597
598 static dyn_string_t
599 substitution_get (dm, n, template_p)
600 demangling_t dm;
601 int n;
602 int *template_p;
603 {
604 struct substitution_def *sub;
605
606 /* Make sure N is in the valid range. */
607 if (n < 0 || n >= dm->num_substitutions)
608 return NULL;
609
610 sub = &(dm->substitutions[n]);
611 *template_p = sub->template_p;
612 return sub->text;
613 }
614
615 #ifdef CP_DEMANGLE_DEBUG
616 /* Debugging routine to print the current substitutions to FP. */
617
618 static void
619 substitutions_print (dm, fp)
620 demangling_t dm;
621 FILE *fp;
622 {
623 int seq_id;
624 int num = dm->num_substitutions;
625
626 fprintf (fp, "SUBSTITUTIONS:\n");
627 for (seq_id = -1; seq_id < num - 1; ++seq_id)
628 {
629 int template_p;
630 dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
631
632 if (seq_id == -1)
633 fprintf (fp, " S_ ");
634 else
635 fprintf (fp, " S%d_", seq_id);
636 fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
637 }
638 }
639
640 #endif /* CP_DEMANGLE_DEBUG */
641
642 /* Creates a new template argument list. Returns NULL if allocation
643 fails. */
644
645 static template_arg_list_t
646 template_arg_list_new ()
647 {
648 template_arg_list_t new_list =
649 (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
650 if (new_list == NULL)
651 return NULL;
652 /* Initialize the new list to have no arguments. */
653 new_list->first_argument = NULL;
654 new_list->last_argument = NULL;
655 /* Return the new list. */
656 return new_list;
657 }
658
659 /* Deletes a template argument list and the template arguments it
660 contains. */
661
662 static void
663 template_arg_list_delete (list)
664 template_arg_list_t list;
665 {
666 /* If there are any arguments on LIST, delete them. */
667 if (list->first_argument != NULL)
668 string_list_delete (list->first_argument);
669 /* Delete LIST. */
670 free (list);
671 }
672
673 /* Adds ARG to the template argument list ARG_LIST. */
674
675 static void
676 template_arg_list_add_arg (arg_list, arg)
677 template_arg_list_t arg_list;
678 string_list_t arg;
679 {
680 if (arg_list->first_argument == NULL)
681 /* If there were no arguments before, ARG is the first one. */
682 arg_list->first_argument = arg;
683 else
684 /* Make ARG the last argument on the list. */
685 arg_list->last_argument->next = arg;
686 /* Make ARG the last on the list. */
687 arg_list->last_argument = arg;
688 arg->next = NULL;
689 }
690
691 /* Returns the template arugment at position INDEX in template
692 argument list ARG_LIST. */
693
694 static string_list_t
695 template_arg_list_get_arg (arg_list, index)
696 template_arg_list_t arg_list;
697 int index;
698 {
699 string_list_t arg = arg_list->first_argument;
700 /* Scan down the list of arguments to find the one at position
701 INDEX. */
702 while (index--)
703 {
704 arg = arg->next;
705 if (arg == NULL)
706 /* Ran out of arguments before INDEX hit zero. That's an
707 error. */
708 return NULL;
709 }
710 /* Return the argument at position INDEX. */
711 return arg;
712 }
713
714 /* Pushes ARG_LIST onto the top of the template argument list stack. */
715
716 static void
717 push_template_arg_list (dm, arg_list)
718 demangling_t dm;
719 template_arg_list_t arg_list;
720 {
721 arg_list->next = dm->template_arg_lists;
722 dm->template_arg_lists = arg_list;
723 #ifdef CP_DEMANGLE_DEBUG
724 fprintf (stderr, " ** pushing template arg list\n");
725 template_arg_list_print (arg_list, stderr);
726 #endif
727 }
728
729 /* Pops and deletes elements on the template argument list stack until
730 arg_list is the topmost element. If arg_list is NULL, all elements
731 are popped and deleted. */
732
733 static void
734 pop_to_template_arg_list (dm, arg_list)
735 demangling_t dm;
736 template_arg_list_t arg_list;
737 {
738 while (dm->template_arg_lists != arg_list)
739 {
740 template_arg_list_t top = dm->template_arg_lists;
741 /* Disconnect the topmost element from the list. */
742 dm->template_arg_lists = top->next;
743 /* Delete the popped element. */
744 template_arg_list_delete (top);
745 #ifdef CP_DEMANGLE_DEBUG
746 fprintf (stderr, " ** removing template arg list\n");
747 #endif
748 }
749 }
750
751 #ifdef CP_DEMANGLE_DEBUG
752
753 /* Prints the contents of ARG_LIST to FP. */
754
755 static void
756 template_arg_list_print (arg_list, fp)
757 template_arg_list_t arg_list;
758 FILE *fp;
759 {
760 string_list_t arg;
761 int index = -1;
762
763 fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
764 for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
765 {
766 if (index == -1)
767 fprintf (fp, " T_ : ");
768 else
769 fprintf (fp, " T%d_ : ", index);
770 ++index;
771 fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
772 }
773 }
774
775 #endif /* CP_DEMANGLE_DEBUG */
776
777 /* Returns the topmost element on the stack of template argument
778 lists. If there is no list of template arguments, returns NULL. */
779
780 static template_arg_list_t
781 current_template_arg_list (dm)
782 demangling_t dm;
783 {
784 return dm->template_arg_lists;
785 }
786
787 /* Allocates a demangling_t object for demangling mangled NAME. A new
788 result must be pushed before the returned object can be used.
789 Returns NULL if allocation fails. */
790
791 static demangling_t
792 demangling_new (name, style)
793 const char *name;
794 int style;
795 {
796 demangling_t dm;
797 dm = (demangling_t) malloc (sizeof (struct demangling_def));
798 if (dm == NULL)
799 return NULL;
800
801 dm->name = name;
802 dm->next = name;
803 dm->result = NULL;
804 dm->num_substitutions = 0;
805 dm->substitutions_allocated = 10;
806 dm->template_arg_lists = NULL;
807 dm->last_source_name = dyn_string_new (0);
808 if (dm->last_source_name == NULL)
809 return NULL;
810 dm->substitutions = (struct substitution_def *)
811 malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
812 if (dm->substitutions == NULL)
813 {
814 dyn_string_delete (dm->last_source_name);
815 return NULL;
816 }
817 dm->style = style;
818
819 return dm;
820 }
821
822 /* Deallocates a demangling_t object and all memory associated with
823 it. */
824
825 static void
826 demangling_delete (dm)
827 demangling_t dm;
828 {
829 int i;
830 template_arg_list_t arg_list = dm->template_arg_lists;
831
832 /* Delete the stack of template argument lists. */
833 while (arg_list != NULL)
834 {
835 template_arg_list_t next = arg_list->next;
836 template_arg_list_delete (arg_list);
837 arg_list = next;
838 }
839 /* Delete the list of substitutions. */
840 for (i = dm->num_substitutions; --i >= 0; )
841 dyn_string_delete (dm->substitutions[i].text);
842 free (dm->substitutions);
843 /* Delete the demangled result. */
844 string_list_delete (dm->result);
845 /* Delete the stored identifier name. */
846 dyn_string_delete (dm->last_source_name);
847 /* Delete the context object itself. */
848 free (dm);
849 }
850
851 /* These functions demangle an alternative of the corresponding
852 production in the mangling spec. The first argument of each is a
853 demangling context structure for the current demangling
854 operation. Most emit demangled text directly to the topmost result
855 string on the result string stack in the demangling context
856 structure. */
857
858 static status_t demangle_char
859 PARAMS ((demangling_t, int));
860 static status_t demangle_mangled_name
861 PARAMS ((demangling_t));
862 static status_t demangle_encoding
863 PARAMS ((demangling_t));
864 static status_t demangle_name
865 PARAMS ((demangling_t, int *));
866 static status_t demangle_nested_name
867 PARAMS ((demangling_t, int *));
868 static status_t demangle_prefix
869 PARAMS ((demangling_t, int *));
870 static status_t demangle_unqualified_name
871 PARAMS ((demangling_t, int *));
872 static status_t demangle_source_name
873 PARAMS ((demangling_t));
874 static status_t demangle_number
875 PARAMS ((demangling_t, int *, int, int));
876 static status_t demangle_number_literally
877 PARAMS ((demangling_t, dyn_string_t, int, int));
878 static status_t demangle_identifier
879 PARAMS ((demangling_t, int, dyn_string_t));
880 static status_t demangle_operator_name
881 PARAMS ((demangling_t, int, int *));
882 static status_t demangle_nv_offset
883 PARAMS ((demangling_t));
884 static status_t demangle_v_offset
885 PARAMS ((demangling_t));
886 static status_t demangle_call_offset
887 PARAMS ((demangling_t));
888 static status_t demangle_special_name
889 PARAMS ((demangling_t));
890 static status_t demangle_ctor_dtor_name
891 PARAMS ((demangling_t));
892 static status_t demangle_type_ptr
893 PARAMS ((demangling_t, int *, int));
894 static status_t demangle_type
895 PARAMS ((demangling_t));
896 static status_t demangle_CV_qualifiers
897 PARAMS ((demangling_t, dyn_string_t));
898 static status_t demangle_builtin_type
899 PARAMS ((demangling_t));
900 static status_t demangle_function_type
901 PARAMS ((demangling_t, int *));
902 static status_t demangle_bare_function_type
903 PARAMS ((demangling_t, int *));
904 static status_t demangle_class_enum_type
905 PARAMS ((demangling_t, int *));
906 static status_t demangle_array_type
907 PARAMS ((demangling_t, int *));
908 static status_t demangle_template_param
909 PARAMS ((demangling_t));
910 static status_t demangle_template_args
911 PARAMS ((demangling_t));
912 static status_t demangle_literal
913 PARAMS ((demangling_t));
914 static status_t demangle_template_arg
915 PARAMS ((demangling_t));
916 static status_t demangle_expression
917 PARAMS ((demangling_t));
918 static status_t demangle_scope_expression
919 PARAMS ((demangling_t));
920 static status_t demangle_expr_primary
921 PARAMS ((demangling_t));
922 static status_t demangle_substitution
923 PARAMS ((demangling_t, int *));
924 static status_t demangle_local_name
925 PARAMS ((demangling_t));
926 static status_t demangle_discriminator
927 PARAMS ((demangling_t, int));
928 static status_t cp_demangle
929 PARAMS ((const char *, dyn_string_t, int));
930 #ifdef IN_LIBGCC2
931 static status_t cp_demangle_type
932 PARAMS ((const char*, dyn_string_t));
933 #endif
934
935 /* When passed to demangle_bare_function_type, indicates that the
936 function's return type is not encoded before its parameter types. */
937 #define BFT_NO_RETURN_TYPE NULL
938
939 /* Check that the next character is C. If so, consume it. If not,
940 return an error. */
941
942 static status_t
943 demangle_char (dm, c)
944 demangling_t dm;
945 int c;
946 {
947 static char *error_message = NULL;
948
949 if (peek_char (dm) == c)
950 {
951 advance_char (dm);
952 return STATUS_OK;
953 }
954 else
955 {
956 if (error_message == NULL)
957 error_message = strdup ("Expected ?");
958 error_message[9] = c;
959 return error_message;
960 }
961 }
962
963 /* Demangles and emits a <mangled-name>.
964
965 <mangled-name> ::= _Z <encoding> */
966
967 static status_t
968 demangle_mangled_name (dm)
969 demangling_t dm;
970 {
971 DEMANGLE_TRACE ("mangled-name", dm);
972 RETURN_IF_ERROR (demangle_char (dm, '_'));
973 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
974 RETURN_IF_ERROR (demangle_encoding (dm));
975 return STATUS_OK;
976 }
977
978 /* Demangles and emits an <encoding>.
979
980 <encoding> ::= <function name> <bare-function-type>
981 ::= <data name>
982 ::= <special-name> */
983
984 static status_t
985 demangle_encoding (dm)
986 demangling_t dm;
987 {
988 int encode_return_type;
989 int start_position;
990 template_arg_list_t old_arg_list = current_template_arg_list (dm);
991 char peek = peek_char (dm);
992
993 DEMANGLE_TRACE ("encoding", dm);
994
995 /* Remember where the name starts. If it turns out to be a template
996 function, we'll have to insert the return type here. */
997 start_position = result_caret_pos (dm);
998
999 if (peek == 'G' || peek == 'T')
1000 RETURN_IF_ERROR (demangle_special_name (dm));
1001 else
1002 {
1003 /* Now demangle the name. */
1004 RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
1005
1006 /* If there's anything left, the name was a function name, with
1007 maybe its return type, and its parameter types, following. */
1008 if (!end_of_name_p (dm)
1009 && peek_char (dm) != 'E')
1010 {
1011 if (encode_return_type)
1012 /* Template functions have their return type encoded. The
1013 return type should be inserted at start_position. */
1014 RETURN_IF_ERROR
1015 (demangle_bare_function_type (dm, &start_position));
1016 else
1017 /* Non-template functions don't have their return type
1018 encoded. */
1019 RETURN_IF_ERROR
1020 (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
1021 }
1022 }
1023
1024 /* Pop off template argument lists that were built during the
1025 mangling of this name, to restore the old template context. */
1026 pop_to_template_arg_list (dm, old_arg_list);
1027
1028 return STATUS_OK;
1029 }
1030
1031 /* Demangles and emits a <name>.
1032
1033 <name> ::= <unscoped-name>
1034 ::= <unscoped-template-name> <template-args>
1035 ::= <nested-name>
1036 ::= <local-name>
1037
1038 <unscoped-name> ::= <unqualified-name>
1039 ::= St <unqualified-name> # ::std::
1040
1041 <unscoped-template-name>
1042 ::= <unscoped-name>
1043 ::= <substitution> */
1044
1045 static status_t
1046 demangle_name (dm, encode_return_type)
1047 demangling_t dm;
1048 int *encode_return_type;
1049 {
1050 int start = substitution_start (dm);
1051 char peek = peek_char (dm);
1052 int is_std_substitution = 0;
1053
1054 /* Generally, the return type is encoded if the function is a
1055 template-id, and suppressed otherwise. There are a few cases,
1056 though, in which the return type is not encoded even for a
1057 templated function. In these cases, this flag is set. */
1058 int suppress_return_type = 0;
1059
1060 DEMANGLE_TRACE ("name", dm);
1061
1062 switch (peek)
1063 {
1064 case 'N':
1065 /* This is a <nested-name>. */
1066 RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type));
1067 break;
1068
1069 case 'Z':
1070 RETURN_IF_ERROR (demangle_local_name (dm));
1071 *encode_return_type = 0;
1072 break;
1073
1074 case 'S':
1075 /* The `St' substitution allows a name nested in std:: to appear
1076 without being enclosed in a nested name. */
1077 if (peek_char_next (dm) == 't')
1078 {
1079 (void) next_char (dm);
1080 (void) next_char (dm);
1081 RETURN_IF_ERROR (result_add (dm, "std::"));
1082 RETURN_IF_ERROR
1083 (demangle_unqualified_name (dm, &suppress_return_type));
1084 is_std_substitution = 1;
1085 }
1086 else
1087 RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1088 /* Check if a template argument list immediately follows.
1089 If so, then we just demangled an <unqualified-template-name>. */
1090 if (peek_char (dm) == 'I')
1091 {
1092 /* A template name of the form std::<unqualified-name> is a
1093 substitution candidate. */
1094 if (is_std_substitution)
1095 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1096 /* Demangle the <template-args> here. */
1097 RETURN_IF_ERROR (demangle_template_args (dm));
1098 *encode_return_type = !suppress_return_type;
1099 }
1100 else
1101 *encode_return_type = 0;
1102
1103 break;
1104
1105 default:
1106 /* This is an <unscoped-name> or <unscoped-template-name>. */
1107 RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type));
1108
1109 /* If the <unqualified-name> is followed by template args, this
1110 is an <unscoped-template-name>. */
1111 if (peek_char (dm) == 'I')
1112 {
1113 /* Add a substitution for the unqualified template name. */
1114 RETURN_IF_ERROR (substitution_add (dm, start, 0));
1115
1116 RETURN_IF_ERROR (demangle_template_args (dm));
1117 *encode_return_type = !suppress_return_type;
1118 }
1119 else
1120 *encode_return_type = 0;
1121
1122 break;
1123 }
1124
1125 return STATUS_OK;
1126 }
1127
1128 /* Demangles and emits a <nested-name>.
1129
1130 <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
1131
1132 static status_t
1133 demangle_nested_name (dm, encode_return_type)
1134 demangling_t dm;
1135 int *encode_return_type;
1136 {
1137 char peek;
1138
1139 DEMANGLE_TRACE ("nested-name", dm);
1140
1141 RETURN_IF_ERROR (demangle_char (dm, 'N'));
1142
1143 peek = peek_char (dm);
1144 if (peek == 'r' || peek == 'V' || peek == 'K')
1145 {
1146 dyn_string_t cv_qualifiers;
1147 status_t status;
1148
1149 /* Snarf up CV qualifiers. */
1150 cv_qualifiers = dyn_string_new (24);
1151 if (cv_qualifiers == NULL)
1152 return STATUS_ALLOCATION_FAILED;
1153 demangle_CV_qualifiers (dm, cv_qualifiers);
1154
1155 /* Emit them, preceded by a space. */
1156 status = result_add_char (dm, ' ');
1157 if (STATUS_NO_ERROR (status))
1158 status = result_add_string (dm, cv_qualifiers);
1159 /* The CV qualifiers that occur in a <nested-name> will be
1160 qualifiers for member functions. These are placed at the end
1161 of the function. Therefore, shift the caret to the left by
1162 the length of the qualifiers, so other text is inserted
1163 before them and they stay at the end. */
1164 result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1);
1165 /* Clean up. */
1166 dyn_string_delete (cv_qualifiers);
1167 RETURN_IF_ERROR (status);
1168 }
1169
1170 RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
1171 /* No need to demangle the final <unqualified-name>; demangle_prefix
1172 will handle it. */
1173 RETURN_IF_ERROR (demangle_char (dm, 'E'));
1174
1175 return STATUS_OK;
1176 }
1177
1178 /* Demangles and emits a <prefix>.
1179
1180 <prefix> ::= <prefix> <unqualified-name>
1181 ::= <template-prefix> <template-args>
1182 ::= # empty
1183 ::= <substitution>
1184
1185 <template-prefix> ::= <prefix>
1186 ::= <substitution> */
1187
1188 static status_t
1189 demangle_prefix (dm, encode_return_type)
1190 demangling_t dm;
1191 int *encode_return_type;
1192 {
1193 int start = substitution_start (dm);
1194 int nested = 0;
1195
1196 /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
1197 After <template-args>, it is set to non-zero; after everything
1198 else it is set to zero. */
1199
1200 /* Generally, the return type is encoded if the function is a
1201 template-id, and suppressed otherwise. There are a few cases,
1202 though, in which the return type is not encoded even for a
1203 templated function. In these cases, this flag is set. */
1204 int suppress_return_type = 0;
1205
1206 DEMANGLE_TRACE ("prefix", dm);
1207
1208 while (1)
1209 {
1210 char peek;
1211
1212 if (end_of_name_p (dm))
1213 return "Unexpected end of name in <compound-name>.";
1214
1215 peek = peek_char (dm);
1216
1217 /* We'll initialize suppress_return_type to false, and set it to true
1218 if we end up demangling a constructor name. However, make
1219 sure we're not actually about to demangle template arguments
1220 -- if so, this is the <template-args> following a
1221 <template-prefix>, so we'll want the previous flag value
1222 around. */
1223 if (peek != 'I')
1224 suppress_return_type = 0;
1225
1226 if (IS_DIGIT ((unsigned char) peek)
1227 || (peek >= 'a' && peek <= 'z')
1228 || peek == 'C' || peek == 'D'
1229 || peek == 'S')
1230 {
1231 /* We have another level of scope qualification. */
1232 if (nested)
1233 RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR));
1234 else
1235 nested = 1;
1236
1237 if (peek == 'S')
1238 /* The substitution determines whether this is a
1239 template-id. */
1240 RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
1241 else
1242 {
1243 /* It's just a name. */
1244 RETURN_IF_ERROR
1245 (demangle_unqualified_name (dm, &suppress_return_type));
1246 *encode_return_type = 0;
1247 }
1248 }
1249 else if (peek == 'Z')
1250 RETURN_IF_ERROR (demangle_local_name (dm));
1251 else if (peek == 'I')
1252 {
1253 RETURN_IF_ERROR (demangle_template_args (dm));
1254
1255 /* Now we want to indicate to the caller that we've
1256 demangled template arguments, thus the prefix was a
1257 <template-prefix>. That's so that the caller knows to
1258 demangle the function's return type, if this turns out to
1259 be a function name. But, if it's a member template
1260 constructor or a templated conversion operator, report it
1261 as untemplated. Those never get encoded return types. */
1262 *encode_return_type = !suppress_return_type;
1263 }
1264 else if (peek == 'E')
1265 /* All done. */
1266 return STATUS_OK;
1267 else
1268 return "Unexpected character in <compound-name>.";
1269
1270 if (peek != 'S'
1271 && peek_char (dm) != 'E')
1272 /* Add a new substitution for the prefix thus far. */
1273 RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type));
1274 }
1275 }
1276
1277 /* Demangles and emits an <unqualified-name>. If this
1278 <unqualified-name> is for a special function type that should never
1279 have its return type encoded (particularly, a constructor or
1280 conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
1281 it is set to zero.
1282
1283 <unqualified-name> ::= <operator-name>
1284 ::= <special-name>
1285 ::= <source-name> */
1286
1287 static status_t
1288 demangle_unqualified_name (dm, suppress_return_type)
1289 demangling_t dm;
1290 int *suppress_return_type;
1291 {
1292 char peek = peek_char (dm);
1293
1294 DEMANGLE_TRACE ("unqualified-name", dm);
1295
1296 /* By default, don't force suppression of the return type (though
1297 non-template functions still don't get a return type encoded). */
1298 *suppress_return_type = 0;
1299
1300 if (IS_DIGIT ((unsigned char) peek))
1301 RETURN_IF_ERROR (demangle_source_name (dm));
1302 else if (peek >= 'a' && peek <= 'z')
1303 {
1304 int num_args;
1305
1306 /* Conversion operators never have a return type encoded. */
1307 if (peek == 'c' && peek_char_next (dm) == 'v')
1308 *suppress_return_type = 1;
1309
1310 RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1311 }
1312 else if (peek == 'C' || peek == 'D')
1313 {
1314 /* Constructors never have a return type encoded. */
1315 if (peek == 'C')
1316 *suppress_return_type = 1;
1317
1318 RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1319 }
1320 else
1321 return "Unexpected character in <unqualified-name>.";
1322
1323 return STATUS_OK;
1324 }
1325
1326 /* Demangles and emits <source-name>.
1327
1328 <source-name> ::= <length number> <identifier> */
1329
1330 static status_t
1331 demangle_source_name (dm)
1332 demangling_t dm;
1333 {
1334 int length;
1335
1336 DEMANGLE_TRACE ("source-name", dm);
1337
1338 /* Decode the length of the identifier. */
1339 RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1340 if (length == 0)
1341 return "Zero length in <source-name>.";
1342
1343 /* Now the identifier itself. It's placed into last_source_name,
1344 where it can be used to build a constructor or destructor name. */
1345 RETURN_IF_ERROR (demangle_identifier (dm, length,
1346 dm->last_source_name));
1347
1348 /* Emit it. */
1349 RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
1350
1351 return STATUS_OK;
1352 }
1353
1354 /* Demangles a number, either a <number> or a <positive-number> at the
1355 current position, consuming all consecutive digit characters. Sets
1356 *VALUE to the resulting numberand returns STATUS_OK. The number is
1357 interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
1358 is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1359
1360 <number> ::= [n] <positive-number>
1361
1362 <positive-number> ::= <decimal integer> */
1363
1364 static status_t
1365 demangle_number (dm, value, base, is_signed)
1366 demangling_t dm;
1367 int *value;
1368 int base;
1369 int is_signed;
1370 {
1371 dyn_string_t number = dyn_string_new (10);
1372
1373 DEMANGLE_TRACE ("number", dm);
1374
1375 if (number == NULL)
1376 return STATUS_ALLOCATION_FAILED;
1377
1378 demangle_number_literally (dm, number, base, is_signed);
1379 *value = strtol (dyn_string_buf (number), NULL, base);
1380 dyn_string_delete (number);
1381
1382 return STATUS_OK;
1383 }
1384
1385 /* Demangles a number at the current position. The digits (and minus
1386 sign, if present) that make up the number are appended to STR.
1387 Only base-BASE digits are accepted; BASE must be either 10 or 36.
1388 If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1389 accepted. Does not consume a trailing underscore or other
1390 terminating character. */
1391
1392 static status_t
1393 demangle_number_literally (dm, str, base, is_signed)
1394 demangling_t dm;
1395 dyn_string_t str;
1396 int base;
1397 int is_signed;
1398 {
1399 DEMANGLE_TRACE ("number*", dm);
1400
1401 if (base != 10 && base != 36)
1402 return STATUS_INTERNAL_ERROR;
1403
1404 /* An `n' denotes a negative number. */
1405 if (is_signed && peek_char (dm) == 'n')
1406 {
1407 /* Skip past the n. */
1408 advance_char (dm);
1409 /* The normal way to write a negative number is with a minus
1410 sign. */
1411 if (!dyn_string_append_char (str, '-'))
1412 return STATUS_ALLOCATION_FAILED;
1413 }
1414
1415 /* Loop until we hit a non-digit. */
1416 while (1)
1417 {
1418 char peek = peek_char (dm);
1419 if (IS_DIGIT ((unsigned char) peek)
1420 || (base == 36 && peek >= 'A' && peek <= 'Z'))
1421 {
1422 /* Accumulate digits. */
1423 if (!dyn_string_append_char (str, next_char (dm)))
1424 return STATUS_ALLOCATION_FAILED;
1425 }
1426 else
1427 /* Not a digit? All done. */
1428 break;
1429 }
1430
1431 return STATUS_OK;
1432 }
1433
1434 /* Demangles an identifier at the current position of LENGTH
1435 characters and places it in IDENTIFIER. */
1436
1437 static status_t
1438 demangle_identifier (dm, length, identifier)
1439 demangling_t dm;
1440 int length;
1441 dyn_string_t identifier;
1442 {
1443 DEMANGLE_TRACE ("identifier", dm);
1444
1445 dyn_string_clear (identifier);
1446 if (!dyn_string_resize (identifier, length))
1447 return STATUS_ALLOCATION_FAILED;
1448
1449 while (length-- > 0)
1450 {
1451 if (end_of_name_p (dm))
1452 return "Unexpected end of name in <identifier>.";
1453 if (!dyn_string_append_char (identifier, next_char (dm)))
1454 return STATUS_ALLOCATION_FAILED;
1455 }
1456
1457 /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
1458 followed by the source file name and some random characters.
1459 Unless we're in strict mode, decipher these names appropriately. */
1460 if (!flag_strict)
1461 {
1462 char *name = dyn_string_buf (identifier);
1463 int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
1464
1465 /* Compare the first, fixed part. */
1466 if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
1467 {
1468 name += prefix_length;
1469 /* The next character might be a period, an underscore, or
1470 dollar sign, depending on the target architecture's
1471 assembler's capabilities. After that comes an `N'. */
1472 if ((*name == '.' || *name == '_' || *name == '$')
1473 && *(name + 1) == 'N')
1474 /* This looks like the anonymous namespace identifier.
1475 Replace it with something comprehensible. */
1476 dyn_string_copy_cstr (identifier, "(anonymous namespace)");
1477 }
1478 }
1479
1480 return STATUS_OK;
1481 }
1482
1483 /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
1484 the short form is emitted; otherwise the full source form
1485 (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
1486 operands that the operator takes.
1487
1488 <operator-name>
1489 ::= nw # new
1490 ::= na # new[]
1491 ::= dl # delete
1492 ::= da # delete[]
1493 ::= ps # + (unary)
1494 ::= ng # - (unary)
1495 ::= ad # & (unary)
1496 ::= de # * (unary)
1497 ::= co # ~
1498 ::= pl # +
1499 ::= mi # -
1500 ::= ml # *
1501 ::= dv # /
1502 ::= rm # %
1503 ::= an # &
1504 ::= or # |
1505 ::= eo # ^
1506 ::= aS # =
1507 ::= pL # +=
1508 ::= mI # -=
1509 ::= mL # *=
1510 ::= dV # /=
1511 ::= rM # %=
1512 ::= aN # &=
1513 ::= oR # |=
1514 ::= eO # ^=
1515 ::= ls # <<
1516 ::= rs # >>
1517 ::= lS # <<=
1518 ::= rS # >>=
1519 ::= eq # ==
1520 ::= ne # !=
1521 ::= lt # <
1522 ::= gt # >
1523 ::= le # <=
1524 ::= ge # >=
1525 ::= nt # !
1526 ::= aa # &&
1527 ::= oo # ||
1528 ::= pp # ++
1529 ::= mm # --
1530 ::= cm # ,
1531 ::= pm # ->*
1532 ::= pt # ->
1533 ::= cl # ()
1534 ::= ix # []
1535 ::= qu # ?
1536 ::= sz # sizeof
1537 ::= cv <type> # cast
1538 ::= v [0-9] <source-name> # vendor extended operator */
1539
1540 static status_t
1541 demangle_operator_name (dm, short_name, num_args)
1542 demangling_t dm;
1543 int short_name;
1544 int *num_args;
1545 {
1546 struct operator_code
1547 {
1548 /* The mangled code for this operator. */
1549 const char *code;
1550 /* The source name of this operator. */
1551 const char *name;
1552 /* The number of arguments this operator takes. */
1553 int num_args;
1554 };
1555
1556 static const struct operator_code operators[] =
1557 {
1558 { "aN", "&=" , 2 },
1559 { "aS", "=" , 2 },
1560 { "aa", "&&" , 2 },
1561 { "ad", "&" , 1 },
1562 { "an", "&" , 2 },
1563 { "cl", "()" , 0 },
1564 { "cm", "," , 2 },
1565 { "co", "~" , 1 },
1566 { "dV", "/=" , 2 },
1567 { "da", " delete[]", 1 },
1568 { "de", "*" , 1 },
1569 { "dl", " delete" , 1 },
1570 { "dv", "/" , 2 },
1571 { "eO", "^=" , 2 },
1572 { "eo", "^" , 2 },
1573 { "eq", "==" , 2 },
1574 { "ge", ">=" , 2 },
1575 { "gt", ">" , 2 },
1576 { "ix", "[]" , 2 },
1577 { "lS", "<<=" , 2 },
1578 { "le", "<=" , 2 },
1579 { "ls", "<<" , 2 },
1580 { "lt", "<" , 2 },
1581 { "mI", "-=" , 2 },
1582 { "mL", "*=" , 2 },
1583 { "mi", "-" , 2 },
1584 { "ml", "*" , 2 },
1585 { "mm", "--" , 1 },
1586 { "na", " new[]" , 1 },
1587 { "ne", "!=" , 2 },
1588 { "ng", "-" , 1 },
1589 { "nt", "!" , 1 },
1590 { "nw", " new" , 1 },
1591 { "oR", "|=" , 2 },
1592 { "oo", "||" , 2 },
1593 { "or", "|" , 2 },
1594 { "pL", "+=" , 2 },
1595 { "pl", "+" , 2 },
1596 { "pm", "->*" , 2 },
1597 { "pp", "++" , 1 },
1598 { "ps", "+" , 1 },
1599 { "pt", "->" , 2 },
1600 { "qu", "?" , 3 },
1601 { "rM", "%=" , 2 },
1602 { "rS", ">>=" , 2 },
1603 { "rm", "%" , 2 },
1604 { "rs", ">>" , 2 },
1605 { "sz", " sizeof" , 1 }
1606 };
1607
1608 const int num_operators =
1609 sizeof (operators) / sizeof (struct operator_code);
1610
1611 int c0 = next_char (dm);
1612 int c1 = next_char (dm);
1613 const struct operator_code* p1 = operators;
1614 const struct operator_code* p2 = operators + num_operators;
1615
1616 DEMANGLE_TRACE ("operator-name", dm);
1617
1618 /* Is this a vendor-extended operator? */
1619 if (c0 == 'v' && IS_DIGIT (c1))
1620 {
1621 RETURN_IF_ERROR (result_add (dm, "operator "));
1622 RETURN_IF_ERROR (demangle_source_name (dm));
1623 *num_args = 0;
1624 return STATUS_OK;
1625 }
1626
1627 /* Is this a conversion operator? */
1628 if (c0 == 'c' && c1 == 'v')
1629 {
1630 RETURN_IF_ERROR (result_add (dm, "operator "));
1631 /* Demangle the converted-to type. */
1632 RETURN_IF_ERROR (demangle_type (dm));
1633 *num_args = 0;
1634 return STATUS_OK;
1635 }
1636
1637 /* Perform a binary search for the operator code. */
1638 while (1)
1639 {
1640 const struct operator_code* p = p1 + (p2 - p1) / 2;
1641 char match0 = p->code[0];
1642 char match1 = p->code[1];
1643
1644 if (c0 == match0 && c1 == match1)
1645 /* Found it. */
1646 {
1647 if (!short_name)
1648 RETURN_IF_ERROR (result_add (dm, "operator"));
1649 RETURN_IF_ERROR (result_add (dm, p->name));
1650 *num_args = p->num_args;
1651
1652 return STATUS_OK;
1653 }
1654
1655 if (p == p1)
1656 /* Couldn't find it. */
1657 return "Unknown code in <operator-name>.";
1658
1659 /* Try again. */
1660 if (c0 < match0 || (c0 == match0 && c1 < match1))
1661 p2 = p;
1662 else
1663 p1 = p;
1664 }
1665 }
1666
1667 /* Demangles and omits an <nv-offset>.
1668
1669 <nv-offset> ::= <offset number> # non-virtual base override */
1670
1671 static status_t
1672 demangle_nv_offset (dm)
1673 demangling_t dm;
1674 {
1675 dyn_string_t number;
1676 status_t status = STATUS_OK;
1677
1678 DEMANGLE_TRACE ("h-offset", dm);
1679
1680 /* Demangle the offset. */
1681 number = dyn_string_new (4);
1682 if (number == NULL)
1683 return STATUS_ALLOCATION_FAILED;
1684 demangle_number_literally (dm, number, 10, 1);
1685
1686 /* Don't display the offset unless in verbose mode. */
1687 if (flag_verbose)
1688 {
1689 status = result_add (dm, " [nv:");
1690 if (STATUS_NO_ERROR (status))
1691 status = result_add_string (dm, number);
1692 if (STATUS_NO_ERROR (status))
1693 status = result_add_char (dm, ']');
1694 }
1695
1696 /* Clean up. */
1697 dyn_string_delete (number);
1698 RETURN_IF_ERROR (status);
1699 return STATUS_OK;
1700 }
1701
1702 /* Demangles and emits a <v-offset>.
1703
1704 <v-offset> ::= <offset number> _ <virtual offset number>
1705 # virtual base override, with vcall offset */
1706
1707 static status_t
1708 demangle_v_offset (dm)
1709 demangling_t dm;
1710 {
1711 dyn_string_t number;
1712 status_t status = STATUS_OK;
1713
1714 DEMANGLE_TRACE ("v-offset", dm);
1715
1716 /* Demangle the offset. */
1717 number = dyn_string_new (4);
1718 if (number == NULL)
1719 return STATUS_ALLOCATION_FAILED;
1720 demangle_number_literally (dm, number, 10, 1);
1721
1722 /* Don't display the offset unless in verbose mode. */
1723 if (flag_verbose)
1724 {
1725 status = result_add (dm, " [v:");
1726 if (STATUS_NO_ERROR (status))
1727 status = result_add_string (dm, number);
1728 if (STATUS_NO_ERROR (status))
1729 result_add_char (dm, ',');
1730 }
1731 dyn_string_delete (number);
1732 RETURN_IF_ERROR (status);
1733
1734 /* Demangle the separator. */
1735 RETURN_IF_ERROR (demangle_char (dm, '_'));
1736
1737 /* Demangle the vcall offset. */
1738 number = dyn_string_new (4);
1739 if (number == NULL)
1740 return STATUS_ALLOCATION_FAILED;
1741 demangle_number_literally (dm, number, 10, 1);
1742
1743 /* Don't display the vcall offset unless in verbose mode. */
1744 if (flag_verbose)
1745 {
1746 status = result_add_string (dm, number);
1747 if (STATUS_NO_ERROR (status))
1748 status = result_add_char (dm, ']');
1749 }
1750 dyn_string_delete (number);
1751 RETURN_IF_ERROR (status);
1752
1753 return STATUS_OK;
1754 }
1755
1756 /* Demangles and emits a <call-offset>.
1757
1758 <call-offset> ::= h <nv-offset> _
1759 ::= v <v-offset> _ */
1760
1761 static status_t
1762 demangle_call_offset (dm)
1763 demangling_t dm;
1764 {
1765 DEMANGLE_TRACE ("call-offset", dm);
1766
1767 switch (peek_char (dm))
1768 {
1769 case 'h':
1770 advance_char (dm);
1771 /* Demangle the offset. */
1772 RETURN_IF_ERROR (demangle_nv_offset (dm));
1773 /* Demangle the separator. */
1774 RETURN_IF_ERROR (demangle_char (dm, '_'));
1775 break;
1776
1777 case 'v':
1778 advance_char (dm);
1779 /* Demangle the offset. */
1780 RETURN_IF_ERROR (demangle_v_offset (dm));
1781 /* Demangle the separator. */
1782 RETURN_IF_ERROR (demangle_char (dm, '_'));
1783 break;
1784
1785 default:
1786 return "Unrecognized <call-offset>.";
1787 }
1788
1789 return STATUS_OK;
1790 }
1791
1792 /* Demangles and emits a <special-name>.
1793
1794 <special-name> ::= GV <object name> # Guard variable
1795 ::= TV <type> # virtual table
1796 ::= TT <type> # VTT
1797 ::= TI <type> # typeinfo structure
1798 ::= TS <type> # typeinfo name
1799
1800 Other relevant productions include thunks:
1801
1802 <special-name> ::= T <call-offset> <base encoding>
1803 # base is the nominal target function of thunk
1804
1805 <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
1806 # base is the nominal target function of thunk
1807 # first call-offset is 'this' adjustment
1808 # second call-offset is result adjustment
1809
1810 where
1811
1812 <call-offset> ::= h <nv-offset> _
1813 ::= v <v-offset> _
1814
1815 Also demangles the special g++ manglings,
1816
1817 <special-name> ::= TC <type> <offset number> _ <base type>
1818 # construction vtable
1819 ::= TF <type> # typeinfo function (old ABI only)
1820 ::= TJ <type> # java Class structure */
1821
1822 static status_t
1823 demangle_special_name (dm)
1824 demangling_t dm;
1825 {
1826 dyn_string_t number;
1827 int unused;
1828 char peek = peek_char (dm);
1829
1830 DEMANGLE_TRACE ("special-name", dm);
1831
1832 if (peek == 'G')
1833 {
1834 /* A guard variable name. Consume the G. */
1835 advance_char (dm);
1836 RETURN_IF_ERROR (demangle_char (dm, 'V'));
1837 RETURN_IF_ERROR (result_add (dm, "guard variable for "));
1838 RETURN_IF_ERROR (demangle_name (dm, &unused));
1839 }
1840 else if (peek == 'T')
1841 {
1842 status_t status = STATUS_OK;
1843
1844 /* Other C++ implementation miscellania. Consume the T. */
1845 advance_char (dm);
1846
1847 switch (peek_char (dm))
1848 {
1849 case 'V':
1850 /* Virtual table. */
1851 advance_char (dm);
1852 RETURN_IF_ERROR (result_add (dm, "vtable for "));
1853 RETURN_IF_ERROR (demangle_type (dm));
1854 break;
1855
1856 case 'T':
1857 /* VTT structure. */
1858 advance_char (dm);
1859 RETURN_IF_ERROR (result_add (dm, "VTT for "));
1860 RETURN_IF_ERROR (demangle_type (dm));
1861 break;
1862
1863 case 'I':
1864 /* Typeinfo structure. */
1865 advance_char (dm);
1866 RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
1867 RETURN_IF_ERROR (demangle_type (dm));
1868 break;
1869
1870 case 'F':
1871 /* Typeinfo function. Used only in old ABI with new mangling. */
1872 advance_char (dm);
1873 RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
1874 RETURN_IF_ERROR (demangle_type (dm));
1875 break;
1876
1877 case 'S':
1878 /* Character string containing type name, used in typeinfo. */
1879 advance_char (dm);
1880 RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
1881 RETURN_IF_ERROR (demangle_type (dm));
1882 break;
1883
1884 case 'J':
1885 /* The java Class variable corresponding to a C++ class. */
1886 advance_char (dm);
1887 RETURN_IF_ERROR (result_add (dm, "java Class for "));
1888 RETURN_IF_ERROR (demangle_type (dm));
1889 break;
1890
1891 case 'h':
1892 /* Non-virtual thunk. */
1893 advance_char (dm);
1894 RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
1895 RETURN_IF_ERROR (demangle_nv_offset (dm));
1896 /* Demangle the separator. */
1897 RETURN_IF_ERROR (demangle_char (dm, '_'));
1898 /* Demangle and emit the target name and function type. */
1899 RETURN_IF_ERROR (result_add (dm, " to "));
1900 RETURN_IF_ERROR (demangle_encoding (dm));
1901 break;
1902
1903 case 'v':
1904 /* Virtual thunk. */
1905 advance_char (dm);
1906 RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
1907 RETURN_IF_ERROR (demangle_v_offset (dm));
1908 /* Demangle the separator. */
1909 RETURN_IF_ERROR (demangle_char (dm, '_'));
1910 /* Demangle and emit the target function. */
1911 RETURN_IF_ERROR (result_add (dm, " to "));
1912 RETURN_IF_ERROR (demangle_encoding (dm));
1913 break;
1914
1915 case 'c':
1916 /* Covariant return thunk. */
1917 advance_char (dm);
1918 RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
1919 RETURN_IF_ERROR (demangle_call_offset (dm));
1920 RETURN_IF_ERROR (demangle_call_offset (dm));
1921 /* Demangle and emit the target function. */
1922 RETURN_IF_ERROR (result_add (dm, " to "));
1923 RETURN_IF_ERROR (demangle_encoding (dm));
1924 break;
1925
1926 case 'C':
1927 /* TC is a special g++ mangling for a construction vtable. */
1928 if (!flag_strict)
1929 {
1930 dyn_string_t derived_type;
1931
1932 advance_char (dm);
1933 RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
1934
1935 /* Demangle the derived type off to the side. */
1936 RETURN_IF_ERROR (result_push (dm));
1937 RETURN_IF_ERROR (demangle_type (dm));
1938 derived_type = (dyn_string_t) result_pop (dm);
1939
1940 /* Demangle the offset. */
1941 number = dyn_string_new (4);
1942 if (number == NULL)
1943 {
1944 dyn_string_delete (derived_type);
1945 return STATUS_ALLOCATION_FAILED;
1946 }
1947 demangle_number_literally (dm, number, 10, 1);
1948 /* Demangle the underscore separator. */
1949 status = demangle_char (dm, '_');
1950
1951 /* Demangle the base type. */
1952 if (STATUS_NO_ERROR (status))
1953 status = demangle_type (dm);
1954
1955 /* Emit the derived type. */
1956 if (STATUS_NO_ERROR (status))
1957 status = result_add (dm, "-in-");
1958 if (STATUS_NO_ERROR (status))
1959 status = result_add_string (dm, derived_type);
1960 dyn_string_delete (derived_type);
1961
1962 /* Don't display the offset unless in verbose mode. */
1963 if (flag_verbose)
1964 {
1965 status = result_add_char (dm, ' ');
1966 if (STATUS_NO_ERROR (status))
1967 result_add_string (dm, number);
1968 }
1969 dyn_string_delete (number);
1970 RETURN_IF_ERROR (status);
1971 break;
1972 }
1973 /* If flag_strict, fall through. */
1974
1975 default:
1976 return "Unrecognized <special-name>.";
1977 }
1978 }
1979 else
1980 return STATUS_ERROR;
1981
1982 return STATUS_OK;
1983 }
1984
1985 /* Demangles and emits a <ctor-dtor-name>.
1986
1987 <ctor-dtor-name>
1988 ::= C1 # complete object (in-charge) ctor
1989 ::= C2 # base object (not-in-charge) ctor
1990 ::= C3 # complete object (in-charge) allocating ctor
1991 ::= D0 # deleting (in-charge) dtor
1992 ::= D1 # complete object (in-charge) dtor
1993 ::= D2 # base object (not-in-charge) dtor */
1994
1995 static status_t
1996 demangle_ctor_dtor_name (dm)
1997 demangling_t dm;
1998 {
1999 static const char *const ctor_flavors[] =
2000 {
2001 "in-charge",
2002 "not-in-charge",
2003 "allocating"
2004 };
2005 static const char *const dtor_flavors[] =
2006 {
2007 "in-charge deleting",
2008 "in-charge",
2009 "not-in-charge"
2010 };
2011
2012 int flavor;
2013 char peek = peek_char (dm);
2014
2015 DEMANGLE_TRACE ("ctor-dtor-name", dm);
2016
2017 if (peek == 'C')
2018 {
2019 /* A constructor name. Consume the C. */
2020 advance_char (dm);
2021 if (peek_char (dm) < '1' || peek_char (dm) > '3')
2022 return "Unrecognized constructor.";
2023 RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
2024 /* Print the flavor of the constructor if in verbose mode. */
2025 flavor = next_char (dm) - '1';
2026 if (flag_verbose)
2027 {
2028 RETURN_IF_ERROR (result_add (dm, "["));
2029 RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor]));
2030 RETURN_IF_ERROR (result_add_char (dm, ']'));
2031 }
2032 }
2033 else if (peek == 'D')
2034 {
2035 /* A destructor name. Consume the D. */
2036 advance_char (dm);
2037 if (peek_char (dm) < '0' || peek_char (dm) > '2')
2038 return "Unrecognized destructor.";
2039 RETURN_IF_ERROR (result_add_char (dm, '~'));
2040 RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
2041 /* Print the flavor of the destructor if in verbose mode. */
2042 flavor = next_char (dm) - '0';
2043 if (flag_verbose)
2044 {
2045 RETURN_IF_ERROR (result_add (dm, " ["));
2046 RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor]));
2047 RETURN_IF_ERROR (result_add_char (dm, ']'));
2048 }
2049 }
2050 else
2051 return STATUS_ERROR;
2052
2053 return STATUS_OK;
2054 }
2055
2056 /* Handle pointer, reference, and pointer-to-member cases for
2057 demangle_type. All consecutive `P's, `R's, and 'M's are joined to
2058 build a pointer/reference type. We snarf all these, plus the
2059 following <type>, all at once since we need to know whether we have
2060 a pointer to data or pointer to function to construct the right
2061 output syntax. C++'s pointer syntax is hairy.
2062
2063 This function adds substitution candidates for every nested
2064 pointer/reference type it processes, including the outermost, final
2065 type, assuming the substitution starts at SUBSTITUTION_START in the
2066 demangling result. For example, if this function demangles
2067 `PP3Foo', it will add a substitution for `Foo', `Foo*', and
2068 `Foo**', in that order.
2069
2070 *INSERT_POS is a quantity used internally, when this function calls
2071 itself recursively, to figure out where to insert pointer
2072 punctuation on the way up. On entry to this function, INSERT_POS
2073 should point to a temporary value, but that value need not be
2074 initialized.
2075
2076 <type> ::= P <type>
2077 ::= R <type>
2078 ::= <pointer-to-member-type>
2079
2080 <pointer-to-member-type> ::= M </class/ type> </member/ type> */
2081
2082 static status_t
2083 demangle_type_ptr (dm, insert_pos, substitution_start)
2084 demangling_t dm;
2085 int *insert_pos;
2086 int substitution_start;
2087 {
2088 status_t status;
2089 int is_substitution_candidate = 1;
2090
2091 DEMANGLE_TRACE ("type*", dm);
2092
2093 /* Scan forward, collecting pointers and references into symbols,
2094 until we hit something else. Then emit the type. */
2095 switch (peek_char (dm))
2096 {
2097 case 'P':
2098 /* A pointer. Snarf the `P'. */
2099 advance_char (dm);
2100 /* Demangle the underlying type. */
2101 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2102 substitution_start));
2103 /* Insert an asterisk where we're told to; it doesn't
2104 necessarily go at the end. If we're doing Java style output,
2105 there is no pointer symbol. */
2106 if (dm->style != DMGL_JAVA)
2107 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
2108 /* The next (outermost) pointer or reference character should go
2109 after this one. */
2110 ++(*insert_pos);
2111 break;
2112
2113 case 'R':
2114 /* A reference. Snarf the `R'. */
2115 advance_char (dm);
2116 /* Demangle the underlying type. */
2117 RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
2118 substitution_start));
2119 /* Insert an ampersand where we're told to; it doesn't
2120 necessarily go at the end. */
2121 RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
2122 /* The next (outermost) pointer or reference character should go
2123 after this one. */
2124 ++(*insert_pos);
2125 break;
2126
2127 case 'M':
2128 {
2129 /* A pointer-to-member. */
2130 dyn_string_t class_type;
2131
2132 /* Eat the 'M'. */
2133 advance_char (dm);
2134
2135 /* Capture the type of which this is a pointer-to-member. */
2136 RETURN_IF_ERROR (result_push (dm));
2137 RETURN_IF_ERROR (demangle_type (dm));
2138 class_type = (dyn_string_t) result_pop (dm);
2139
2140 if (peek_char (dm) == 'F')
2141 /* A pointer-to-member function. We want output along the
2142 lines of `void (C::*) (int, int)'. Demangle the function
2143 type, which would in this case give `void () (int, int)'
2144 and set *insert_pos to the spot between the first
2145 parentheses. */
2146 status = demangle_type_ptr (dm, insert_pos, substitution_start);
2147 else if (peek_char (dm) == 'A')
2148 /* A pointer-to-member array variable. We want output that
2149 looks like `int (Klass::*) [10]'. Demangle the array type
2150 as `int () [10]', and set *insert_pos to the spot between
2151 the parentheses. */
2152 status = demangle_array_type (dm, insert_pos);
2153 else
2154 {
2155 /* A pointer-to-member variable. Demangle the type of the
2156 pointed-to member. */
2157 status = demangle_type (dm);
2158 /* Make it pretty. */
2159 if (STATUS_NO_ERROR (status)
2160 && !result_previous_char_is_space (dm))
2161 status = result_add_char (dm, ' ');
2162 /* The pointer-to-member notation (e.g. `C::*') follows the
2163 member's type. */
2164 *insert_pos = result_caret_pos (dm);
2165 }
2166
2167 /* Build the pointer-to-member notation. */
2168 if (STATUS_NO_ERROR (status))
2169 status = result_insert (dm, *insert_pos, "::*");
2170 if (STATUS_NO_ERROR (status))
2171 status = result_insert_string (dm, *insert_pos, class_type);
2172 /* There may be additional levels of (pointer or reference)
2173 indirection in this type. If so, the `*' and `&' should be
2174 added after the pointer-to-member notation (e.g. `C::*&' for
2175 a reference to a pointer-to-member of class C). */
2176 *insert_pos += dyn_string_length (class_type) + 3;
2177
2178 /* Clean up. */
2179 dyn_string_delete (class_type);
2180
2181 RETURN_IF_ERROR (status);
2182 }
2183 break;
2184
2185 case 'F':
2186 /* Ooh, tricky, a pointer-to-function. When we demangle the
2187 function type, the return type should go at the very
2188 beginning. */
2189 *insert_pos = result_caret_pos (dm);
2190 /* The parentheses indicate this is a function pointer or
2191 reference type. */
2192 RETURN_IF_ERROR (result_add (dm, "()"));
2193 /* Now demangle the function type. The return type will be
2194 inserted before the `()', and the argument list will go after
2195 it. */
2196 RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
2197 /* We should now have something along the lines of
2198 `void () (int, int)'. The pointer or reference characters
2199 have to inside the first set of parentheses. *insert_pos has
2200 already been updated to point past the end of the return
2201 type. Move it one character over so it points inside the
2202 `()'. */
2203 ++(*insert_pos);
2204 break;
2205
2206 case 'A':
2207 /* An array pointer or reference. demangle_array_type will figure
2208 out where the asterisks and ampersands go. */
2209 RETURN_IF_ERROR (demangle_array_type (dm, insert_pos));
2210 break;
2211
2212 default:
2213 /* No more pointer or reference tokens; this is therefore a
2214 pointer to data. Finish up by demangling the underlying
2215 type. */
2216 RETURN_IF_ERROR (demangle_type (dm));
2217 /* The pointer or reference characters follow the underlying
2218 type, as in `int*&'. */
2219 *insert_pos = result_caret_pos (dm);
2220 /* Because of the production <type> ::= <substitution>,
2221 demangle_type will already have added the underlying type as
2222 a substitution candidate. Don't do it again. */
2223 is_substitution_candidate = 0;
2224 break;
2225 }
2226
2227 if (is_substitution_candidate)
2228 RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
2229
2230 return STATUS_OK;
2231 }
2232
2233 /* Demangles and emits a <type>.
2234
2235 <type> ::= <builtin-type>
2236 ::= <function-type>
2237 ::= <class-enum-type>
2238 ::= <array-type>
2239 ::= <pointer-to-member-type>
2240 ::= <template-param>
2241 ::= <template-template-param> <template-args>
2242 ::= <CV-qualifiers> <type>
2243 ::= P <type> # pointer-to
2244 ::= R <type> # reference-to
2245 ::= C <type> # complex pair (C 2000)
2246 ::= G <type> # imaginary (C 2000)
2247 ::= U <source-name> <type> # vendor extended type qualifier
2248 ::= <substitution> */
2249
2250 static status_t
2251 demangle_type (dm)
2252 demangling_t dm;
2253 {
2254 int start = substitution_start (dm);
2255 char peek = peek_char (dm);
2256 char peek_next;
2257 int encode_return_type = 0;
2258 template_arg_list_t old_arg_list = current_template_arg_list (dm);
2259 int insert_pos;
2260
2261 /* A <type> can be a <substitution>; therefore, this <type> is a
2262 substitution candidate unless a special condition holds (see
2263 below). */
2264 int is_substitution_candidate = 1;
2265
2266 DEMANGLE_TRACE ("type", dm);
2267
2268 /* A <class-enum-type> can start with a digit (a <source-name>), an
2269 N (a <nested-name>), or a Z (a <local-name>). */
2270 if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
2271 RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type));
2272 /* Lower-case letters begin <builtin-type>s, except for `r', which
2273 denotes restrict. */
2274 else if (peek >= 'a' && peek <= 'z' && peek != 'r')
2275 {
2276 RETURN_IF_ERROR (demangle_builtin_type (dm));
2277 /* Built-in types are not substitution candidates. */
2278 is_substitution_candidate = 0;
2279 }
2280 else
2281 switch (peek)
2282 {
2283 case 'r':
2284 case 'V':
2285 case 'K':
2286 /* CV-qualifiers (including restrict). We have to demangle
2287 them off to the side, since C++ syntax puts them in a funny
2288 place for qualified pointer and reference types. */
2289 {
2290 status_t status;
2291 dyn_string_t cv_qualifiers = dyn_string_new (24);
2292 int old_caret_position = result_get_caret (dm);
2293
2294 if (cv_qualifiers == NULL)
2295 return STATUS_ALLOCATION_FAILED;
2296
2297 /* Decode all adjacent CV qualifiers. */
2298 demangle_CV_qualifiers (dm, cv_qualifiers);
2299 /* Emit them, and shift the caret left so that the
2300 underlying type will be emitted before the qualifiers. */
2301 status = result_add_string (dm, cv_qualifiers);
2302 result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
2303 /* Clean up. */
2304 dyn_string_delete (cv_qualifiers);
2305 RETURN_IF_ERROR (status);
2306 /* Also prepend a blank, if needed. */
2307 RETURN_IF_ERROR (result_add_char (dm, ' '));
2308 result_shift_caret (dm, -1);
2309
2310 /* Demangle the underlying type. It will be emitted before
2311 the CV qualifiers, since we moved the caret. */
2312 RETURN_IF_ERROR (demangle_type (dm));
2313
2314 /* Put the caret back where it was previously. */
2315 result_set_caret (dm, old_caret_position);
2316 }
2317 break;
2318
2319 case 'F':
2320 return "Non-pointer or -reference function type.";
2321
2322 case 'A':
2323 RETURN_IF_ERROR (demangle_array_type (dm, NULL));
2324 break;
2325
2326 case 'T':
2327 /* It's either a <template-param> or a
2328 <template-template-param>. In either case, demangle the
2329 `T' token first. */
2330 RETURN_IF_ERROR (demangle_template_param (dm));
2331
2332 /* Check for a template argument list; if one is found, it's a
2333 <template-template-param> ::= <template-param>
2334 ::= <substitution> */
2335 if (peek_char (dm) == 'I')
2336 {
2337 /* Add a substitution candidate. The template parameter
2338 `T' token is a substitution candidate by itself,
2339 without the template argument list. */
2340 RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2341
2342 /* Now demangle the template argument list. */
2343 RETURN_IF_ERROR (demangle_template_args (dm));
2344 /* The entire type, including the template template
2345 parameter and its argument list, will be added as a
2346 substitution candidate below. */
2347 }
2348
2349 break;
2350
2351 case 'S':
2352 /* First check if this is a special substitution. If it is,
2353 this is a <class-enum-type>. Special substitutions have a
2354 letter following the `S'; other substitutions have a digit
2355 or underscore. */
2356 peek_next = peek_char_next (dm);
2357 if (IS_DIGIT (peek_next) || peek_next == '_')
2358 {
2359 RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type));
2360
2361 /* The substituted name may have been a template name.
2362 Check if template arguments follow, and if so, demangle
2363 them. */
2364 if (peek_char (dm) == 'I')
2365 RETURN_IF_ERROR (demangle_template_args (dm));
2366 else
2367 /* A substitution token is not itself a substitution
2368 candidate. (However, if the substituted template is
2369 instantiated, the resulting type is.) */
2370 is_substitution_candidate = 0;
2371 }
2372 else
2373 {
2374 /* Now some trickiness. We have a special substitution
2375 here. Often, the special substitution provides the
2376 name of a template that's subsequently instantiated,
2377 for instance `SaIcE' => std::allocator<char>. In these
2378 cases we need to add a substitution candidate for the
2379 entire <class-enum-type> and thus don't want to clear
2380 the is_substitution_candidate flag.
2381
2382 However, it's possible that what we have here is a
2383 substitution token representing an entire type, such as
2384 `Ss' => std::string. In this case, we mustn't add a
2385 new substitution candidate for this substitution token.
2386 To detect this case, remember where the start of the
2387 substitution token is. */
2388 const char *next = dm->next;
2389 /* Now demangle the <class-enum-type>. */
2390 RETURN_IF_ERROR
2391 (demangle_class_enum_type (dm, &encode_return_type));
2392 /* If all that was just demangled is the two-character
2393 special substitution token, supress the addition of a
2394 new candidate for it. */
2395 if (dm->next == next + 2)
2396 is_substitution_candidate = 0;
2397 }
2398
2399 break;
2400
2401 case 'P':
2402 case 'R':
2403 case 'M':
2404 RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
2405 /* demangle_type_ptr adds all applicable substitution
2406 candidates. */
2407 is_substitution_candidate = 0;
2408 break;
2409
2410 case 'C':
2411 /* A C99 complex type. */
2412 RETURN_IF_ERROR (result_add (dm, "complex "));
2413 advance_char (dm);
2414 RETURN_IF_ERROR (demangle_type (dm));
2415 break;
2416
2417 case 'G':
2418 /* A C99 imaginary type. */
2419 RETURN_IF_ERROR (result_add (dm, "imaginary "));
2420 advance_char (dm);
2421 RETURN_IF_ERROR (demangle_type (dm));
2422 break;
2423
2424 case 'U':
2425 /* Vendor-extended type qualifier. */
2426 advance_char (dm);
2427 RETURN_IF_ERROR (demangle_source_name (dm));
2428 RETURN_IF_ERROR (result_add_char (dm, ' '));
2429 RETURN_IF_ERROR (demangle_type (dm));
2430 break;
2431
2432 default:
2433 return "Unexpected character in <type>.";
2434 }
2435
2436 if (is_substitution_candidate)
2437 /* Add a new substitution for the type. If this type was a
2438 <template-param>, pass its index since from the point of
2439 substitutions; a <template-param> token is a substitution
2440 candidate distinct from the type that is substituted for it. */
2441 RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
2442
2443 /* Pop off template argument lists added during mangling of this
2444 type. */
2445 pop_to_template_arg_list (dm, old_arg_list);
2446
2447 return STATUS_OK;
2448 }
2449
2450 /* C++ source names of builtin types, indexed by the mangled code
2451 letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
2452 static const char *const builtin_type_names[26] =
2453 {
2454 "signed char", /* a */
2455 "bool", /* b */
2456 "char", /* c */
2457 "double", /* d */
2458 "long double", /* e */
2459 "float", /* f */
2460 "__float128", /* g */
2461 "unsigned char", /* h */
2462 "int", /* i */
2463 "unsigned", /* j */
2464 NULL, /* k */
2465 "long", /* l */
2466 "unsigned long", /* m */
2467 "__int128", /* n */
2468 "unsigned __int128", /* o */
2469 NULL, /* p */
2470 NULL, /* q */
2471 NULL, /* r */
2472 "short", /* s */
2473 "unsigned short", /* t */
2474 NULL, /* u */
2475 "void", /* v */
2476 "wchar_t", /* w */
2477 "long long", /* x */
2478 "unsigned long long", /* y */
2479 "..." /* z */
2480 };
2481
2482 /* Java source names of builtin types. Types that arn't valid in Java
2483 are also included here - we don't fail if someone attempts to demangle a
2484 C++ symbol in Java style. */
2485 static const char *const java_builtin_type_names[26] =
2486 {
2487 "signed char", /* a */
2488 "boolean", /* C++ "bool" */ /* b */
2489 "byte", /* C++ "char" */ /* c */
2490 "double", /* d */
2491 "long double", /* e */
2492 "float", /* f */
2493 "__float128", /* g */
2494 "unsigned char", /* h */
2495 "int", /* i */
2496 "unsigned", /* j */
2497 NULL, /* k */
2498 "long", /* l */
2499 "unsigned long", /* m */
2500 "__int128", /* n */
2501 "unsigned __int128", /* o */
2502 NULL, /* p */
2503 NULL, /* q */
2504 NULL, /* r */
2505 "short", /* s */
2506 "unsigned short", /* t */
2507 NULL, /* u */
2508 "void", /* v */
2509 "char", /* C++ "wchar_t" */ /* w */
2510 "long", /* C++ "long long" */ /* x */
2511 "unsigned long long", /* y */
2512 "..." /* z */
2513 };
2514
2515 /* Demangles and emits a <builtin-type>.
2516
2517 <builtin-type> ::= v # void
2518 ::= w # wchar_t
2519 ::= b # bool
2520 ::= c # char
2521 ::= a # signed char
2522 ::= h # unsigned char
2523 ::= s # short
2524 ::= t # unsigned short
2525 ::= i # int
2526 ::= j # unsigned int
2527 ::= l # long
2528 ::= m # unsigned long
2529 ::= x # long long, __int64
2530 ::= y # unsigned long long, __int64
2531 ::= n # __int128
2532 ::= o # unsigned __int128
2533 ::= f # float
2534 ::= d # double
2535 ::= e # long double, __float80
2536 ::= g # __float128
2537 ::= z # ellipsis
2538 ::= u <source-name> # vendor extended type */
2539
2540 static status_t
2541 demangle_builtin_type (dm)
2542 demangling_t dm;
2543 {
2544
2545 char code = peek_char (dm);
2546
2547 DEMANGLE_TRACE ("builtin-type", dm);
2548
2549 if (code == 'u')
2550 {
2551 advance_char (dm);
2552 RETURN_IF_ERROR (demangle_source_name (dm));
2553 return STATUS_OK;
2554 }
2555 else if (code >= 'a' && code <= 'z')
2556 {
2557 const char *type_name;
2558 /* Java uses different names for some built-in types. */
2559 if (dm->style == DMGL_JAVA)
2560 type_name = java_builtin_type_names[code - 'a'];
2561 else
2562 type_name = builtin_type_names[code - 'a'];
2563 if (type_name == NULL)
2564 return "Unrecognized <builtin-type> code.";
2565
2566 RETURN_IF_ERROR (result_add (dm, type_name));
2567 advance_char (dm);
2568 return STATUS_OK;
2569 }
2570 else
2571 return "Non-alphabetic <builtin-type> code.";
2572 }
2573
2574 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2575 restrict) at the current position. The qualifiers are appended to
2576 QUALIFIERS. Returns STATUS_OK. */
2577
2578 static status_t
2579 demangle_CV_qualifiers (dm, qualifiers)
2580 demangling_t dm;
2581 dyn_string_t qualifiers;
2582 {
2583 DEMANGLE_TRACE ("CV-qualifiers", dm);
2584
2585 while (1)
2586 {
2587 switch (peek_char (dm))
2588 {
2589 case 'r':
2590 if (!dyn_string_append_space (qualifiers))
2591 return STATUS_ALLOCATION_FAILED;
2592 if (!dyn_string_append_cstr (qualifiers, "restrict"))
2593 return STATUS_ALLOCATION_FAILED;
2594 break;
2595
2596 case 'V':
2597 if (!dyn_string_append_space (qualifiers))
2598 return STATUS_ALLOCATION_FAILED;
2599 if (!dyn_string_append_cstr (qualifiers, "volatile"))
2600 return STATUS_ALLOCATION_FAILED;
2601 break;
2602
2603 case 'K':
2604 if (!dyn_string_append_space (qualifiers))
2605 return STATUS_ALLOCATION_FAILED;
2606 if (!dyn_string_append_cstr (qualifiers, "const"))
2607 return STATUS_ALLOCATION_FAILED;
2608 break;
2609
2610 default:
2611 return STATUS_OK;
2612 }
2613
2614 advance_char (dm);
2615 }
2616 }
2617
2618 /* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
2619 position in the result string of the start of the function
2620 identifier, at which the function's return type will be inserted;
2621 *FUNCTION_NAME_POS is updated to position past the end of the
2622 function's return type.
2623
2624 <function-type> ::= F [Y] <bare-function-type> E */
2625
2626 static status_t
2627 demangle_function_type (dm, function_name_pos)
2628 demangling_t dm;
2629 int *function_name_pos;
2630 {
2631 DEMANGLE_TRACE ("function-type", dm);
2632 RETURN_IF_ERROR (demangle_char (dm, 'F'));
2633 if (peek_char (dm) == 'Y')
2634 {
2635 /* Indicate this function has C linkage if in verbose mode. */
2636 if (flag_verbose)
2637 RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
2638 advance_char (dm);
2639 }
2640 RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2641 RETURN_IF_ERROR (demangle_char (dm, 'E'));
2642 return STATUS_OK;
2643 }
2644
2645 /* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
2646 position in the result string at which the function return type
2647 should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2648 function's return type is assumed not to be encoded.
2649
2650 <bare-function-type> ::= <signature type>+ */
2651
2652 static status_t
2653 demangle_bare_function_type (dm, return_type_pos)
2654 demangling_t dm;
2655 int *return_type_pos;
2656 {
2657 /* Sequence is the index of the current function parameter, counting
2658 from zero. The value -1 denotes the return type. */
2659 int sequence =
2660 (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2661
2662 DEMANGLE_TRACE ("bare-function-type", dm);
2663
2664 RETURN_IF_ERROR (result_add_char (dm, '('));
2665 while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2666 {
2667 if (sequence == -1)
2668 /* We're decoding the function's return type. */
2669 {
2670 dyn_string_t return_type;
2671 status_t status = STATUS_OK;
2672
2673 /* Decode the return type off to the side. */
2674 RETURN_IF_ERROR (result_push (dm));
2675 RETURN_IF_ERROR (demangle_type (dm));
2676 return_type = (dyn_string_t) result_pop (dm);
2677
2678 /* Add a space to the end of the type. Insert the return
2679 type where we've been asked to. */
2680 if (!dyn_string_append_space (return_type))
2681 status = STATUS_ALLOCATION_FAILED;
2682 if (STATUS_NO_ERROR (status))
2683 {
2684 if (!dyn_string_insert (result_string (dm), *return_type_pos,
2685 return_type))
2686 status = STATUS_ALLOCATION_FAILED;
2687 else
2688 *return_type_pos += dyn_string_length (return_type);
2689 }
2690
2691 dyn_string_delete (return_type);
2692 RETURN_IF_ERROR (status);
2693 }
2694 else
2695 {
2696 /* Skip `void' parameter types. One should only occur as
2697 the only type in a parameter list; in that case, we want
2698 to print `foo ()' instead of `foo (void)'. */
2699 if (peek_char (dm) == 'v')
2700 /* Consume the v. */
2701 advance_char (dm);
2702 else
2703 {
2704 /* Separate parameter types by commas. */
2705 if (sequence > 0)
2706 RETURN_IF_ERROR (result_add (dm, ", "));
2707 /* Demangle the type. */
2708 RETURN_IF_ERROR (demangle_type (dm));
2709 }
2710 }
2711
2712 ++sequence;
2713 }
2714 RETURN_IF_ERROR (result_add_char (dm, ')'));
2715
2716 /* We should have demangled at least one parameter type (which would
2717 be void, for a function that takes no parameters), plus the
2718 return type, if we were supposed to demangle that. */
2719 if (sequence == -1)
2720 return "Missing function return type.";
2721 else if (sequence == 0)
2722 return "Missing function parameter.";
2723
2724 return STATUS_OK;
2725 }
2726
2727 /* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
2728 non-zero if the type is a template-id, zero otherwise.
2729
2730 <class-enum-type> ::= <name> */
2731
2732 static status_t
2733 demangle_class_enum_type (dm, encode_return_type)
2734 demangling_t dm;
2735 int *encode_return_type;
2736 {
2737 DEMANGLE_TRACE ("class-enum-type", dm);
2738
2739 RETURN_IF_ERROR (demangle_name (dm, encode_return_type));
2740 return STATUS_OK;
2741 }
2742
2743 /* Demangles and emits an <array-type>.
2744
2745 If PTR_INSERT_POS is not NULL, the array type is formatted as a
2746 pointer or reference to an array, except that asterisk and
2747 ampersand punctuation is omitted (since it's not know at this
2748 point). *PTR_INSERT_POS is set to the position in the demangled
2749 name at which this punctuation should be inserted. For example,
2750 `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
2751 between the parentheses.
2752
2753 If PTR_INSERT_POS is NULL, the array type is assumed not to be
2754 pointer- or reference-qualified. Then, for example, `A10_i' is
2755 demangled simply as `int[10]'.
2756
2757 <array-type> ::= A [<dimension number>] _ <element type>
2758 ::= A <dimension expression> _ <element type> */
2759
2760 static status_t
2761 demangle_array_type (dm, ptr_insert_pos)
2762 demangling_t dm;
2763 int *ptr_insert_pos;
2764 {
2765 status_t status = STATUS_OK;
2766 dyn_string_t array_size = NULL;
2767 char peek;
2768
2769 DEMANGLE_TRACE ("array-type", dm);
2770
2771 RETURN_IF_ERROR (demangle_char (dm, 'A'));
2772
2773 /* Demangle the array size into array_size. */
2774 peek = peek_char (dm);
2775 if (peek == '_')
2776 /* Array bound is omitted. This is a C99-style VLA. */
2777 ;
2778 else if (IS_DIGIT (peek_char (dm)))
2779 {
2780 /* It looks like a constant array bound. */
2781 array_size = dyn_string_new (10);
2782 if (array_size == NULL)
2783 return STATUS_ALLOCATION_FAILED;
2784 status = demangle_number_literally (dm, array_size, 10, 0);
2785 }
2786 else
2787 {
2788 /* Anything is must be an expression for a nont-constant array
2789 bound. This happens if the array type occurs in a template
2790 and the array bound references a template parameter. */
2791 RETURN_IF_ERROR (result_push (dm));
2792 RETURN_IF_ERROR (demangle_expression (dm));
2793 array_size = (dyn_string_t) result_pop (dm);
2794 }
2795 /* array_size may have been allocated by now, so we can't use
2796 RETURN_IF_ERROR until it's been deallocated. */
2797
2798 /* Demangle the base type of the array. */
2799 if (STATUS_NO_ERROR (status))
2800 status = demangle_char (dm, '_');
2801 if (STATUS_NO_ERROR (status))
2802 status = demangle_type (dm);
2803
2804 if (ptr_insert_pos != NULL)
2805 {
2806 /* This array is actually part of an pointer- or
2807 reference-to-array type. Format appropriately, except we
2808 don't know which and how much punctuation to use. */
2809 if (STATUS_NO_ERROR (status))
2810 status = result_add (dm, " () ");
2811 /* Let the caller know where to insert the punctuation. */
2812 *ptr_insert_pos = result_caret_pos (dm) - 2;
2813 }
2814
2815 /* Emit the array dimension syntax. */
2816 if (STATUS_NO_ERROR (status))
2817 status = result_add_char (dm, '[');
2818 if (STATUS_NO_ERROR (status) && array_size != NULL)
2819 status = result_add_string (dm, array_size);
2820 if (STATUS_NO_ERROR (status))
2821 status = result_add_char (dm, ']');
2822 if (array_size != NULL)
2823 dyn_string_delete (array_size);
2824
2825 RETURN_IF_ERROR (status);
2826
2827 return STATUS_OK;
2828 }
2829
2830 /* Demangles and emits a <template-param>.
2831
2832 <template-param> ::= T_ # first template parameter
2833 ::= T <parameter-2 number> _ */
2834
2835 static status_t
2836 demangle_template_param (dm)
2837 demangling_t dm;
2838 {
2839 int parm_number;
2840 template_arg_list_t current_arg_list = current_template_arg_list (dm);
2841 string_list_t arg;
2842
2843 DEMANGLE_TRACE ("template-param", dm);
2844
2845 /* Make sure there is a template argmust list in which to look up
2846 this parameter reference. */
2847 if (current_arg_list == NULL)
2848 return "Template parameter outside of template.";
2849
2850 RETURN_IF_ERROR (demangle_char (dm, 'T'));
2851 if (peek_char (dm) == '_')
2852 parm_number = 0;
2853 else
2854 {
2855 RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2856 ++parm_number;
2857 }
2858 RETURN_IF_ERROR (demangle_char (dm, '_'));
2859
2860 arg = template_arg_list_get_arg (current_arg_list, parm_number);
2861 if (arg == NULL)
2862 /* parm_number exceeded the number of arguments in the current
2863 template argument list. */
2864 return "Template parameter number out of bounds.";
2865 RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
2866
2867 return STATUS_OK;
2868 }
2869
2870 /* Demangles and emits a <template-args>.
2871
2872 <template-args> ::= I <template-arg>+ E */
2873
2874 static status_t
2875 demangle_template_args (dm)
2876 demangling_t dm;
2877 {
2878 int first = 1;
2879 dyn_string_t old_last_source_name;
2880 template_arg_list_t arg_list = template_arg_list_new ();
2881
2882 if (arg_list == NULL)
2883 return STATUS_ALLOCATION_FAILED;
2884
2885 /* Preserve the most recently demangled source name. */
2886 old_last_source_name = dm->last_source_name;
2887 dm->last_source_name = dyn_string_new (0);
2888
2889 DEMANGLE_TRACE ("template-args", dm);
2890
2891 if (dm->last_source_name == NULL)
2892 return STATUS_ALLOCATION_FAILED;
2893
2894 RETURN_IF_ERROR (demangle_char (dm, 'I'));
2895 RETURN_IF_ERROR (result_open_template_list (dm));
2896 do
2897 {
2898 string_list_t arg;
2899
2900 if (first)
2901 first = 0;
2902 else
2903 RETURN_IF_ERROR (result_add (dm, ", "));
2904
2905 /* Capture the template arg. */
2906 RETURN_IF_ERROR (result_push (dm));
2907 RETURN_IF_ERROR (demangle_template_arg (dm));
2908 arg = result_pop (dm);
2909
2910 /* Emit it in the demangled name. */
2911 RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
2912
2913 /* Save it for use in expanding <template-param>s. */
2914 template_arg_list_add_arg (arg_list, arg);
2915 }
2916 while (peek_char (dm) != 'E');
2917 /* Append the '>'. */
2918 RETURN_IF_ERROR (result_close_template_list (dm));
2919
2920 /* Consume the 'E'. */
2921 advance_char (dm);
2922
2923 /* Restore the most recent demangled source name. */
2924 dyn_string_delete (dm->last_source_name);
2925 dm->last_source_name = old_last_source_name;
2926
2927 /* Push the list onto the top of the stack of template argument
2928 lists, so that arguments from it are used from now on when
2929 expanding <template-param>s. */
2930 push_template_arg_list (dm, arg_list);
2931
2932 return STATUS_OK;
2933 }
2934
2935 /* This function, which does not correspond to a production in the
2936 mangling spec, handles the `literal' production for both
2937 <template-arg> and <expr-primary>. It does not expect or consume
2938 the initial `L' or final `E'. The demangling is given by:
2939
2940 <literal> ::= <type> </value/ number>
2941
2942 and the emitted output is `(type)number'. */
2943
2944 static status_t
2945 demangle_literal (dm)
2946 demangling_t dm;
2947 {
2948 char peek = peek_char (dm);
2949 dyn_string_t value_string;
2950 status_t status;
2951
2952 DEMANGLE_TRACE ("literal", dm);
2953
2954 if (!flag_verbose && peek >= 'a' && peek <= 'z')
2955 {
2956 /* If not in verbose mode and this is a builtin type, see if we
2957 can produce simpler numerical output. In particular, for
2958 integer types shorter than `long', just write the number
2959 without type information; for bools, write `true' or `false'.
2960 Other refinements could be made here too. */
2961
2962 /* This constant string is used to map from <builtin-type> codes
2963 (26 letters of the alphabet) to codes that determine how the
2964 value will be displayed. The codes are:
2965 b: display as bool
2966 i: display as int
2967 l: display as long
2968 A space means the value will be represented using cast
2969 notation. */
2970 static const char *const code_map = "ibi iii ll ii i ";
2971
2972 char code = code_map[peek - 'a'];
2973 /* FIXME: Implement demangling of floats and doubles. */
2974 if (code == 'u')
2975 return STATUS_UNIMPLEMENTED;
2976 if (code == 'b')
2977 {
2978 /* It's a boolean. */
2979 char value;
2980
2981 /* Consume the b. */
2982 advance_char (dm);
2983 /* Look at the next character. It should be 0 or 1,
2984 corresponding to false or true, respectively. */
2985 value = peek_char (dm);
2986 if (value == '0')
2987 RETURN_IF_ERROR (result_add (dm, "false"));
2988 else if (value == '1')
2989 RETURN_IF_ERROR (result_add (dm, "true"));
2990 else
2991 return "Unrecognized bool constant.";
2992 /* Consume the 0 or 1. */
2993 advance_char (dm);
2994 return STATUS_OK;
2995 }
2996 else if (code == 'i' || code == 'l')
2997 {
2998 /* It's an integer or long. */
2999
3000 /* Consume the type character. */
3001 advance_char (dm);
3002
3003 /* Demangle the number and write it out. */
3004 value_string = dyn_string_new (0);
3005 status = demangle_number_literally (dm, value_string, 10, 1);
3006 if (STATUS_NO_ERROR (status))
3007 status = result_add_string (dm, value_string);
3008 /* For long integers, append an l. */
3009 if (code == 'l' && STATUS_NO_ERROR (status))
3010 status = result_add_char (dm, code);
3011 dyn_string_delete (value_string);
3012
3013 RETURN_IF_ERROR (status);
3014 return STATUS_OK;
3015 }
3016 /* ...else code == ' ', so fall through to represent this
3017 literal's type explicitly using cast syntax. */
3018 }
3019
3020 RETURN_IF_ERROR (result_add_char (dm, '('));
3021 RETURN_IF_ERROR (demangle_type (dm));
3022 RETURN_IF_ERROR (result_add_char (dm, ')'));
3023
3024 value_string = dyn_string_new (0);
3025 if (value_string == NULL)
3026 return STATUS_ALLOCATION_FAILED;
3027
3028 status = demangle_number_literally (dm, value_string, 10, 1);
3029 if (STATUS_NO_ERROR (status))
3030 status = result_add_string (dm, value_string);
3031 dyn_string_delete (value_string);
3032 RETURN_IF_ERROR (status);
3033
3034 return STATUS_OK;
3035 }
3036
3037 /* Demangles and emits a <template-arg>.
3038
3039 <template-arg> ::= <type> # type
3040 ::= L <type> <value number> E # literal
3041 ::= LZ <encoding> E # external name
3042 ::= X <expression> E # expression */
3043
3044 static status_t
3045 demangle_template_arg (dm)
3046 demangling_t dm;
3047 {
3048 DEMANGLE_TRACE ("template-arg", dm);
3049
3050 switch (peek_char (dm))
3051 {
3052 case 'L':
3053 advance_char (dm);
3054
3055 if (peek_char (dm) == 'Z')
3056 {
3057 /* External name. */
3058 advance_char (dm);
3059 /* FIXME: Standard is contradictory here. */
3060 RETURN_IF_ERROR (demangle_encoding (dm));
3061 }
3062 else
3063 RETURN_IF_ERROR (demangle_literal (dm));
3064 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3065 break;
3066
3067 case 'X':
3068 /* Expression. */
3069 advance_char (dm);
3070 RETURN_IF_ERROR (demangle_expression (dm));
3071 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3072 break;
3073
3074 default:
3075 RETURN_IF_ERROR (demangle_type (dm));
3076 break;
3077 }
3078
3079 return STATUS_OK;
3080 }
3081
3082 /* Demangles and emits an <expression>.
3083
3084 <expression> ::= <unary operator-name> <expression>
3085 ::= <binary operator-name> <expression> <expression>
3086 ::= <expr-primary>
3087 ::= <scope-expression> */
3088
3089 static status_t
3090 demangle_expression (dm)
3091 demangling_t dm;
3092 {
3093 char peek = peek_char (dm);
3094
3095 DEMANGLE_TRACE ("expression", dm);
3096
3097 if (peek == 'L' || peek == 'T')
3098 RETURN_IF_ERROR (demangle_expr_primary (dm));
3099 else if (peek == 's' && peek_char_next (dm) == 'r')
3100 RETURN_IF_ERROR (demangle_scope_expression (dm));
3101 else
3102 /* An operator expression. */
3103 {
3104 int num_args;
3105 status_t status = STATUS_OK;
3106 dyn_string_t operator_name;
3107
3108 /* We have an operator name. Since we want to output binary
3109 operations in infix notation, capture the operator name
3110 first. */
3111 RETURN_IF_ERROR (result_push (dm));
3112 RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
3113 operator_name = (dyn_string_t) result_pop (dm);
3114
3115 /* If it's binary, do an operand first. */
3116 if (num_args > 1)
3117 {
3118 status = result_add_char (dm, '(');
3119 if (STATUS_NO_ERROR (status))
3120 status = demangle_expression (dm);
3121 if (STATUS_NO_ERROR (status))
3122 status = result_add_char (dm, ')');
3123 }
3124
3125 /* Emit the operator. */
3126 if (STATUS_NO_ERROR (status))
3127 status = result_add_string (dm, operator_name);
3128 dyn_string_delete (operator_name);
3129 RETURN_IF_ERROR (status);
3130
3131 /* Emit its second (if binary) or only (if unary) operand. */
3132 RETURN_IF_ERROR (result_add_char (dm, '('));
3133 RETURN_IF_ERROR (demangle_expression (dm));
3134 RETURN_IF_ERROR (result_add_char (dm, ')'));
3135
3136 /* The ternary operator takes a third operand. */
3137 if (num_args == 3)
3138 {
3139 RETURN_IF_ERROR (result_add (dm, ":("));
3140 RETURN_IF_ERROR (demangle_expression (dm));
3141 RETURN_IF_ERROR (result_add_char (dm, ')'));
3142 }
3143 }
3144
3145 return STATUS_OK;
3146 }
3147
3148 /* Demangles and emits a <scope-expression>.
3149
3150 <scope-expression> ::= sr <qualifying type> <source-name>
3151 ::= sr <qualifying type> <encoding> */
3152
3153 static status_t
3154 demangle_scope_expression (dm)
3155 demangling_t dm;
3156 {
3157 RETURN_IF_ERROR (demangle_char (dm, 's'));
3158 RETURN_IF_ERROR (demangle_char (dm, 'r'));
3159 RETURN_IF_ERROR (demangle_type (dm));
3160 RETURN_IF_ERROR (result_add (dm, "::"));
3161 RETURN_IF_ERROR (demangle_encoding (dm));
3162 return STATUS_OK;
3163 }
3164
3165 /* Demangles and emits an <expr-primary>.
3166
3167 <expr-primary> ::= <template-param>
3168 ::= L <type> <value number> E # literal
3169 ::= L <mangled-name> E # external name */
3170
3171 static status_t
3172 demangle_expr_primary (dm)
3173 demangling_t dm;
3174 {
3175 char peek = peek_char (dm);
3176
3177 DEMANGLE_TRACE ("expr-primary", dm);
3178
3179 if (peek == 'T')
3180 RETURN_IF_ERROR (demangle_template_param (dm));
3181 else if (peek == 'L')
3182 {
3183 /* Consume the `L'. */
3184 advance_char (dm);
3185 peek = peek_char (dm);
3186
3187 if (peek == '_')
3188 RETURN_IF_ERROR (demangle_mangled_name (dm));
3189 else
3190 RETURN_IF_ERROR (demangle_literal (dm));
3191
3192 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3193 }
3194 else
3195 return STATUS_ERROR;
3196
3197 return STATUS_OK;
3198 }
3199
3200 /* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
3201 if the substitution is the name of a template, zero otherwise.
3202
3203 <substitution> ::= S <seq-id> _
3204 ::= S_
3205
3206 ::= St # ::std::
3207 ::= Sa # ::std::allocator
3208 ::= Sb # ::std::basic_string
3209 ::= Ss # ::std::basic_string<char,
3210 ::std::char_traits<char>,
3211 ::std::allocator<char> >
3212 ::= Si # ::std::basic_istream<char,
3213 std::char_traits<char> >
3214 ::= So # ::std::basic_ostream<char,
3215 std::char_traits<char> >
3216 ::= Sd # ::std::basic_iostream<char,
3217 std::char_traits<char> >
3218 */
3219
3220 static status_t
3221 demangle_substitution (dm, template_p)
3222 demangling_t dm;
3223 int *template_p;
3224 {
3225 int seq_id;
3226 int peek;
3227 dyn_string_t text;
3228
3229 DEMANGLE_TRACE ("substitution", dm);
3230
3231 RETURN_IF_ERROR (demangle_char (dm, 'S'));
3232
3233 /* Scan the substitution sequence index. A missing number denotes
3234 the first index. */
3235 peek = peek_char (dm);
3236 if (peek == '_')
3237 seq_id = -1;
3238 /* If the following character is 0-9 or a capital letter, interpret
3239 the sequence up to the next underscore as a base-36 substitution
3240 index. */
3241 else if (IS_DIGIT ((unsigned char) peek)
3242 || (peek >= 'A' && peek <= 'Z'))
3243 RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
3244 else
3245 {
3246 const char *new_last_source_name = NULL;
3247
3248 switch (peek)
3249 {
3250 case 't':
3251 RETURN_IF_ERROR (result_add (dm, "std"));
3252 break;
3253
3254 case 'a':
3255 RETURN_IF_ERROR (result_add (dm, "std::allocator"));
3256 new_last_source_name = "allocator";
3257 *template_p = 1;
3258 break;
3259
3260 case 'b':
3261 RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
3262 new_last_source_name = "basic_string";
3263 *template_p = 1;
3264 break;
3265
3266 case 's':
3267 if (!flag_verbose)
3268 {
3269 RETURN_IF_ERROR (result_add (dm, "std::string"));
3270 new_last_source_name = "string";
3271 }
3272 else
3273 {
3274 RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
3275 new_last_source_name = "basic_string";
3276 }
3277 *template_p = 0;
3278 break;
3279
3280 case 'i':
3281 if (!flag_verbose)
3282 {
3283 RETURN_IF_ERROR (result_add (dm, "std::istream"));
3284 new_last_source_name = "istream";
3285 }
3286 else
3287 {
3288 RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traints<char> >"));
3289 new_last_source_name = "basic_istream";
3290 }
3291 *template_p = 0;
3292 break;
3293
3294 case 'o':
3295 if (!flag_verbose)
3296 {
3297 RETURN_IF_ERROR (result_add (dm, "std::ostream"));
3298 new_last_source_name = "ostream";
3299 }
3300 else
3301 {
3302 RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
3303 new_last_source_name = "basic_ostream";
3304 }
3305 *template_p = 0;
3306 break;
3307
3308 case 'd':
3309 if (!flag_verbose)
3310 {
3311 RETURN_IF_ERROR (result_add (dm, "std::iostream"));
3312 new_last_source_name = "iostream";
3313 }
3314 else
3315 {
3316 RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
3317 new_last_source_name = "basic_iostream";
3318 }
3319 *template_p = 0;
3320 break;
3321
3322 default:
3323 return "Unrecognized <substitution>.";
3324 }
3325
3326 /* Consume the character we just processed. */
3327 advance_char (dm);
3328
3329 if (new_last_source_name != NULL)
3330 {
3331 if (!dyn_string_copy_cstr (dm->last_source_name,
3332 new_last_source_name))
3333 return STATUS_ALLOCATION_FAILED;
3334 }
3335
3336 return STATUS_OK;
3337 }
3338
3339 /* Look up the substitution text. Since `S_' is the most recent
3340 substitution, `S0_' is the second-most-recent, etc., shift the
3341 numbering by one. */
3342 text = substitution_get (dm, seq_id + 1, template_p);
3343 if (text == NULL)
3344 return "Substitution number out of range.";
3345
3346 /* Emit the substitution text. */
3347 RETURN_IF_ERROR (result_add_string (dm, text));
3348
3349 RETURN_IF_ERROR (demangle_char (dm, '_'));
3350 return STATUS_OK;
3351 }
3352
3353 /* Demangles and emits a <local-name>.
3354
3355 <local-name> := Z <function encoding> E <entity name> [<discriminator>]
3356 := Z <function encoding> E s [<discriminator>] */
3357
3358 static status_t
3359 demangle_local_name (dm)
3360 demangling_t dm;
3361 {
3362 DEMANGLE_TRACE ("local-name", dm);
3363
3364 RETURN_IF_ERROR (demangle_char (dm, 'Z'));
3365 RETURN_IF_ERROR (demangle_encoding (dm));
3366 RETURN_IF_ERROR (demangle_char (dm, 'E'));
3367 RETURN_IF_ERROR (result_add (dm, "::"));
3368
3369 if (peek_char (dm) == 's')
3370 {
3371 /* Local character string literal. */
3372 RETURN_IF_ERROR (result_add (dm, "string literal"));
3373 /* Consume the s. */
3374 advance_char (dm);
3375 RETURN_IF_ERROR (demangle_discriminator (dm, 0));
3376 }
3377 else
3378 {
3379 int unused;
3380 /* Local name for some other entity. Demangle its name. */
3381 RETURN_IF_ERROR (demangle_name (dm, &unused));
3382 RETURN_IF_ERROR (demangle_discriminator (dm, 1));
3383 }
3384
3385 return STATUS_OK;
3386 }
3387
3388 /* Optimonally demangles and emits a <discriminator>. If there is no
3389 <discriminator> at the current position in the mangled string, the
3390 descriminator is assumed to be zero. Emit the discriminator number
3391 in parentheses, unless SUPPRESS_FIRST is non-zero and the
3392 discriminator is zero.
3393
3394 <discriminator> ::= _ <number> */
3395
3396 static status_t
3397 demangle_discriminator (dm, suppress_first)
3398 demangling_t dm;
3399 int suppress_first;
3400 {
3401 /* Output for <discriminator>s to the demangled name is completely
3402 suppressed if not in verbose mode. */
3403
3404 if (peek_char (dm) == '_')
3405 {
3406 /* Consume the underscore. */
3407 advance_char (dm);
3408 if (flag_verbose)
3409 RETURN_IF_ERROR (result_add (dm, " [#"));
3410 /* Check if there's a number following the underscore. */
3411 if (IS_DIGIT ((unsigned char) peek_char (dm)))
3412 {
3413 int discriminator;
3414 /* Demangle the number. */
3415 RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
3416 if (flag_verbose)
3417 /* Write the discriminator. The mangled number is two
3418 less than the discriminator ordinal, counting from
3419 zero. */
3420 RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2,
3421 (dyn_string_t) dm->result));
3422 }
3423 else
3424 {
3425 if (flag_verbose)
3426 /* A missing digit correspond to one. */
3427 RETURN_IF_ERROR (result_add_char (dm, '1'));
3428 }
3429 if (flag_verbose)
3430 RETURN_IF_ERROR (result_add_char (dm, ']'));
3431 }
3432 else if (!suppress_first)
3433 {
3434 if (flag_verbose)
3435 RETURN_IF_ERROR (result_add (dm, " [#0]"));
3436 }
3437
3438 return STATUS_OK;
3439 }
3440
3441 /* Demangle NAME into RESULT, which must be an initialized
3442 dyn_string_t. On success, returns STATUS_OK. On failure, returns
3443 an error message, and the contents of RESULT are unchanged. */
3444
3445 static status_t
3446 cp_demangle (name, result, style)
3447 const char *name;
3448 dyn_string_t result;
3449 int style;
3450 {
3451 status_t status;
3452 int length = strlen (name);
3453
3454 if (length > 2 && name[0] == '_' && name[1] == 'Z')
3455 {
3456 demangling_t dm = demangling_new (name, style);
3457 if (dm == NULL)
3458 return STATUS_ALLOCATION_FAILED;
3459
3460 status = result_push (dm);
3461 if (status != STATUS_OK)
3462 {
3463 demangling_delete (dm);
3464 return status;
3465 }
3466
3467 status = demangle_mangled_name (dm);
3468 if (STATUS_NO_ERROR (status))
3469 {
3470 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3471 if (!dyn_string_copy (result, demangled))
3472 return STATUS_ALLOCATION_FAILED;
3473 dyn_string_delete (demangled);
3474 }
3475
3476 demangling_delete (dm);
3477 }
3478 else
3479 {
3480 /* It's evidently not a mangled C++ name. It could be the name
3481 of something with C linkage, though, so just copy NAME into
3482 RESULT. */
3483 if (!dyn_string_copy_cstr (result, name))
3484 return STATUS_ALLOCATION_FAILED;
3485 status = STATUS_OK;
3486 }
3487
3488 return status;
3489 }
3490
3491 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3492 dyn_string_t. On success, returns STATUS_OK. On failiure, returns
3493 an error message, and the contents of RESULT are unchanged. */
3494
3495 #ifdef IN_LIBGCC2
3496 static status_t
3497 cp_demangle_type (type_name, result)
3498 const char* type_name;
3499 dyn_string_t result;
3500 {
3501 status_t status;
3502 demangling_t dm = demangling_new (type_name);
3503
3504 if (dm == NULL)
3505 return STATUS_ALLOCATION_FAILED;
3506
3507 /* Demangle the type name. The demangled name is stored in dm. */
3508 status = result_push (dm);
3509 if (status != STATUS_OK)
3510 {
3511 demangling_delete (dm);
3512 return status;
3513 }
3514
3515 status = demangle_type (dm);
3516
3517 if (STATUS_NO_ERROR (status))
3518 {
3519 /* The demangling succeeded. Pop the result out of dm and copy
3520 it into RESULT. */
3521 dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3522 if (!dyn_string_copy (result, demangled))
3523 return STATUS_ALLOCATION_FAILED;
3524 dyn_string_delete (demangled);
3525 }
3526
3527 /* Clean up. */
3528 demangling_delete (dm);
3529
3530 return status;
3531 }
3532
3533 extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
3534
3535 /* ia64 ABI-mandated entry point in the C++ runtime library for performing
3536 demangling. MANGLED_NAME is a NUL-terminated character string
3537 containing the name to be demangled.
3538
3539 OUTPUT_BUFFER is a region of memory, allocated with malloc, of
3540 *LENGTH bytes, into which the demangled name is stored. If
3541 OUTPUT_BUFFER is not long enough, it is expanded using realloc.
3542 OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
3543 is placed in a region of memory allocated with malloc.
3544
3545 If LENGTH is non-NULL, the length of the buffer conaining the
3546 demangled name, is placed in *LENGTH.
3547
3548 The return value is a pointer to the start of the NUL-terminated
3549 demangled name, or NULL if the demangling fails. The caller is
3550 responsible for deallocating this memory using free.
3551
3552 *STATUS is set to one of the following values:
3553 0: The demangling operation succeeded.
3554 -1: A memory allocation failiure occurred.
3555 -2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
3556 -3: One of the arguments is invalid.
3557
3558 The demagling is performed using the C++ ABI mangling rules, with
3559 GNU extensions. */
3560
3561 char *
3562 __cxa_demangle (mangled_name, output_buffer, length, status)
3563 const char *mangled_name;
3564 char *output_buffer;
3565 size_t *length;
3566 int *status;
3567 {
3568 struct dyn_string demangled_name;
3569 status_t result;
3570
3571 if (status == NULL)
3572 return NULL;
3573
3574 if (mangled_name == NULL) {
3575 *status = -3;
3576 return NULL;
3577 }
3578
3579 /* Did the caller provide a buffer for the demangled name? */
3580 if (output_buffer == NULL) {
3581 /* No; dyn_string will malloc a buffer for us. */
3582 if (!dyn_string_init (&demangled_name, 0))
3583 {
3584 *status = -1;
3585 return NULL;
3586 }
3587 }
3588 else {
3589 /* Yes. Check that the length was provided. */
3590 if (length == NULL) {
3591 *status = -3;
3592 return NULL;
3593 }
3594 /* Install the buffer into a dyn_string. */
3595 demangled_name.allocated = *length;
3596 demangled_name.length = 0;
3597 demangled_name.s = output_buffer;
3598 }
3599
3600 if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
3601 /* MANGLED_NAME apprears to be a function or variable name.
3602 Demangle it accordingly. */
3603 result = cp_demangle (mangled_name, &demangled_name, 0);
3604 else
3605 /* Try to demangled MANGLED_NAME as the name of a type. */
3606 result = cp_demangle_type (mangled_name, &demangled_name);
3607
3608 if (result == STATUS_OK)
3609 /* The demangling succeeded. */
3610 {
3611 /* If LENGTH isn't NULL, store the allocated buffer length
3612 there; the buffer may have been realloced by dyn_string
3613 functions. */
3614 if (length != NULL)
3615 *length = demangled_name.allocated;
3616 /* The operation was a success. */
3617 *status = 0;
3618 return dyn_string_buf (&demangled_name);
3619 }
3620 else if (result == STATUS_ALLOCATION_FAILED)
3621 /* A call to malloc or realloc failed during the demangling
3622 operation. */
3623 {
3624 *status = -1;
3625 return NULL;
3626 }
3627 else
3628 /* The demangling failed for another reason, most probably because
3629 MANGLED_NAME isn't a valid mangled name. */
3630 {
3631 /* If the buffer containing the demangled name wasn't provided
3632 by the caller, free it. */
3633 if (output_buffer == NULL)
3634 free (dyn_string_buf (&demangled_name));
3635 *status = -2;
3636 return NULL;
3637 }
3638 }
3639
3640 #else /* !IN_LIBGCC2 */
3641
3642 /* Variant entry point for integration with the existing cplus-dem
3643 demangler. Attempts to demangle MANGLED. If the demangling
3644 succeeds, returns a buffer, allocated with malloc, containing the
3645 demangled name. The caller must deallocate the buffer using free.
3646 If the demangling failes, returns NULL. */
3647
3648 char *
3649 cplus_demangle_v3 (mangled)
3650 const char* mangled;
3651 {
3652 dyn_string_t demangled;
3653 status_t status;
3654
3655 /* If this isn't a mangled name, don't pretend to demangle it. */
3656 if (strncmp (mangled, "_Z", 2) != 0)
3657 return NULL;
3658
3659 /* Create a dyn_string to hold the demangled name. */
3660 demangled = dyn_string_new (0);
3661 /* Attempt the demangling. */
3662 status = cp_demangle ((char *) mangled, demangled, 0);
3663
3664 if (STATUS_NO_ERROR (status))
3665 /* Demangling succeeded. */
3666 {
3667 /* Grab the demangled result from the dyn_string. It was
3668 allocated with malloc, so we can return it directly. */
3669 char *return_value = dyn_string_release (demangled);
3670 /* Hand back the demangled name. */
3671 return return_value;
3672 }
3673 else if (status == STATUS_ALLOCATION_FAILED)
3674 {
3675 fprintf (stderr, "Memory allocation failed.\n");
3676 abort ();
3677 }
3678 else
3679 /* Demangling failed. */
3680 {
3681 dyn_string_delete (demangled);
3682 return NULL;
3683 }
3684 }
3685
3686 /* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
3687 conventions, but the output formatting is a little different.
3688 This instructs the C++ demangler not to emit pointer characters ("*"), and
3689 to use Java's namespace separator symbol ("." instead of "::"). It then
3690 does an additional pass over the demangled output to replace instances
3691 of JArray<TYPE> with TYPE[]. */
3692
3693 char *
3694 java_demangle_v3 (mangled)
3695 const char* mangled;
3696 {
3697 dyn_string_t demangled;
3698 char *next;
3699 char *end;
3700 int len;
3701 status_t status;
3702 int nesting = 0;
3703 char *cplus_demangled;
3704 char *return_value;
3705
3706 /* Create a dyn_string to hold the demangled name. */
3707 demangled = dyn_string_new (0);
3708
3709 /* Attempt the demangling. */
3710 status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA);
3711
3712 if (STATUS_NO_ERROR (status))
3713 /* Demangling succeeded. */
3714 {
3715 /* Grab the demangled result from the dyn_string. */
3716 cplus_demangled = dyn_string_release (demangled);
3717 }
3718 else if (status == STATUS_ALLOCATION_FAILED)
3719 {
3720 fprintf (stderr, "Memory allocation failed.\n");
3721 abort ();
3722 }
3723 else
3724 /* Demangling failed. */
3725 {
3726 dyn_string_delete (demangled);
3727 return NULL;
3728 }
3729
3730 len = strlen (cplus_demangled);
3731 next = cplus_demangled;
3732 end = next + len;
3733 demangled = NULL;
3734
3735 /* Replace occurances of JArray<TYPE> with TYPE[]. */
3736 while (next < end)
3737 {
3738 char *open_str = strstr (next, "JArray<");
3739 char *close_str = NULL;
3740 if (nesting > 0)
3741 close_str = strchr (next, '>');
3742
3743 if (open_str != NULL && (close_str == NULL || close_str > open_str))
3744 {
3745 ++nesting;
3746
3747 if (!demangled)
3748 demangled = dyn_string_new(len);
3749
3750 /* Copy prepending symbols, if any. */
3751 if (open_str > next)
3752 {
3753 open_str[0] = 0;
3754 dyn_string_append_cstr (demangled, next);
3755 }
3756 next = open_str + 7;
3757 }
3758 else if (close_str != NULL)
3759 {
3760 --nesting;
3761
3762 /* Copy prepending type symbol, if any. Squash any spurious
3763 whitespace. */
3764 if (close_str > next && next[0] != ' ')
3765 {
3766 close_str[0] = 0;
3767 dyn_string_append_cstr (demangled, next);
3768 }
3769 dyn_string_append_cstr (demangled, "[]");
3770 next = close_str + 1;
3771 }
3772 else
3773 {
3774 /* There are no more arrays. Copy the rest of the symbol, or
3775 simply return the original symbol if no changes were made. */
3776 if (next == cplus_demangled)
3777 return cplus_demangled;
3778
3779 dyn_string_append_cstr (demangled, next);
3780 next = end;
3781 }
3782 }
3783
3784 free (cplus_demangled);
3785
3786 return_value = dyn_string_release (demangled);
3787 return return_value;
3788 }
3789
3790 #endif /* IN_LIBGCC2 */
3791
3792 #ifdef STANDALONE_DEMANGLER
3793
3794 #include "getopt.h"
3795
3796 static void print_usage
3797 PARAMS ((FILE* fp, int exit_value));
3798
3799 /* Non-zero if CHAR is a character than can occur in a mangled name. */
3800 #define is_mangled_char(CHAR) \
3801 (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \
3802 || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$')
3803
3804 /* The name of this program, as invoked. */
3805 const char* program_name;
3806
3807 /* Prints usage summary to FP and then exits with EXIT_VALUE. */
3808
3809 static void
3810 print_usage (fp, exit_value)
3811 FILE* fp;
3812 int exit_value;
3813 {
3814 fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
3815 fprintf (fp, "Options:\n");
3816 fprintf (fp, " -h,--help Display this message.\n");
3817 fprintf (fp, " -s,--strict Demangle standard names only.\n");
3818 fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
3819 fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
3820
3821 exit (exit_value);
3822 }
3823
3824 /* Option specification for getopt_long. */
3825 static struct option long_options[] =
3826 {
3827 { "help", no_argument, NULL, 'h' },
3828 { "strict", no_argument, NULL, 's' },
3829 { "verbose", no_argument, NULL, 'v' },
3830 { NULL, no_argument, NULL, 0 },
3831 };
3832
3833 /* Main entry for a demangling filter executable. It will demangle
3834 its command line arguments, if any. If none are provided, it will
3835 filter stdin to stdout, replacing any recognized mangled C++ names
3836 with their demangled equivalents. */
3837
3838 int
3839 main (argc, argv)
3840 int argc;
3841 char *argv[];
3842 {
3843 status_t status;
3844 int i;
3845 int opt_char;
3846
3847 /* Use the program name of this program, as invoked. */
3848 program_name = argv[0];
3849
3850 /* Parse options. */
3851 do
3852 {
3853 opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
3854 switch (opt_char)
3855 {
3856 case '?': /* Unrecognized option. */
3857 print_usage (stderr, 1);
3858 break;
3859
3860 case 'h':
3861 print_usage (stdout, 0);
3862 break;
3863
3864 case 's':
3865 flag_strict = 1;
3866 break;
3867
3868 case 'v':
3869 flag_verbose = 1;
3870 break;
3871 }
3872 }
3873 while (opt_char != -1);
3874
3875 if (optind == argc)
3876 /* No command line arguments were provided. Filter stdin. */
3877 {
3878 dyn_string_t mangled = dyn_string_new (3);
3879 dyn_string_t demangled = dyn_string_new (0);
3880 status_t status;
3881
3882 /* Read all of input. */
3883 while (!feof (stdin))
3884 {
3885 char c = getchar ();
3886
3887 /* The first character of a mangled name is an underscore. */
3888 if (feof (stdin))
3889 break;
3890 if (c != '_')
3891 {
3892 /* It's not a mangled name. Print the character and go
3893 on. */
3894 putchar (c);
3895 continue;
3896 }
3897 c = getchar ();
3898
3899 /* The second character of a mangled name is a capital `Z'. */
3900 if (feof (stdin))
3901 break;
3902 if (c != 'Z')
3903 {
3904 /* It's not a mangled name. Print the previous
3905 underscore, the `Z', and go on. */
3906 putchar ('_');
3907 putchar (c);
3908 continue;
3909 }
3910
3911 /* Start keeping track of the candidate mangled name. */
3912 dyn_string_append_char (mangled, '_');
3913 dyn_string_append_char (mangled, 'Z');
3914
3915 /* Pile characters into mangled until we hit one that can't
3916 occur in a mangled name. */
3917 c = getchar ();
3918 while (!feof (stdin) && is_mangled_char (c))
3919 {
3920 dyn_string_append_char (mangled, c);
3921 if (feof (stdin))
3922 break;
3923 c = getchar ();
3924 }
3925
3926 /* Attempt to demangle the name. */
3927 status = cp_demangle (dyn_string_buf (mangled), demangled, 0);
3928
3929 /* If the demangling succeeded, great! Print out the
3930 demangled version. */
3931 if (STATUS_NO_ERROR (status))
3932 fputs (dyn_string_buf (demangled), stdout);
3933 /* Abort on allocation failures. */
3934 else if (status == STATUS_ALLOCATION_FAILED)
3935 {
3936 fprintf (stderr, "Memory allocation failed.\n");
3937 abort ();
3938 }
3939 /* Otherwise, it might not have been a mangled name. Just
3940 print out the original text. */
3941 else
3942 fputs (dyn_string_buf (mangled), stdout);
3943
3944 /* If we haven't hit EOF yet, we've read one character that
3945 can't occur in a mangled name, so print it out. */
3946 if (!feof (stdin))
3947 putchar (c);
3948
3949 /* Clear the candidate mangled name, to start afresh next
3950 time we hit a `_Z'. */
3951 dyn_string_clear (mangled);
3952 }
3953
3954 dyn_string_delete (mangled);
3955 dyn_string_delete (demangled);
3956 }
3957 else
3958 /* Demangle command line arguments. */
3959 {
3960 dyn_string_t result = dyn_string_new (0);
3961
3962 /* Loop over command line arguments. */
3963 for (i = optind; i < argc; ++i)
3964 {
3965 /* Attempt to demangle. */
3966 status = cp_demangle (argv[i], result, 0);
3967
3968 /* If it worked, print the demangled name. */
3969 if (STATUS_NO_ERROR (status))
3970 printf ("%s\n", dyn_string_buf (result));
3971 /* Abort on allocaiton failures. */
3972 else if (status == STATUS_ALLOCATION_FAILED)
3973 {
3974 fprintf (stderr, "Memory allocation failed.\n");
3975 abort ();
3976 }
3977 /* If not, print the error message to stderr instead. */
3978 else
3979 fprintf (stderr, "%s\n", status);
3980 }
3981 dyn_string_delete (result);
3982 }
3983
3984 return 0;
3985 }
3986
3987 #endif /* STANDALONE_DEMANGLER */
This page took 0.10874 seconds and 5 git commands to generate.