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