OSDN Git Service

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