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