OSDN Git Service

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