* md5.c: #include "ansidecl.h".
[external/binutils.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 static status_t cp_demangle_type
858   PARAMS ((const char*, dyn_string_t));
859
860 /* When passed to demangle_bare_function_type, indicates that the
861    function's return type is not encoded before its parameter types.  */
862 #define BFT_NO_RETURN_TYPE    -1
863
864 /* Check that the next character is C.  If so, consume it.  If not,
865    return an error.  */
866
867 static status_t
868 demangle_char (dm, c)
869      demangling_t dm;
870      int c;
871 {
872   static char *error_message = NULL;
873
874   if (peek_char (dm) == c)
875     {
876       advance_char (dm);
877       return STATUS_OK;
878     }
879   else
880     {
881       if (error_message == NULL)
882         error_message = strdup ("Expected ?");
883       error_message[9] = c;
884       return error_message;
885     }
886 }
887
888 /* Demangles and emits a <mangled-name>.  
889
890     <mangled-name>      ::= _Z <encoding>  */
891
892 static status_t
893 demangle_mangled_name (dm)
894      demangling_t dm;
895 {
896   DEMANGLE_TRACE ("mangled-name", dm);
897   RETURN_IF_ERROR (demangle_char (dm, '_'));
898   RETURN_IF_ERROR (demangle_char (dm, 'Z'));
899   RETURN_IF_ERROR (demangle_encoding (dm));
900   return STATUS_OK;
901 }
902
903 /* Demangles and emits an <encoding>.  
904
905     <encoding>          ::= <function name> <bare-function-type>
906                         ::= <data name>
907                         ::= <special-name>  */
908
909 static status_t
910 demangle_encoding (dm)
911      demangling_t dm;
912 {
913   int template_p;
914   int start_position;
915   template_arg_list_t old_arg_list = current_template_arg_list (dm);
916   char peek = peek_char (dm);
917
918   DEMANGLE_TRACE ("encoding", dm);
919   
920   /* Remember where the name starts.  If it turns out to be a template
921      function, we'll have to insert the return type here.  */
922   start_position = result_length (dm);
923
924   if (peek == 'G' || peek == 'T')
925     RETURN_IF_ERROR (demangle_special_name (dm));
926   else
927     {
928       /* Now demangle the name.  */
929       RETURN_IF_ERROR (demangle_name (dm, &template_p));
930
931       /* If there's anything left, the name was a function name, with
932          maybe its return type, and its parameters types, following.  */
933       if (!end_of_name_p (dm) 
934           && peek_char (dm) != 'E')
935         {
936           if (template_p)
937             /* Template functions have their return type encoded.  The
938                return type should be inserted at start_position.  */
939             RETURN_IF_ERROR 
940               (demangle_bare_function_type (dm, start_position));
941           else
942             /* Non-template functions don't have their return type
943                encoded.  */
944             RETURN_IF_ERROR 
945               (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE)); 
946         }
947     }
948
949   /* Pop off template argument lists that were built during the
950      mangling of this name, to restore the old template context.  */
951   pop_to_template_arg_list (dm, old_arg_list);
952
953   return STATUS_OK;
954 }
955
956 /* Demangles and emits a <name>.
957
958     <name>              ::= <unscoped-name>
959                         ::= <unscoped-template-name> <template-args>
960                         ::= <nested-name>
961                         ::= <local-name>
962
963     <unscoped-name>     ::= <unqualified-name>
964                         ::= St <unqualified-name>   # ::std::
965
966     <unscoped-template-name>    
967                         ::= <unscoped-name>
968                         ::= <substitution>  */
969
970 static status_t
971 demangle_name (dm, template_p)
972      demangling_t dm;
973      int *template_p;
974 {
975   int special_std_substitution;
976   int start = substitution_start (dm);
977
978   DEMANGLE_TRACE ("name", dm);
979
980   switch (peek_char (dm))
981     {
982     case 'N':
983       /* This is a <nested-name>.  */
984       RETURN_IF_ERROR (demangle_nested_name (dm, template_p));
985       break;
986
987     case 'Z':
988       RETURN_IF_ERROR (demangle_local_name (dm));
989       break;
990
991     case 'S':
992       /* The `St' substitution allows a name nested in std:: to appear
993          without being enclosed in a nested name.  */
994       if (peek_char_next (dm) == 't') 
995         {
996           (void) next_char (dm);
997           (void) next_char (dm);
998           RETURN_IF_ERROR (result_append (dm, "std::"));
999           RETURN_IF_ERROR (demangle_unqualified_name (dm));
1000         }
1001       else
1002         {
1003           RETURN_IF_ERROR (demangle_substitution (dm, template_p,
1004                                                   &special_std_substitution));
1005           if (special_std_substitution)
1006             {
1007               /* This was the magic `std::' substitution.  We can have
1008                  a <nested-name> or one of the unscoped names
1009                  following.  */
1010               RETURN_IF_ERROR (result_append (dm, "::"));
1011               RETURN_IF_ERROR (demangle_name (dm, template_p));
1012             }
1013         }
1014       /* Check if a template argument list immediately follows.
1015          If so, then we just demangled an <unqualified-template-name>.  */
1016       if (peek_char (dm) == 'I') 
1017         {
1018           RETURN_IF_ERROR (substitution_add (dm, start, 0, 
1019                                              NOT_TEMPLATE_PARM));
1020           RETURN_IF_ERROR (demangle_template_args (dm));
1021         }
1022       break;
1023
1024     default:
1025       /* This is an <unscoped-name> or <unscoped-template-name>.  */
1026       RETURN_IF_ERROR (demangle_unqualified_name (dm));
1027
1028       /* If the <unqualified-name> is followed by template args, this
1029          is an <unscoped-template-name>.  */
1030       if (peek_char (dm) == 'I')
1031         {
1032           /* Add a substitution for the unqualified template name.  */
1033           RETURN_IF_ERROR (substitution_add (dm, start, 0, 
1034                                              NOT_TEMPLATE_PARM));
1035
1036           RETURN_IF_ERROR (demangle_template_args (dm));
1037           *template_p = 1;
1038         }
1039       else
1040         *template_p = 0;
1041
1042       break;
1043     }
1044
1045   return STATUS_OK;
1046 }
1047
1048 /* Demangles and emits a <nested-name>. 
1049
1050     <nested-name>       ::= N [<CV-qualifiers>] <prefix> <component> E  */
1051
1052 static status_t
1053 demangle_nested_name (dm, template_p)
1054      demangling_t dm;
1055      int *template_p;
1056 {
1057   char peek;
1058
1059   DEMANGLE_TRACE ("nested-name", dm);
1060
1061   RETURN_IF_ERROR (demangle_char (dm, 'N'));
1062
1063   peek = peek_char (dm);
1064   if (peek == 'r' || peek == 'V' || peek == 'K')
1065     {
1066       status_t status;
1067
1068       /* Snarf up and emit CV qualifiers.  */
1069       dyn_string_t cv_qualifiers = dyn_string_new (24);
1070       if (cv_qualifiers == NULL)
1071         return STATUS_ALLOCATION_FAILED;
1072
1073       demangle_CV_qualifiers (dm, cv_qualifiers);
1074       status = result_append_string (dm, cv_qualifiers);
1075       dyn_string_delete (cv_qualifiers);
1076       RETURN_IF_ERROR (status);
1077       RETURN_IF_ERROR (result_append_space (dm));
1078     }
1079   
1080   RETURN_IF_ERROR (demangle_prefix (dm, template_p));
1081   /* No need to demangle the final <component>; demangle_prefix will
1082      handle it.  */
1083   RETURN_IF_ERROR (demangle_char (dm, 'E'));
1084
1085   return STATUS_OK;
1086 }
1087
1088 /* Demangles and emits a <prefix>.
1089
1090     <prefix>            ::= <prefix> <component>
1091                         ::= <template-prefix> <template-args>
1092                         ::= # empty
1093                         ::= <substitution>
1094
1095     <template-prefix>   ::= <prefix>
1096                         ::= <substitution>
1097
1098     <component>         ::= <unqualified-name>
1099                         ::= <local-name>  */
1100
1101 static status_t
1102 demangle_prefix (dm, template_p)
1103      demangling_t dm;
1104      int *template_p;
1105 {
1106   int start = substitution_start (dm);
1107   int nested = 0;
1108
1109   /* TEMPLATE_P is updated as we decend the nesting chain.  After
1110      <template-args>, it is set to non-zero; after everything else it
1111      is set to zero.  */
1112
1113   DEMANGLE_TRACE ("prefix", dm);
1114
1115   while (1)
1116     {
1117       char peek;
1118       int unused;
1119
1120       if (end_of_name_p (dm))
1121         return "Unexpected end of name in <compound-name>.";
1122
1123       peek = peek_char (dm);
1124       
1125       if (IS_DIGIT ((unsigned char) peek)
1126           || (peek >= 'a' && peek <= 'z')
1127           || peek == 'C' || peek == 'D'
1128           || peek == 'S')
1129         {
1130           /* We have another level of scope qualification.  */
1131           if (nested)
1132             RETURN_IF_ERROR (result_append (dm, "::"));
1133           else
1134             nested = 1;
1135
1136           if (peek == 'S')
1137             /* The substitution determines whether this is a
1138                template-id.   */
1139             RETURN_IF_ERROR (demangle_substitution (dm, template_p, 
1140                                                     &unused));
1141           else
1142             {
1143               RETURN_IF_ERROR (demangle_unqualified_name (dm));
1144               *template_p = 0;
1145             }
1146         }
1147       else if (peek == 'Z')
1148         RETURN_IF_ERROR (demangle_local_name (dm));
1149       else if (peek == 'I')
1150         {
1151           if (*template_p)
1152             return STATUS_INTERNAL_ERROR;
1153           /* The template name is a substitution candidate.  */
1154           RETURN_IF_ERROR (substitution_add (dm, start, 0, NOT_TEMPLATE_PARM));
1155           RETURN_IF_ERROR (demangle_template_args (dm));
1156           *template_p = 1;
1157         }
1158       else if (peek == 'E')
1159         /* All done.  */
1160         return STATUS_OK;
1161       else
1162         return "Unexpected character in <compound-name>.";
1163
1164       /* Add a new substitution for the prefix thus far.  */
1165       RETURN_IF_ERROR (substitution_add (dm, start, *template_p, 
1166                                          NOT_TEMPLATE_PARM));
1167     }
1168 }
1169
1170 /* Demangles and emits an <unqualified-name>.  If the
1171    <unqualified-name> is a function and the first element in the
1172    argument list should be taken to be its return type,
1173    ENCODE_RETURN_TYPE is non-zero.
1174
1175     <unqualified-name>  ::= <operator-name>
1176                         ::= <special-name>  
1177                         ::= <source-name>  */
1178
1179 static status_t
1180 demangle_unqualified_name (dm)
1181      demangling_t dm;
1182 {
1183   char peek = peek_char (dm);
1184
1185   DEMANGLE_TRACE ("unqualified-name", dm);
1186
1187   if (IS_DIGIT ((unsigned char) peek))
1188     RETURN_IF_ERROR (demangle_source_name (dm));
1189   else if (peek >= 'a' && peek <= 'z')
1190     {
1191       int num_args;
1192       RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args));
1193     }
1194   else if (peek == 'C' || peek == 'D')
1195     RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
1196   else
1197     return "Unexpected character in <unqualified-name>.";
1198
1199   return STATUS_OK;
1200 }
1201
1202 /* Demangles and emits <source-name>.  
1203
1204     <source-name> ::= <length number> <identifier>  */
1205
1206 static status_t
1207 demangle_source_name (dm)
1208      demangling_t dm;
1209 {
1210   int length;
1211
1212   DEMANGLE_TRACE ("source-name", dm);
1213
1214   /* Decode the length of the identifier.  */
1215   RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
1216   if (length == 0)
1217     return "Zero length in <source-name>.";
1218
1219   /* Now the identifier itself.  It's placed into last_source_name,
1220      where it can be used to build a constructor or destructor name.  */
1221   RETURN_IF_ERROR (demangle_identifier (dm, length, 
1222                                         dm->last_source_name));
1223
1224   /* Emit it.  */
1225   RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1226
1227   return STATUS_OK;
1228 }
1229
1230 /* Demangles a number, either a <number> or a <positive-number> at the
1231    current position, consuming all consecutive digit characters.  Sets
1232    *VALUE to the resulting numberand returns STATUS_OK.  The number is
1233    interpreted as BASE, which must be either 10 or 36.  If IS_SIGNED
1234    is non-zero, negative numbers -- prefixed with `n' -- are accepted.
1235
1236     <number> ::= [n] <positive-number>
1237
1238     <positive-number> ::= <decimal integer>  */
1239
1240 static status_t
1241 demangle_number (dm, value, base, is_signed)
1242      demangling_t dm;
1243      int *value;
1244      int base;
1245      int is_signed;
1246 {
1247   dyn_string_t number = dyn_string_new (10);
1248
1249   DEMANGLE_TRACE ("number", dm);
1250
1251   if (number == NULL)
1252     return STATUS_ALLOCATION_FAILED;
1253
1254   demangle_number_literally (dm, number, base, is_signed);
1255   *value = strtol (dyn_string_buf (number), NULL, base);
1256   dyn_string_delete (number);
1257
1258   return STATUS_OK;
1259 }
1260
1261 /* Demangles a number at the current position.  The digits (and minus
1262    sign, if present) that make up the number are appended to STR.
1263    Only base-BASE digits are accepted; BASE must be either 10 or 36.
1264    If IS_SIGNED, negative numbers -- prefixed with `n' -- are
1265    accepted.  Does not consume a trailing underscore or other
1266    terminating character.  */
1267
1268 static status_t
1269 demangle_number_literally (dm, str, base, is_signed)
1270      demangling_t dm;
1271      dyn_string_t str;
1272      int base;
1273      int is_signed;
1274 {
1275   DEMANGLE_TRACE ("number*", dm);
1276
1277   if (base != 10 && base != 36)
1278     return STATUS_INTERNAL_ERROR;
1279
1280   /* An `n' denotes a negative number.  */
1281   if (is_signed && peek_char (dm) == 'n')
1282     {
1283       /* Skip past the n.  */
1284       advance_char (dm);
1285       /* The normal way to write a negative number is with a minus
1286          sign.  */
1287       if (!dyn_string_append_char (str, '-'))
1288         return STATUS_ALLOCATION_FAILED;
1289     }
1290
1291   /* Loop until we hit a non-digit.  */
1292   while (1)
1293     {
1294       char peek = peek_char (dm);
1295       if (IS_DIGIT ((unsigned char) peek)
1296           || (base == 36 && peek >= 'A' && peek <= 'Z'))
1297         {
1298           /* Accumulate digits.  */
1299           if (!dyn_string_append_char (str, next_char (dm)))
1300             return STATUS_ALLOCATION_FAILED;
1301         }
1302       else
1303         /* Not a digit?  All done.  */
1304         break;
1305     }
1306
1307   return STATUS_OK;
1308 }
1309
1310 /* Demangles an identifier at the current position of LENGTH
1311    characters and places it in IDENTIFIER.  */
1312
1313 static status_t
1314 demangle_identifier (dm, length, identifier)
1315      demangling_t dm;
1316      int length;
1317      dyn_string_t identifier;
1318 {
1319   DEMANGLE_TRACE ("identifier", dm);
1320
1321   dyn_string_clear (identifier);
1322   if (!dyn_string_resize (identifier, length))
1323     return STATUS_ALLOCATION_FAILED;
1324
1325   while (length-- > 0)
1326     {
1327       if (end_of_name_p (dm))
1328         return "Unexpected end of name in <identifier>.";
1329       if (!dyn_string_append_char (identifier, next_char (dm)))
1330         return STATUS_ALLOCATION_FAILED;
1331     }
1332
1333   return STATUS_OK;
1334 }
1335
1336 /* Demangles and emits an <operator-name>.  If SHORT_NAME is non-zero,
1337    the short form is emitted; otherwise the full source form
1338    (`operator +' etc.) is emitted.  *NUM_ARGS is set to the number of
1339    operands that the operator takes.  
1340
1341     <operator-name>
1342                   ::= nw        # new           
1343                   ::= na        # new[]
1344                   ::= dl        # delete        
1345                   ::= da        # delete[]      
1346                   ::= ps        # + (unary)
1347                   ::= ng        # - (unary)     
1348                   ::= ad        # & (unary)     
1349                   ::= de        # * (unary)     
1350                   ::= co        # ~             
1351                   ::= pl        # +             
1352                   ::= mi        # -             
1353                   ::= ml        # *             
1354                   ::= dv        # /             
1355                   ::= rm        # %             
1356                   ::= an        # &             
1357                   ::= or        # |             
1358                   ::= eo        # ^             
1359                   ::= aS        # =             
1360                   ::= pL        # +=            
1361                   ::= mI        # -=            
1362                   ::= mL        # *=            
1363                   ::= dV        # /=            
1364                   ::= rM        # %=            
1365                   ::= aN        # &=            
1366                   ::= oR        # |=            
1367                   ::= eO        # ^=            
1368                   ::= ls        # <<            
1369                   ::= rs        # >>            
1370                   ::= lS        # <<=           
1371                   ::= rS        # >>=           
1372                   ::= eq        # ==            
1373                   ::= ne        # !=            
1374                   ::= lt        # <             
1375                   ::= gt        # >             
1376                   ::= le        # <=            
1377                   ::= ge        # >=            
1378                   ::= nt        # !             
1379                   ::= aa        # &&            
1380                   ::= oo        # ||            
1381                   ::= pp        # ++            
1382                   ::= mm        # --            
1383                   ::= cm        # ,             
1384                   ::= pm        # ->*           
1385                   ::= pt        # ->            
1386                   ::= cl        # ()            
1387                   ::= ix        # []            
1388                   ::= qu        # ?
1389                   ::= sz        # sizeof 
1390                   ::= cv <type> # cast        
1391                   ::= vx <source-name>  # vendor extended operator  */
1392
1393 static status_t
1394 demangle_operator_name (dm, short_name, num_args)
1395      demangling_t dm;
1396      int short_name;
1397      int *num_args;
1398 {
1399   struct operator_code
1400   {
1401     /* The mangled code for this operator.  */
1402     const char *code;
1403     /* The source name of this operator.  */
1404     const char *name;
1405     /* The number of arguments this operator takes.  */
1406     int num_args;
1407   };
1408
1409   static const struct operator_code operators[] = 
1410   {
1411     { "aN", "&="       , 2 },
1412     { "aS", "="        , 2 },
1413     { "aa", "&&"       , 2 },
1414     { "ad", "&"        , 1 },
1415     { "an", "&"        , 2 },
1416     { "cl", "()"       , 0 },
1417     { "cm", ","        , 2 },
1418     { "co", "~"        , 1 },
1419     { "dV", "/="       , 2 },
1420     { "da", " delete[]", 1 },
1421     { "de", "*"        , 1 },
1422     { "dl", " delete"  , 1 },
1423     { "dv", "/"        , 2 },
1424     { "eO", "^="       , 2 },
1425     { "eo", "^"        , 2 },
1426     { "eq", "=="       , 2 },
1427     { "ge", ">="       , 2 },
1428     { "gt", ">"        , 2 },
1429     { "ix", "[]"       , 2 },
1430     { "lS", "<<="      , 2 },
1431     { "le", "<="       , 2 },
1432     { "ls", "<<"       , 2 },
1433     { "lt", "<"        , 2 },
1434     { "mI", "-="       , 2 },
1435     { "mL", "*="       , 2 },
1436     { "mi", "-"        , 2 },
1437     { "ml", "*"        , 2 },
1438     { "mm", "--"       , 1 },
1439     { "na", " new[]"   , 1 },
1440     { "ne", "!="       , 2 },
1441     { "ng", "-"        , 1 },
1442     { "nt", "!"        , 1 },
1443     { "nw", " new"     , 1 },
1444     { "oR", "|="       , 2 },
1445     { "oo", "||"       , 2 },
1446     { "or", "|"        , 2 },
1447     { "pL", "+="       , 2 },
1448     { "pl", "+"        , 2 },
1449     { "pm", "->*"      , 2 },
1450     { "pp", "++"       , 1 },
1451     { "ps", "+"        , 1 },
1452     { "qu", "?"        , 3 },
1453     { "rM", "%="       , 2 },
1454     { "rS", ">>="      , 2 },
1455     { "rm", "%"        , 2 },
1456     { "rs", ">>"       , 2 },
1457     { "sz", " sizeof"  , 1 }
1458   };
1459
1460   const int num_operators = 
1461     sizeof (operators) / sizeof (struct operator_code);
1462
1463   int c0 = next_char (dm);
1464   int c1 = next_char (dm);
1465   const struct operator_code* p1 = operators;
1466   const struct operator_code* p2 = operators + num_operators;
1467
1468   DEMANGLE_TRACE ("operator-name", dm);
1469
1470   /* Is this a vendor extended operator?  */
1471   if (c0 == 'v' && c1 == 'x')
1472     {
1473       RETURN_IF_ERROR (result_append (dm, "operator"));
1474       RETURN_IF_ERROR (demangle_source_name (dm));
1475       *num_args = 0;
1476       return STATUS_OK;
1477     }
1478
1479   /* Is this a conversion operator?  */
1480   if (c0 == 'c' && c1 == 'v')
1481     {
1482       RETURN_IF_ERROR (result_append (dm, "operator "));
1483       /* Demangle the converted-to type.  */
1484       RETURN_IF_ERROR (demangle_type (dm));
1485       *num_args = 0;
1486       return STATUS_OK;
1487     }
1488
1489   /* Perform a binary search for the operator code.  */
1490   while (1)
1491     {
1492       const struct operator_code* p = p1 + (p2 - p1) / 2;
1493       char match0 = p->code[0];
1494       char match1 = p->code[1];
1495
1496       if (c0 == match0 && c1 == match1)
1497         /* Found it.  */
1498         {
1499           if (!short_name)
1500             RETURN_IF_ERROR (result_append (dm, "operator"));
1501           RETURN_IF_ERROR (result_append (dm, p->name));
1502           *num_args = p->num_args;
1503
1504           return STATUS_OK;
1505         }
1506
1507       if (p == p1)
1508         /* Couldn't find it.  */
1509         return "Unknown code in <operator-name>.";
1510
1511       /* Try again.  */
1512       if (c0 < match0 || (c0 == match0 && c1 < match1))
1513         p2 = p;
1514       else
1515         p1 = p;
1516     }
1517 }
1518
1519 /* Demangles and emits a <special-name>.  
1520
1521     <special-name> ::= GV <object name>   # Guard variable
1522                    ::= Th[n] <offset number> _ <base name> <base encoding>
1523                                           # non-virtual base override thunk
1524                    ::= Tv[n] <offset number> _ <vcall offset number> 
1525                          _ <base encoding>
1526                                           # virtual base override thunk
1527                    ::= TV <type>          # virtual table
1528                    ::= TT <type>          # VTT
1529                    ::= TI <type>          # typeinfo structure
1530                    ::= TS <type>          # typeinfo name  
1531
1532    Also demangles the special g++ manglings,
1533
1534     <special-name> ::= CT <type> <offset number> _ <base type>
1535                                           # construction vtable
1536                    ::= TF <type>          # typeinfo function (old ABI only)
1537                    ::= TJ <type>          # java Class structure  */
1538
1539 static status_t
1540 demangle_special_name (dm)
1541      demangling_t dm;
1542 {
1543   dyn_string_t number;
1544   int unused;
1545   char peek = peek_char (dm);
1546
1547   DEMANGLE_TRACE ("special-name", dm);
1548
1549   if (peek == 'G')
1550     {
1551       /* A guard variable name.  Consume the G.  */
1552       advance_char (dm);
1553       RETURN_IF_ERROR (demangle_char (dm, 'V'));
1554       RETURN_IF_ERROR (result_append (dm, "guard variable for "));
1555       RETURN_IF_ERROR (demangle_name (dm, &unused));
1556     }
1557   else if (peek == 'T')
1558     {
1559       status_t status = STATUS_OK;
1560
1561       /* Other C++ implementation miscellania.  Consume the T.  */
1562       advance_char (dm);
1563
1564       switch (peek_char (dm))
1565         {
1566         case 'V':
1567           /* Virtual table.  */
1568           advance_char (dm);
1569           RETURN_IF_ERROR (result_append (dm, "vtable for "));
1570           RETURN_IF_ERROR (demangle_type (dm));
1571           break;
1572
1573         case 'T':
1574           /* VTT structure.  */
1575           advance_char (dm);
1576           RETURN_IF_ERROR (result_append (dm, "VTT for "));
1577           RETURN_IF_ERROR (demangle_type (dm));
1578           break;
1579
1580         case 'I':
1581           /* Typeinfo structure.  */
1582           advance_char (dm);
1583           RETURN_IF_ERROR (result_append (dm, "typeinfo for "));
1584           RETURN_IF_ERROR (demangle_type (dm));
1585           break;
1586
1587         case 'F':
1588           /* Typeinfo function.  Used only in old ABI with new mangling.  */
1589           advance_char (dm);
1590           RETURN_IF_ERROR (result_append (dm, "typeinfo fn for "));
1591           RETURN_IF_ERROR (demangle_type (dm));
1592           break;
1593
1594         case 'S':
1595           /* Character string containing type name, used in typeinfo. */
1596           advance_char (dm);
1597           RETURN_IF_ERROR (result_append (dm, "typeinfo name for "));
1598           RETURN_IF_ERROR (demangle_type (dm));
1599           break;
1600
1601         case 'J':
1602           /* The java Class variable corresponding to a C++ class.  */
1603           advance_char (dm);
1604           RETURN_IF_ERROR (result_append (dm, "java Class for "));
1605           RETURN_IF_ERROR (demangle_type (dm));
1606           break;
1607
1608         case 'h':
1609           /* Non-virtual thunk.  */
1610           advance_char (dm);
1611           RETURN_IF_ERROR (result_append (dm, "non-virtual thunk"));
1612           /* Demangle and emit the offset.  */
1613           number = dyn_string_new (4);
1614           if (number == NULL)
1615             return STATUS_ALLOCATION_FAILED;
1616           demangle_number_literally (dm, number, 10, 1);
1617           /* Don't display the offset unless in verbose mode.  */
1618           if (flag_verbose)
1619             {
1620               status = result_append_char (dm, ' ');
1621               if (STATUS_NO_ERROR (status))
1622                 status = result_append_string (dm, number);
1623             }
1624           dyn_string_delete (number);
1625           RETURN_IF_ERROR (status);
1626           /* Demangle the separator.  */
1627           RETURN_IF_ERROR (demangle_char (dm, '_'));
1628           /* Demangle and emit the target name and function type.  */
1629           RETURN_IF_ERROR (result_append (dm, " to "));
1630           RETURN_IF_ERROR (demangle_encoding (dm));
1631           break;
1632
1633         case 'v':
1634           /* Virtual thunk.  */
1635           advance_char (dm);
1636           RETURN_IF_ERROR (result_append (dm, "virtual thunk "));
1637           /* Demangle and emit the offset.  */
1638           number = dyn_string_new (4);
1639           if (number == NULL)
1640             return STATUS_ALLOCATION_FAILED;
1641           demangle_number_literally (dm, number, 10, 1);
1642           /* Don't display the offset unless in verbose mode.  */
1643           if (flag_verbose)
1644             {
1645               status = result_append_string (dm, number);
1646               if (STATUS_NO_ERROR (status))
1647                 result_append_char (dm, ' ');
1648             }
1649           dyn_string_delete (number);
1650           RETURN_IF_ERROR (status);
1651           /* Demangle the separator.  */
1652           RETURN_IF_ERROR (demangle_char (dm, '_'));
1653           /* Demangle and emit the vcall offset.  */
1654           number = dyn_string_new (4);
1655           if (number == NULL)
1656             return STATUS_ALLOCATION_FAILED;
1657           demangle_number_literally (dm, number, 10, 1);
1658           /* Don't display the vcall offset unless in verbose mode.  */
1659           if (flag_verbose)
1660             {
1661               status = result_append_string (dm, number);
1662               if (STATUS_NO_ERROR (status))
1663                 status = result_append_char (dm, ' ');
1664             }
1665           dyn_string_delete (number);
1666           RETURN_IF_ERROR (status);
1667           /* Demangle the separator.  */
1668           RETURN_IF_ERROR (demangle_char (dm, '_'));
1669           /* Demangle and emit the target function.  */
1670           RETURN_IF_ERROR (result_append (dm, "to "));
1671           RETURN_IF_ERROR (demangle_encoding (dm));
1672           break;
1673
1674         case 'C':
1675           /* TC is a special g++ mangling for a construction vtable. */
1676           if (!flag_strict)
1677             {
1678               dyn_string_t derived_type;
1679
1680               advance_char (dm);
1681               RETURN_IF_ERROR (result_append (dm, "construction vtable for "));
1682
1683               /* Demangle the derived type off to the side.  */
1684               RETURN_IF_ERROR (result_push (dm));
1685               RETURN_IF_ERROR (demangle_type (dm));
1686               derived_type = (dyn_string_t) result_pop (dm);
1687
1688               /* Demangle the offset.  */
1689               number = dyn_string_new (4);
1690               if (number == NULL)
1691                 {
1692                   dyn_string_delete (derived_type);
1693                   return STATUS_ALLOCATION_FAILED;
1694                 }
1695               demangle_number_literally (dm, number, 10, 1);
1696               /* Demangle the underscore separator.  */
1697               status = demangle_char (dm, '_');
1698
1699               /* Demangle the base type.  */
1700               if (STATUS_NO_ERROR (status))
1701                 status = demangle_type (dm);
1702
1703               /* Emit the derived type.  */
1704               if (STATUS_NO_ERROR (status))
1705                 status = result_append (dm, "-in-");
1706               if (STATUS_NO_ERROR (status))
1707                 status = result_append_string (dm, derived_type);
1708               dyn_string_delete (derived_type);
1709
1710               /* Don't display the offset unless in verbose mode.  */
1711               if (flag_verbose)
1712                 {
1713                   status = result_append_char (dm, ' ');
1714                   if (STATUS_NO_ERROR (status))
1715                     result_append_string (dm, number);
1716                 }
1717               dyn_string_delete (number);
1718               RETURN_IF_ERROR (status);
1719               break;
1720             }
1721           /* If flag_strict, fall through.  */
1722
1723         default:
1724           return "Unrecognized <special-name>.";
1725         }
1726     }
1727   else
1728     return STATUS_ERROR;
1729
1730   return STATUS_OK;
1731 }
1732
1733 /* Demangles and emits a <ctor-dtor-name>.  
1734    
1735     <ctor-dtor-name>
1736                    ::= C1  # complete object (in-charge) ctor
1737                    ::= C2  # base object (not-in-charge) ctor
1738                    ::= C3  # complete object (in-charge) allocating ctor
1739                    ::= C4  # base object (not-in-charge) allocating ctor
1740                    ::= D0  # deleting (in-charge) dtor
1741                    ::= D1  # complete object (in-charge) dtor
1742                    ::= D2  # base object (not-in-charge) dtor  */
1743
1744 static status_t
1745 demangle_ctor_dtor_name (dm)
1746      demangling_t dm;
1747 {
1748   static const char *const ctor_flavors[] = 
1749   {
1750     "in-charge",
1751     "not-in-charge",
1752     "in-charge allocating",
1753     "not-in-charge allocating"
1754   };
1755   static const char *const dtor_flavors[] = 
1756   {
1757     "in-charge deleting",
1758     "in-charge",
1759     "not-in-charge"
1760   };
1761
1762   int flavor;
1763   char peek = peek_char (dm);
1764
1765   DEMANGLE_TRACE ("ctor-dtor-name", dm);
1766   
1767   if (peek == 'C')
1768     {
1769       /* A constructor name.  Consume the C.  */
1770       advance_char (dm);
1771       if (peek_char (dm) < '1' || peek_char (dm) > '4')
1772         return "Unrecognized constructor.";
1773       RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1774       /* Print the flavor of the constructor if in verbose mode.  */
1775       flavor = next_char (dm) - '1';
1776       if (flag_verbose)
1777         {
1778           RETURN_IF_ERROR (result_append (dm, "["));
1779           RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor]));
1780           RETURN_IF_ERROR (result_append_char (dm, ']'));
1781         }
1782     }
1783   else if (peek == 'D')
1784     {
1785       /* A destructor name.  Consume the D.  */
1786       advance_char (dm);
1787       if (peek_char (dm) < '0' || peek_char (dm) > '2')
1788         return "Unrecognized destructor.";
1789       RETURN_IF_ERROR (result_append_char (dm, '~'));
1790       RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
1791       /* Print the flavor of the destructor if in verbose mode.  */
1792       flavor = next_char (dm) - '0';
1793       if (flag_verbose)
1794         {
1795           RETURN_IF_ERROR (result_append (dm, " ["));
1796           RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor]));
1797           RETURN_IF_ERROR (result_append_char (dm, ']'));
1798         }
1799     }
1800   else
1801     return STATUS_ERROR;
1802
1803   return STATUS_OK;
1804 }
1805
1806 /* Handle pointer, reference, and pointer-to-member cases for
1807    demangle_type.  All consecutive `P's, `R's, and 'M's are joined to
1808    build a pointer/reference type.  We snarf all these, plus the
1809    following <type>, all at once since we need to know whether we have
1810    a pointer to data or pointer to function to construct the right
1811    output syntax.  C++'s pointer syntax is hairy.  
1812
1813      <type> ::= P <type>
1814             ::= R <type>
1815             ::= <pointer-to-member-type>
1816
1817      <pointer-to-member-type> ::= M </class/ type> </member/ type>  */
1818
1819 static status_t
1820 demangle_type_ptr (dm)
1821      demangling_t dm;
1822 {
1823   char next;
1824   status_t status;
1825
1826   /* Collect pointer symbols into this string.  */
1827   dyn_string_t symbols = dyn_string_new (10);
1828
1829   DEMANGLE_TRACE ("type*", dm);
1830
1831   if (symbols == NULL)
1832     return STATUS_ALLOCATION_FAILED;
1833
1834   /* Scan forward, collecting pointers and references into symbols,
1835      until we hit something else.  Then emit the type.  */
1836   while (1)
1837     {
1838       next = peek_char (dm);
1839       if (next == 'P')
1840         {
1841           if (!dyn_string_append_char (symbols, '*'))
1842             return STATUS_ALLOCATION_FAILED;
1843           advance_char (dm);
1844         }
1845       else if (next == 'R')
1846         {
1847           if (!dyn_string_append_char (symbols, '&'))
1848             return STATUS_ALLOCATION_FAILED;
1849           advance_char (dm);
1850         }
1851       else if (next == 'M')
1852         {
1853           /* Pointer-to-member.  */
1854           dyn_string_t class_type;
1855
1856           /* Eat the 'M'.  */
1857           advance_char (dm);
1858
1859           /* Capture the type of which this is a pointer-to-member.  */
1860           RETURN_IF_ERROR (result_push (dm));
1861           RETURN_IF_ERROR (demangle_type (dm));
1862           class_type = (dyn_string_t) result_pop (dm);
1863
1864           /* Build the pointer-to-member notation.  It comes before
1865              other pointer and reference qualifiers -- */
1866           if (!dyn_string_prepend_cstr (symbols, "::*"))
1867             return STATUS_ALLOCATION_FAILED;
1868           if (!dyn_string_prepend (symbols, class_type))
1869             return STATUS_ALLOCATION_FAILED;
1870           dyn_string_delete (class_type);
1871
1872           if (peek_char (dm) == 'F')
1873             continue;
1874
1875           /* Demangle the type of the pointed-to member.  */
1876           status = demangle_type (dm);
1877           /* Make it pretty.  */
1878           if (STATUS_NO_ERROR (status))
1879             status = result_append_space (dm);
1880           /* Add the pointer-to-member syntax, and other pointer and
1881              reference symbols.  */
1882           if (STATUS_NO_ERROR (status))
1883             status = result_append_string (dm, symbols);
1884           /* Clean up.  */
1885           dyn_string_delete (symbols);
1886
1887           RETURN_IF_ERROR (status);
1888           return STATUS_OK;
1889         }
1890       else if (next == 'F')
1891         {
1892           /* Ooh, tricky, a pointer-to-function.  */
1893           int position = result_length (dm);
1894           status = result_append_char (dm, '(');
1895           if (STATUS_NO_ERROR (status))
1896             status = result_append_string (dm, symbols);
1897           if (STATUS_NO_ERROR (status))
1898             status = result_append_char (dm, ')');
1899           dyn_string_delete (symbols);
1900           RETURN_IF_ERROR (status);
1901
1902           RETURN_IF_ERROR (demangle_function_type (dm, position));
1903           return STATUS_OK;
1904         }
1905       else
1906         {
1907           /* No more pointe or reference tokens.  Finish up.  */
1908           status = demangle_type (dm);
1909
1910           if (STATUS_NO_ERROR (status))
1911             status = result_append_string (dm, symbols);
1912           dyn_string_delete (symbols);
1913           RETURN_IF_ERROR (status);
1914
1915           RETURN_IF_ERROR (status);
1916           return STATUS_OK;
1917         }
1918     }
1919 }
1920
1921 /* Demangles and emits a <type>.  
1922
1923     <type> ::= <builtin-type>
1924            ::= <function-type>
1925            ::= <class-enum-type>
1926            ::= <array-type>
1927            ::= <pointer-to-member-type>
1928            ::= <template-param>
1929            ::= <CV-qualifiers> <type>
1930            ::= P <type>   # pointer-to
1931            ::= R <type>   # reference-to
1932            ::= C <type>   # complex pair (C 2000)
1933            ::= G <type>   # imaginary (C 2000)
1934            ::= U <source-name> <type>     # vendor extended type qualifier
1935            ::= <substitution>  */
1936
1937 static status_t
1938 demangle_type (dm)
1939      demangling_t dm;
1940 {
1941   int start = substitution_start (dm);
1942   char peek = peek_char (dm);
1943   char peek_next;
1944   int template_p = 0;
1945   int special_std_substitution;
1946   int is_builtin_type = 0;
1947   template_arg_list_t old_arg_list = current_template_arg_list (dm);
1948   int template_parm = NOT_TEMPLATE_PARM;
1949
1950   DEMANGLE_TRACE ("type", dm);
1951
1952   /* A <class-enum-type> can start with a digit (a <source-name>), an
1953      N (a <nested-name>), or a Z (a <local-name>).  */
1954   if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
1955     RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p));
1956   else if (peek >= 'a' && peek <= 'z')
1957     {
1958       RETURN_IF_ERROR (demangle_builtin_type (dm));
1959       is_builtin_type = 1;
1960     }
1961   else
1962     switch (peek)
1963       {
1964       case 'r':
1965       case 'V':
1966       case 'K':
1967         {
1968           status_t status;
1969           dyn_string_t cv_qualifiers = dyn_string_new (24);
1970
1971           if (cv_qualifiers == NULL)
1972             return STATUS_ALLOCATION_FAILED;
1973
1974           demangle_CV_qualifiers (dm, cv_qualifiers);
1975
1976           /* If the qualifiers apply to a pointer or reference, they
1977              need to come after the whole qualified type.  */
1978           if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
1979             {
1980               status = demangle_type (dm);
1981               if (STATUS_NO_ERROR (status))
1982                 status = result_append_space (dm);
1983               if (STATUS_NO_ERROR (status))
1984                 status = result_append_string (dm, cv_qualifiers);
1985             }
1986           /* Otherwise, the qualifiers come first.  */
1987           else
1988             {
1989               status = result_append_string (dm, cv_qualifiers);
1990               if (STATUS_NO_ERROR (status))
1991                 status = result_append_space (dm);
1992               if (STATUS_NO_ERROR (status))
1993                 status = demangle_type (dm);
1994             }
1995
1996           dyn_string_delete (cv_qualifiers);
1997           RETURN_IF_ERROR (status);
1998         }
1999         break;
2000
2001       case 'F':
2002         return "Non-pointer or -reference function type.";
2003
2004       case 'A':
2005         RETURN_IF_ERROR (demangle_array_type (dm));
2006         break;
2007
2008       case 'T':
2009         RETURN_IF_ERROR (demangle_template_param (dm, &template_parm));
2010         break;
2011
2012       case 'S':
2013         /* First check if this is a special substitution.  If it is,
2014            this is a <class-enum-type>.  Special substitutions have a
2015            letter following the `S'; other substitutions have a digit
2016            or underscore.  */
2017         peek_next = peek_char_next (dm);
2018         if (IS_DIGIT (peek_next) || peek_next == '_')
2019           RETURN_IF_ERROR (demangle_substitution (dm, &template_p,
2020                                                   &special_std_substitution));
2021         else
2022           demangle_class_enum_type (dm, &template_p);
2023         break;
2024
2025       case 'P':
2026       case 'R':
2027       case 'M':
2028         RETURN_IF_ERROR (demangle_type_ptr (dm));
2029         break;
2030
2031       case 'C':
2032         /* A C99 complex type.  */
2033         RETURN_IF_ERROR (result_append (dm, "complex "));
2034         advance_char (dm);
2035         RETURN_IF_ERROR (demangle_type (dm));
2036         break;
2037
2038       case 'G':
2039         /* A C99 imaginary type.  */
2040         RETURN_IF_ERROR (result_append (dm, "imaginary "));
2041         advance_char (dm);
2042         RETURN_IF_ERROR (demangle_type (dm));
2043         break;
2044
2045       case 'U':
2046         /* Vendor extended type qualifier.  */
2047         advance_char (dm);
2048         RETURN_IF_ERROR (demangle_source_name (dm));
2049         RETURN_IF_ERROR (result_append_char (dm, ' '));
2050         RETURN_IF_ERROR (demangle_type (dm));
2051         break;
2052
2053       default:
2054         return "Unexpected character in <type>.";
2055       }
2056
2057   /* Unqualified builin types are not substitution candidates.  */
2058   if (!is_builtin_type)
2059     /* Add a new substitution for the type. If this type was a
2060        <template-param>, pass its index since from the point of
2061        substitutions, a <template-param> token is a substitution
2062        candidate distinct from the type that is substituted for it.  */
2063     RETURN_IF_ERROR (substitution_add (dm, start, template_p, template_parm));
2064
2065   /* Pop off template argument lists added during mangling of this
2066      type.  */
2067   pop_to_template_arg_list (dm, old_arg_list);
2068
2069   return STATUS_OK;
2070 }
2071
2072 /* C++ source names of builtin types, indexed by the mangled code
2073    letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc).  */
2074 static const char *const builtin_type_names[26] = 
2075 {
2076   "signed char",              /* a */
2077   "bool",                     /* b */
2078   "char",                     /* c */
2079   "double",                   /* d */
2080   "long double",              /* e */
2081   "float",                    /* f */
2082   "__float128",               /* g */
2083   "unsigned char",            /* h */
2084   "int",                      /* i */
2085   "unsigned",                 /* j */
2086   NULL,                       /* k */
2087   "long",                     /* l */
2088   "unsigned long",            /* m */
2089   "__int128",                 /* n */
2090   "unsigned __int128",        /* o */
2091   NULL,                       /* p */
2092   NULL,                       /* q */
2093   NULL,                       /* r */
2094   "short",                    /* s */
2095   "unsigned short",           /* t */
2096   NULL,                       /* u */
2097   "void",                     /* v */
2098   "wchar_t",                  /* w */
2099   "long long",                /* x */
2100   "unsigned long long",       /* y */
2101   "..."                       /* z */
2102 };
2103
2104 /* Demangles and emits a <builtin-type>.  
2105
2106     <builtin-type> ::= v  # void
2107                    ::= w  # wchar_t
2108                    ::= b  # bool
2109                    ::= c  # char
2110                    ::= a  # signed char
2111                    ::= h  # unsigned char
2112                    ::= s  # short
2113                    ::= t  # unsigned short
2114                    ::= i  # int
2115                    ::= j  # unsigned int
2116                    ::= l  # long
2117                    ::= m  # unsigned long
2118                    ::= x  # long long, __int64
2119                    ::= y  # unsigned long long, __int64
2120                    ::= n  # __int128
2121                    ::= o  # unsigned __int128
2122                    ::= f  # float
2123                    ::= d  # double
2124                    ::= e  # long double, __float80
2125                    ::= g  # __float128
2126                    ::= z  # ellipsis
2127                    ::= u <source-name>    # vendor extended type  */
2128
2129 static status_t
2130 demangle_builtin_type (dm)
2131      demangling_t dm;
2132 {
2133
2134   char code = peek_char (dm);
2135
2136   DEMANGLE_TRACE ("builtin-type", dm);
2137
2138   if (code == 'u')
2139     {
2140       advance_char (dm);
2141       RETURN_IF_ERROR (demangle_source_name (dm));
2142       return STATUS_OK;
2143     }
2144   else if (code >= 'a' && code <= 'z')
2145     {
2146       const char *type_name = builtin_type_names[code - 'a'];
2147       if (type_name == NULL)
2148         return "Unrecognized <builtin-type> code.";
2149
2150       RETURN_IF_ERROR (result_append (dm, type_name));
2151       advance_char (dm);
2152       return STATUS_OK;
2153     }
2154   else
2155     return "Non-alphabetic <builtin-type> code.";
2156 }
2157
2158 /* Demangles all consecutive CV-qualifiers (const, volatile, and
2159    restrict) at the current position.  The qualifiers are appended to
2160    QUALIFIERS.  Returns STATUS_OK.  */
2161
2162 static status_t
2163 demangle_CV_qualifiers (dm, qualifiers)
2164      demangling_t dm;
2165      dyn_string_t qualifiers;
2166 {
2167   DEMANGLE_TRACE ("CV-qualifiers", dm);
2168
2169   while (1)
2170     {
2171       switch (peek_char (dm))
2172         {
2173         case 'r':
2174           if (!dyn_string_append_space (qualifiers))
2175             return STATUS_ALLOCATION_FAILED;
2176           if (!dyn_string_append_cstr (qualifiers, "restrict"))
2177             return STATUS_ALLOCATION_FAILED;
2178           break;
2179
2180         case 'V':
2181           if (!dyn_string_append_space (qualifiers))
2182             return STATUS_ALLOCATION_FAILED;
2183           if (!dyn_string_append_cstr (qualifiers, "volatile"))
2184             return STATUS_ALLOCATION_FAILED;
2185           break;
2186
2187         case 'K':
2188           if (!dyn_string_append_space (qualifiers))
2189             return STATUS_ALLOCATION_FAILED;
2190           if (!dyn_string_append_cstr (qualifiers, "const"))
2191             return STATUS_ALLOCATION_FAILED;
2192           break;
2193
2194         default:
2195           return STATUS_OK;
2196         }
2197
2198       advance_char (dm);
2199     }
2200 }
2201
2202 /* Demangles and emits a <function-type> FUNCTION_NAME_POS is the
2203    position in the result string of the start of the function
2204    identifier, at which the function's return type will be inserted.  
2205
2206     <function-type> ::= F [Y] <bare-function-type> E  */
2207
2208 static status_t
2209 demangle_function_type (dm, function_name_pos)
2210      demangling_t dm;
2211      int function_name_pos;
2212 {
2213   DEMANGLE_TRACE ("function-type", dm);
2214   RETURN_IF_ERROR (demangle_char (dm, 'F'));  
2215   if (peek_char (dm) == 'Y')
2216     {
2217       /* Indicate this function has C linkage if in verbose mode.  */
2218       if (flag_verbose)
2219         RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] "));
2220       advance_char (dm);
2221     }
2222   RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
2223   RETURN_IF_ERROR (demangle_char (dm, 'E'));
2224   return STATUS_OK;
2225 }
2226
2227 /* Demangles and emits a <bare-function-type>.  RETURN_TYPE_POS is the
2228    position in the result string at which the function return type
2229    should be inserted.  If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
2230    function's return type is assumed not to be encoded.  
2231
2232     <bare-function-type> ::= <signature type>+  */
2233
2234 static status_t
2235 demangle_bare_function_type (dm, return_type_pos)
2236      demangling_t dm;
2237      int return_type_pos;
2238 {
2239   /* Sequence is the index of the current function parameter, counting
2240      from zero.  The value -1 denotes the return type.  */
2241   int sequence = 
2242     (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
2243
2244   DEMANGLE_TRACE ("bare-function-type", dm);
2245
2246   RETURN_IF_ERROR (result_append_char (dm, '('));
2247   while (!end_of_name_p (dm) && peek_char (dm) != 'E')
2248     {
2249       if (sequence == -1)
2250         /* We're decoding the function's return type.  */
2251         {
2252           dyn_string_t return_type;
2253           status_t status = STATUS_OK;
2254
2255           /* Decode the return type off to the side.  */
2256           RETURN_IF_ERROR (result_push (dm));
2257           RETURN_IF_ERROR (demangle_type (dm));
2258           return_type = (dyn_string_t) result_pop (dm);
2259
2260           /* Add a space to the end of the type.  Insert the return
2261              type where we've been asked to. */
2262           if (!dyn_string_append_space (return_type) 
2263               || !dyn_string_insert (result_string (dm), return_type_pos, 
2264                                      return_type))
2265             status = STATUS_ALLOCATION_FAILED;
2266
2267           dyn_string_delete (return_type);
2268           RETURN_IF_ERROR (status);
2269         }
2270       else 
2271         {
2272           /* Skip `void' parameter types.  One should only occur as
2273              the only type in a parameter list; in that case, we want
2274              to print `foo ()' instead of `foo (void)'.  */
2275           if (peek_char (dm) == 'v')
2276             {
2277               /* Consume the v.  */
2278               advance_char (dm);
2279               continue;
2280             }
2281           /* Separate parameter types by commas.  */
2282           if (sequence > 0)
2283             RETURN_IF_ERROR (result_append (dm, ", "));
2284           /* Demangle the type.  */
2285           RETURN_IF_ERROR (demangle_type (dm));
2286         }
2287
2288       ++sequence;
2289     }
2290   RETURN_IF_ERROR (result_append_char (dm, ')'));
2291
2292   return STATUS_OK;
2293 }
2294
2295 /* Demangles and emits a <class-enum-type>.  *TEMPLATE_P is set to
2296    non-zero if the type is a template-id, zero otherwise.  
2297
2298     <class-enum-type> ::= <name>  */
2299
2300 static status_t
2301 demangle_class_enum_type (dm, template_p)
2302      demangling_t dm;
2303      int *template_p;
2304 {
2305   DEMANGLE_TRACE ("class-enum-type", dm);
2306
2307   RETURN_IF_ERROR (demangle_name (dm, template_p));
2308   return STATUS_OK;
2309 }
2310
2311 /* Demangles and emits an <array-type>.  
2312
2313     <array-type> ::= A [<dimension number>] _ <element type>  */
2314
2315 static status_t
2316 demangle_array_type (dm)
2317      demangling_t dm;
2318 {
2319   status_t status;
2320   dyn_string_t array_size = dyn_string_new (10);
2321
2322   if (array_size == NULL)
2323     return STATUS_ALLOCATION_FAILED;
2324
2325   status = demangle_char (dm, 'A');
2326
2327   /* Demangle the array size into array_size.  */
2328   if (STATUS_NO_ERROR (status))
2329     status = demangle_number_literally (dm, array_size, 10, 0);
2330
2331   /* Demangle the base type of the array.  */
2332   if (STATUS_NO_ERROR (status))
2333     status = demangle_char (dm, '_');
2334   if (STATUS_NO_ERROR (status))
2335     status = demangle_type (dm);
2336
2337   /* Emit the array dimension syntax.  */
2338   if (STATUS_NO_ERROR (status))
2339     status = result_append_char (dm, '[');
2340   if (STATUS_NO_ERROR (status))
2341     status = result_append_string (dm, array_size);
2342   if (STATUS_NO_ERROR (status))
2343     status = result_append_char (dm, ']');
2344   dyn_string_delete (array_size);
2345   
2346   RETURN_IF_ERROR (status);
2347
2348   return STATUS_OK;
2349 }
2350
2351 /* Demangles and emits a <template-param>.  The zero-indexed position
2352    in the parameter list is placed in *TEMPLATE_PARM_NUMBER.  
2353
2354     <template-param> ::= T_       # first template parameter
2355                      ::= T <parameter-2 number> _  */
2356
2357 static status_t
2358 demangle_template_param (dm, template_parm_number)
2359      demangling_t dm;
2360      int *template_parm_number;
2361 {
2362   int parm_number;
2363   template_arg_list_t current_arg_list = current_template_arg_list (dm);
2364   string_list_t arg;
2365
2366   DEMANGLE_TRACE ("template-param", dm);
2367
2368   /* Make sure there is a template argmust list in which to look up
2369      this parameter reference.  */
2370   if (current_arg_list == NULL)
2371     return "Template parameter outside of template.";
2372
2373   RETURN_IF_ERROR (demangle_char (dm, 'T'));
2374   if (peek_char (dm) == '_')
2375     parm_number = 0;
2376   else
2377     {
2378       RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
2379       ++parm_number;
2380     }
2381   RETURN_IF_ERROR (demangle_char (dm, '_'));
2382
2383   arg = template_arg_list_get_arg (current_arg_list, parm_number);
2384   if (arg == NULL)
2385     /* parm_number exceeded the number of arguments in the current
2386        template argument list.  */
2387     return "Template parameter number out of bounds.";
2388   RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2389
2390   if (peek_char (dm) == 'I')
2391     RETURN_IF_ERROR (demangle_template_args (dm));
2392
2393   *template_parm_number = parm_number;
2394   return STATUS_OK;
2395 }
2396
2397 /* Demangles and emits a <template-args>.  
2398
2399     <template-args> ::= I <template-arg>+ E  */
2400
2401 static status_t
2402 demangle_template_args (dm)
2403      demangling_t dm;
2404 {
2405   int first = 1;
2406   dyn_string_t old_last_source_name;
2407   template_arg_list_t arg_list = template_arg_list_new ();
2408
2409   if (arg_list == NULL)
2410     return STATUS_ALLOCATION_FAILED;
2411
2412   /* Preserve the most recently demangled source name.  */
2413   old_last_source_name = dm->last_source_name;
2414   dm->last_source_name = dyn_string_new (0);
2415
2416   DEMANGLE_TRACE ("template-args", dm);
2417
2418   if (dm->last_source_name == NULL)
2419     return STATUS_ALLOCATION_FAILED;
2420
2421   RETURN_IF_ERROR (demangle_char (dm, 'I'));
2422   RETURN_IF_ERROR (result_append_char (dm, '<'));
2423   do
2424     {
2425       string_list_t arg;
2426
2427       if (first)
2428         first = 0;
2429       else
2430         RETURN_IF_ERROR (result_append (dm, ", "));
2431
2432       /* Capture the template arg.  */
2433       RETURN_IF_ERROR (result_push (dm));
2434       RETURN_IF_ERROR (demangle_template_arg (dm));
2435       arg = result_pop (dm);
2436
2437       /* Emit it in the demangled name.  */
2438       RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
2439
2440       /* Save it for use in expanding <template-param>s.  */
2441       template_arg_list_add_arg (arg_list, arg);
2442     }
2443   while (peek_char (dm) != 'E');
2444   /* Append the '>'.  */
2445   RETURN_IF_ERROR (result_close_template_list (dm));
2446
2447   /* Consume the 'E'.  */
2448   advance_char (dm);
2449
2450   /* Restore the most recent demangled source name.  */
2451   dyn_string_delete (dm->last_source_name);
2452   dm->last_source_name = old_last_source_name;
2453
2454   /* Push the list onto the top of the stack of template argument
2455      lists, so that arguments from it are used from now on when
2456      expanding <template-param>s.  */
2457   push_template_arg_list (dm, arg_list);
2458
2459   return STATUS_OK;
2460 }
2461
2462 /* This function, which does not correspond to a production in the
2463    mangling spec, handles the `literal' production for both
2464    <template-arg> and <expr-primary>.  It does not expect or consume
2465    the initial `L' or final `E'.  The demangling is given by:
2466
2467      <literal> ::= <type> </value/ number>
2468
2469    and the emitted output is `(type)number'.  */
2470
2471 static status_t
2472 demangle_literal (dm)
2473      demangling_t dm;
2474 {
2475   char peek = peek_char (dm);
2476   dyn_string_t value_string;
2477   status_t status;
2478
2479   DEMANGLE_TRACE ("literal", dm);
2480
2481   if (!flag_verbose && peek >= 'a' && peek <= 'z')
2482     {
2483       /* If not in verbose mode and this is a builtin type, see if we
2484          can produce simpler numerical output.  In particular, for
2485          integer types shorter than `long', just write the number
2486          without type information; for bools, write `true' or `false'.
2487          Other refinements could be made here too.  */
2488
2489       /* This constant string is used to map from <builtin-type> codes
2490          (26 letters of the alphabet) to codes that determine how the 
2491          value will be displayed.  The codes are:
2492            b: display as bool
2493            i: display as int
2494            l: display as long
2495          A space means the value will be represented using cast
2496          notation. */
2497       static const char *const code_map = "ibi    iii ll     ii  i  ";
2498
2499       char code = code_map[peek - 'a'];
2500       /* FIXME: Implement demangling of floats and doubles.  */
2501       if (code == 'u')
2502         return STATUS_UNIMPLEMENTED;
2503       if (code == 'b')
2504         {
2505           /* It's a boolean.  */
2506           char value;
2507
2508           /* Consume the b.  */
2509           advance_char (dm);
2510           /* Look at the next character.  It should be 0 or 1,
2511              corresponding to false or true, respectively.  */
2512           value = peek_char (dm);
2513           if (value == '0')
2514             RETURN_IF_ERROR (result_append (dm, "false"));
2515           else if (value == '1')
2516             RETURN_IF_ERROR (result_append (dm, "true"));
2517           else
2518             return "Unrecognized bool constant.";
2519           /* Consume the 0 or 1.  */
2520           advance_char (dm);
2521           return STATUS_OK;
2522         }
2523       else if (code == 'i' || code == 'l')
2524         {
2525           /* It's an integer or long.  */
2526
2527           /* Consume the type character.  */
2528           advance_char (dm);
2529
2530           /* Demangle the number and write it out.  */
2531           value_string = dyn_string_new (0);
2532           status = demangle_number_literally (dm, value_string, 10, 1);
2533           if (STATUS_NO_ERROR (status))
2534             status = result_append_string (dm, value_string);
2535           /* For long integers, append an l.  */
2536           if (code == 'l' && STATUS_NO_ERROR (status))
2537             status = result_append_char (dm, code);
2538           dyn_string_delete (value_string);
2539
2540           RETURN_IF_ERROR (status);
2541           return STATUS_OK;
2542         }
2543       /* ...else code == ' ', so fall through to represent this
2544          literal's type explicitly using cast syntax.  */
2545     }
2546
2547   RETURN_IF_ERROR (result_append_char (dm, '('));
2548   RETURN_IF_ERROR (demangle_type (dm));
2549   RETURN_IF_ERROR (result_append_char (dm, ')'));
2550
2551   value_string = dyn_string_new (0);
2552   if (value_string == NULL)
2553     return STATUS_ALLOCATION_FAILED;
2554
2555   status = demangle_number_literally (dm, value_string, 10, 1);
2556   if (STATUS_NO_ERROR (status))
2557     status = result_append_string (dm, value_string);
2558   dyn_string_delete (value_string);
2559   RETURN_IF_ERROR (status);
2560
2561   return STATUS_OK;
2562 }
2563
2564 /* Demangles and emits a <template-arg>.  
2565
2566     <template-arg> ::= <type>                     # type
2567                    ::= L <type> <value number> E  # literal
2568                    ::= LZ <encoding> E            # external name
2569                    ::= X <expression> E           # expression  */
2570
2571 static status_t
2572 demangle_template_arg (dm)
2573      demangling_t dm;
2574 {
2575   DEMANGLE_TRACE ("template-arg", dm);
2576
2577   switch (peek_char (dm))
2578     {
2579     case 'L':
2580       advance_char (dm);
2581
2582       if (peek_char (dm) == 'Z')
2583         {
2584           /* External name.  */
2585           advance_char (dm);
2586           /* FIXME: Standard is contradictory here.  */
2587           RETURN_IF_ERROR (demangle_encoding (dm));
2588         }
2589       else
2590         RETURN_IF_ERROR (demangle_literal (dm));
2591       RETURN_IF_ERROR (demangle_char (dm, 'E'));
2592       break;
2593
2594     case 'X':
2595       /* Expression.  */
2596       advance_char (dm);
2597       RETURN_IF_ERROR (demangle_expression (dm));
2598       break;
2599
2600     default:
2601       RETURN_IF_ERROR (demangle_type (dm));
2602       break;
2603     }
2604
2605   return STATUS_OK;
2606 }
2607
2608 /* Demangles and emits an <expression>.
2609
2610     <expression> ::= <unary operator-name> <expression>
2611                  ::= <binary operator-name> <expression> <expression>
2612                  ::= <expr-primary>  
2613                  ::= <scope-expression>  */
2614
2615 static status_t
2616 demangle_expression (dm)
2617      demangling_t dm;
2618 {
2619   char peek = peek_char (dm);
2620
2621   DEMANGLE_TRACE ("expression", dm);
2622
2623   if (peek == 'L' || peek == 'T')
2624     RETURN_IF_ERROR (demangle_expr_primary (dm));
2625   else if (peek == 's' && peek_char_next (dm) == 'r')
2626     RETURN_IF_ERROR (demangle_scope_expression (dm));
2627   else
2628     /* An operator expression.  */
2629     {
2630       int num_args;
2631       status_t status = STATUS_OK;
2632       dyn_string_t operator_name;
2633
2634       /* We have an operator name.  Since we want to output binary
2635          operations in infix notation, capture the operator name
2636          first.  */
2637       RETURN_IF_ERROR (result_push (dm));
2638       RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args));
2639       operator_name = (dyn_string_t) result_pop (dm);
2640
2641       /* If it's binary, do an operand first.  */
2642       if (num_args > 1)
2643         {
2644           status = result_append_char (dm, '(');
2645           if (STATUS_NO_ERROR (status))
2646             status = demangle_expression (dm);
2647           if (STATUS_NO_ERROR (status))
2648             status = result_append_char (dm, ')');
2649         }
2650
2651       /* Emit the operator.  */  
2652       if (STATUS_NO_ERROR (status))
2653         status = result_append_string (dm, operator_name);
2654       dyn_string_delete (operator_name);
2655       RETURN_IF_ERROR (status);
2656       
2657       /* Emit its second (if binary) or only (if unary) operand.  */
2658       RETURN_IF_ERROR (result_append_char (dm, '('));
2659       RETURN_IF_ERROR (demangle_expression (dm));
2660       RETURN_IF_ERROR (result_append_char (dm, ')'));
2661
2662       /* The ternary operator takes a third operand.  */
2663       if (num_args == 3)
2664         {
2665           RETURN_IF_ERROR (result_append (dm, ":("));
2666           RETURN_IF_ERROR (demangle_expression (dm));
2667           RETURN_IF_ERROR (result_append_char (dm, ')'));
2668         }
2669     }
2670
2671   return STATUS_OK;
2672 }
2673
2674 /* Demangles and emits a <scope-expression>.  
2675
2676     <scope-expression> ::= sr <qualifying type> <source-name>
2677                        ::= sr <qualifying type> <encoding>  */
2678
2679 static status_t
2680 demangle_scope_expression (dm)
2681      demangling_t dm;
2682 {
2683   RETURN_IF_ERROR (demangle_char (dm, 's'));
2684   RETURN_IF_ERROR (demangle_char (dm, 'r'));
2685   RETURN_IF_ERROR (demangle_type (dm));
2686   RETURN_IF_ERROR (result_append (dm, "::"));
2687   RETURN_IF_ERROR (demangle_encoding (dm));
2688   return STATUS_OK;
2689 }
2690
2691 /* Demangles and emits an <expr-primary>.  
2692
2693     <expr-primary> ::= <template-param>
2694                    ::= L <type> <value number> E  # literal
2695                    ::= L <mangled-name> E         # external name  */
2696
2697 static status_t
2698 demangle_expr_primary (dm)
2699      demangling_t dm;
2700 {
2701   char peek = peek_char (dm);
2702   int unused;
2703
2704   DEMANGLE_TRACE ("expr-primary", dm);
2705
2706   if (peek == 'T')
2707     RETURN_IF_ERROR (demangle_template_param (dm, &unused));
2708   else if (peek == 'L')
2709     {
2710       /* Consume the `L'.  */
2711       advance_char (dm);
2712       peek = peek_char (dm);
2713
2714       if (peek == '_')
2715         RETURN_IF_ERROR (demangle_mangled_name (dm));
2716       else
2717         RETURN_IF_ERROR (demangle_literal (dm));
2718
2719       RETURN_IF_ERROR (demangle_char (dm, 'E'));
2720     }
2721   else
2722     return STATUS_ERROR;
2723
2724   return STATUS_OK;
2725 }
2726
2727 /* Demangles and emits a <substitution>.  Sets *TEMPLATE_P to non-zero
2728    if the substitution is the name of a template, zero otherwise.  If
2729    the substitution token is St, which corresponds to the `::std::'
2730    namespace and can appear in a non-nested name, sets
2731    *SPECIAL_STD_SUBSTITUTION to non-zero; zero otherwise.  
2732
2733      <substitution> ::= S <seq-id> _
2734                     ::= S_
2735
2736                     ::= St   # ::std::
2737                     ::= Sa   # ::std::allocator
2738                     ::= Sb   # ::std::basic_string
2739                     ::= Ss   # ::std::basic_string<char,
2740                                                    ::std::char_traits<char>,
2741                                                    ::std::allocator<char> >
2742                     ::= Si   # ::std::basic_istream<char,  
2743                                                     std::char_traits<char> >
2744                     ::= So   # ::std::basic_ostream<char,  
2745                                                     std::char_traits<char> >
2746                     ::= Sd   # ::std::basic_iostream<char, 
2747                                                      std::char_traits<char> >
2748 */
2749
2750 static status_t
2751 demangle_substitution (dm, template_p, special_std_substitution)
2752      demangling_t dm;
2753      int *template_p;
2754      int *special_std_substitution;
2755 {
2756   int seq_id;
2757   int peek;
2758   dyn_string_t text;
2759
2760   DEMANGLE_TRACE ("substitution", dm);
2761
2762   RETURN_IF_ERROR (demangle_char (dm, 'S'));
2763   *special_std_substitution = 0;
2764
2765   /* Scan the substitution sequence index.  A missing number denotes
2766      the first index.  */
2767   peek = peek_char (dm);
2768   if (peek == '_')
2769     seq_id = -1;
2770   /* If the following character is 0-9 or a capital letter, interpret
2771      the sequence up to the next underscore as a base-36 substitution
2772      index.  */
2773   else if (IS_DIGIT ((unsigned char) peek) 
2774            || (peek >= 'A' && peek <= 'Z'))
2775     RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
2776   else 
2777     {
2778       const char *new_last_source_name = NULL;
2779
2780       switch (peek)
2781         {
2782         case 't':
2783           RETURN_IF_ERROR (result_append (dm, "std"));
2784           *special_std_substitution = 1;
2785           break;
2786
2787         case 'a':
2788           RETURN_IF_ERROR (result_append (dm, "std::allocator"));
2789           new_last_source_name = "allocator";
2790           *template_p = 1;
2791           break;
2792
2793         case 'b':
2794           RETURN_IF_ERROR (result_append (dm, "std::basic_string"));
2795           new_last_source_name = "basic_string";
2796           *template_p = 1;
2797           break;
2798           
2799         case 's':
2800           if (!flag_verbose)
2801             {
2802               RETURN_IF_ERROR (result_append (dm, "std::string"));
2803               new_last_source_name = "string";
2804             }
2805           else
2806             {
2807               RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
2808               new_last_source_name = "basic_string";
2809             }
2810           *template_p = 0;
2811           break;
2812
2813         case 'i':
2814           if (!flag_verbose)
2815             {
2816               RETURN_IF_ERROR (result_append (dm, "std::istream"));
2817               new_last_source_name = "istream";
2818             }
2819           else
2820             {
2821               RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >"));
2822               new_last_source_name = "basic_istream";
2823             }
2824           *template_p = 0;
2825           break;
2826
2827         case 'o':
2828           if (!flag_verbose)
2829             {
2830               RETURN_IF_ERROR (result_append (dm, "std::ostream"));
2831               new_last_source_name = "ostream";
2832             }
2833           else
2834             {
2835               RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >"));
2836               new_last_source_name = "basic_ostream";
2837             }
2838           *template_p = 0;
2839           break;
2840
2841         case 'd':
2842           if (!flag_verbose) 
2843             {
2844               RETURN_IF_ERROR (result_append (dm, "std::iostream"));
2845               new_last_source_name = "iostream";
2846             }
2847           else
2848             {
2849               RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >"));
2850               new_last_source_name = "basic_iostream";
2851             }
2852           *template_p = 0;
2853           break;
2854
2855         default:
2856           return "Unrecognized <substitution>.";
2857         }
2858       
2859       /* Consume the character we just processed.  */
2860       advance_char (dm);
2861
2862       if (new_last_source_name != NULL)
2863         {
2864           if (!dyn_string_copy_cstr (dm->last_source_name, 
2865                                      new_last_source_name))
2866             return STATUS_ALLOCATION_FAILED;
2867         }
2868
2869       return STATUS_OK;
2870     }
2871
2872   /* Look up the substitution text.  Since `S_' is the most recent
2873      substitution, `S0_' is the second-most-recent, etc., shift the
2874      numbering by one.  */
2875   text = substitution_get (dm, seq_id + 1, template_p);
2876   if (text == NULL) 
2877     return "Substitution number out of range.";
2878
2879   /* Emit the substitution text.  */
2880   RETURN_IF_ERROR (result_append_string (dm, text));
2881
2882   RETURN_IF_ERROR (demangle_char (dm, '_'));
2883   return STATUS_OK;
2884 }
2885
2886 /* Demangles and emits a <local-name>.  
2887
2888     <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2889                  := Z <function encoding> E s [<discriminator>]  */
2890
2891 static status_t
2892 demangle_local_name (dm)
2893      demangling_t dm;
2894 {
2895   DEMANGLE_TRACE ("local-name", dm);
2896
2897   RETURN_IF_ERROR (demangle_char (dm, 'Z'));
2898   RETURN_IF_ERROR (demangle_encoding (dm));
2899   RETURN_IF_ERROR (demangle_char (dm, 'E'));
2900   RETURN_IF_ERROR (result_append (dm, "'s "));
2901
2902   if (peek_char (dm) == 's')
2903     {
2904       /* Local character string literal.  */
2905       RETURN_IF_ERROR (result_append (dm, "string literal"));
2906       /* Consume the s.  */
2907       advance_char (dm);
2908       RETURN_IF_ERROR (demangle_discriminator (dm, 0));
2909     }
2910   else
2911     {
2912       int unused;
2913       RETURN_IF_ERROR (result_append (dm, "local "));
2914       /* Local name for some other entity.  Demangle its name.  */
2915       RETURN_IF_ERROR (demangle_name (dm, &unused));
2916       RETURN_IF_ERROR (demangle_discriminator (dm, 1));
2917      }
2918
2919    return STATUS_OK;
2920  }
2921
2922  /* Optimonally demangles and emits a <discriminator>.  If there is no
2923     <discriminator> at the current position in the mangled string, the
2924     descriminator is assumed to be zero.  Emit the discriminator number
2925     in parentheses, unless SUPPRESS_FIRST is non-zero and the
2926     discriminator is zero.  
2927
2928      <discriminator> ::= _ <number>  */
2929
2930 static status_t
2931 demangle_discriminator (dm, suppress_first)
2932      demangling_t dm;
2933      int suppress_first;
2934 {
2935   /* Output for <discriminator>s to the demangled name is completely
2936      supressed if not in verbose mode.  */
2937
2938   if (peek_char (dm) == '_')
2939     {
2940       /* Consume the underscore.  */
2941       advance_char (dm);
2942       if (flag_verbose)
2943         RETURN_IF_ERROR (result_append (dm, " [#"));
2944       /* Check if there's a number following the underscore.  */
2945       if (IS_DIGIT ((unsigned char) peek_char (dm)))
2946         {
2947           int discriminator;
2948           /* Demangle the number.  */
2949           RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
2950           if (flag_verbose)
2951             /* Write the discriminator.  The mangled number is two
2952                less than the discriminator ordinal, counting from
2953                zero.  */
2954             RETURN_IF_ERROR (int_to_dyn_string (discriminator + 2, 
2955                                                 (dyn_string_t) dm->result));
2956         }
2957       else
2958         {
2959           if (flag_verbose)
2960             /* A missing digit correspond to one.  */
2961             RETURN_IF_ERROR (result_append_char (dm, '1'));
2962         }
2963       if (flag_verbose)
2964         RETURN_IF_ERROR (result_append_char (dm, ']'));
2965     }
2966   else if (!suppress_first)
2967     {
2968       if (flag_verbose)
2969         RETURN_IF_ERROR (result_append (dm, " [#0]"));
2970     }
2971
2972   return STATUS_OK;
2973 }
2974
2975 /* Demangle NAME into RESULT, which must be an initialized
2976    dyn_string_t.  On success, returns STATUS_OK.  On failure, returns
2977    an error message, and the contents of RESULT are unchanged.  */
2978
2979 static status_t
2980 cp_demangle (name, result)
2981      const char *name;
2982      dyn_string_t result;
2983 {
2984   status_t status;
2985   int length = strlen (name);
2986
2987   if (length > 2 && name[0] == '_' && name[1] == 'Z')
2988     {
2989       demangling_t dm = demangling_new (name);
2990       if (dm == NULL)
2991         return STATUS_ALLOCATION_FAILED;
2992
2993       status = result_push (dm);
2994       if (status != STATUS_OK)
2995         {
2996           demangling_delete (dm);
2997           return status;
2998         }
2999
3000       status = demangle_mangled_name (dm);
3001       if (STATUS_NO_ERROR (status))
3002         {
3003           dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3004           if (!dyn_string_copy (result, demangled))
3005             return STATUS_ALLOCATION_FAILED;
3006           dyn_string_delete (demangled);
3007         }
3008       
3009       demangling_delete (dm);
3010     }
3011   else
3012     {
3013       /* It's evidently not a mangled C++ name.  It could be the name
3014          of something with C linkage, though, so just copy NAME into
3015          RESULT.  */
3016       if (!dyn_string_copy_cstr (result, name))
3017         return STATUS_ALLOCATION_FAILED;
3018       status = STATUS_OK;
3019     }
3020
3021   return status; 
3022 }
3023
3024 /* Demangle TYPE_NAME into RESULT, which must be an initialized
3025    dyn_string_t.  On success, returns STATUS_OK.  On failiure, returns
3026    an error message, and the contents of RESULT are unchanged.  */
3027
3028 static status_t
3029 cp_demangle_type (type_name, result)
3030      const char* type_name;
3031      dyn_string_t result;
3032 {
3033   status_t status;
3034   demangling_t dm = demangling_new (type_name);
3035   
3036   if (dm == NULL)
3037     return STATUS_ALLOCATION_FAILED;
3038
3039   /* Demangle the type name.  The demangled name is stored in dm.  */
3040   status = result_push (dm);
3041   if (status != STATUS_OK)
3042     {
3043       demangling_delete (dm);
3044       return status;
3045     }
3046
3047   status = demangle_type (dm);
3048
3049   if (STATUS_NO_ERROR (status))
3050     {
3051       /* The demangling succeeded.  Pop the result out of dm and copy
3052          it into RESULT.  */
3053       dyn_string_t demangled = (dyn_string_t) result_pop (dm);
3054       if (!dyn_string_copy (result, demangled))
3055         return STATUS_ALLOCATION_FAILED;
3056       dyn_string_delete (demangled);
3057     }
3058
3059   /* Clean up.  */
3060   demangling_delete (dm);
3061
3062   return status;
3063 }
3064
3065
3066 #ifdef IN_LIBGCC2
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 */