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