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