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