OSDN Git Service

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