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