OSDN Git Service

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