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