OSDN Git Service

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