OSDN Git Service

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