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