OSDN Git Service

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