PR 75964: Invalid integer ABS handling in simplify-rtx.c
[official-gcc.git] / libiberty / cplus-dem.c
blob81c17a3207d8d69e7d3c34e5f7f53fbb54876ddc
1 /* Demangler for GNU C++
2 Copyright (C) 1989-2017 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
5 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
7 This file is part of the libiberty library.
8 Libiberty is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 In addition to the permissions in the GNU Library General Public
14 License, the Free Software Foundation gives you unlimited permission
15 to link the compiled version of this file into combinations with other
16 programs, and to distribute those combinations without any restriction
17 coming from the use of this file. (The Library Public License
18 restrictions do apply in other respects; for example, they cover
19 modification of the file, and distribution when not linked into a
20 combined executable.)
22 Libiberty is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Library General Public License for more details.
27 You should have received a copy of the GNU Library General Public
28 License along with libiberty; see the file COPYING.LIB. If
29 not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
30 Boston, MA 02110-1301, USA. */
32 /* This file exports two functions; cplus_mangle_opname and cplus_demangle.
34 This file imports xmalloc and xrealloc, which are like malloc and
35 realloc except that they generate a fatal error if there is no
36 available memory. */
38 /* This file lives in both GCC and libiberty. When making changes, please
39 try not to break either. */
41 #ifdef HAVE_CONFIG_H
42 #include "config.h"
43 #endif
45 #include "safe-ctype.h"
47 #include <sys/types.h>
48 #include <string.h>
49 #include <stdio.h>
51 #ifdef HAVE_STDLIB_H
52 #include <stdlib.h>
53 #else
54 void * malloc ();
55 void * realloc ();
56 #endif
58 #ifdef HAVE_LIMITS_H
59 #include <limits.h>
60 #endif
61 #ifndef INT_MAX
62 # define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
63 #endif
65 #include <demangle.h>
66 #undef CURRENT_DEMANGLING_STYLE
67 #define CURRENT_DEMANGLING_STYLE work->options
69 #include "libiberty.h"
71 #define min(X,Y) (((X) < (Y)) ? (X) : (Y))
73 /* A value at least one greater than the maximum number of characters
74 that will be output when using the `%d' format with `printf'. */
75 #define INTBUF_SIZE 32
77 extern void fancy_abort (void) ATTRIBUTE_NORETURN;
79 /* In order to allow a single demangler executable to demangle strings
80 using various common values of CPLUS_MARKER, as well as any specific
81 one set at compile time, we maintain a string containing all the
82 commonly used ones, and check to see if the marker we are looking for
83 is in that string. CPLUS_MARKER is usually '$' on systems where the
84 assembler can deal with that. Where the assembler can't, it's usually
85 '.' (but on many systems '.' is used for other things). We put the
86 current defined CPLUS_MARKER first (which defaults to '$'), followed
87 by the next most common value, followed by an explicit '$' in case
88 the value of CPLUS_MARKER is not '$'.
90 We could avoid this if we could just get g++ to tell us what the actual
91 cplus marker character is as part of the debug information, perhaps by
92 ensuring that it is the character that terminates the gcc<n>_compiled
93 marker symbol (FIXME). */
95 #if !defined (CPLUS_MARKER)
96 #define CPLUS_MARKER '$'
97 #endif
99 enum demangling_styles current_demangling_style = auto_demangling;
101 static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
103 static char char_str[2] = { '\000', '\000' };
105 void
106 set_cplus_marker_for_demangling (int ch)
108 cplus_markers[0] = ch;
111 typedef struct string /* Beware: these aren't required to be */
112 { /* '\0' terminated. */
113 char *b; /* pointer to start of string */
114 char *p; /* pointer after last character */
115 char *e; /* pointer after end of allocated space */
116 } string;
118 /* Stuff that is shared between sub-routines.
119 Using a shared structure allows cplus_demangle to be reentrant. */
121 struct work_stuff
123 int options;
124 char **typevec;
125 char **ktypevec;
126 char **btypevec;
127 int numk;
128 int numb;
129 int ksize;
130 int bsize;
131 int ntypes;
132 int typevec_size;
133 int constructor;
134 int destructor;
135 int static_type; /* A static member function */
136 int temp_start; /* index in demangled to start of template args */
137 int type_quals; /* The type qualifiers. */
138 int dllimported; /* Symbol imported from a PE DLL */
139 char **tmpl_argvec; /* Template function arguments. */
140 int ntmpl_args; /* The number of template function arguments. */
141 int forgetting_types; /* Nonzero if we are not remembering the types
142 we see. */
143 string* previous_argument; /* The last function argument demangled. */
144 int nrepeats; /* The number of times to repeat the previous
145 argument. */
146 int *proctypevec; /* Indices of currently processed remembered typevecs. */
147 int proctypevec_size;
148 int nproctypes;
151 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
152 #define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
154 static const struct optable
156 const char *const in;
157 const char *const out;
158 const int flags;
159 } optable[] = {
160 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
161 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
162 {"new", " new", 0}, /* old (1.91, and 1.x) */
163 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
164 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
165 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
166 {"as", "=", DMGL_ANSI}, /* ansi */
167 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
168 {"eq", "==", DMGL_ANSI}, /* old, ansi */
169 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
170 {"gt", ">", DMGL_ANSI}, /* old, ansi */
171 {"le", "<=", DMGL_ANSI}, /* old, ansi */
172 {"lt", "<", DMGL_ANSI}, /* old, ansi */
173 {"plus", "+", 0}, /* old */
174 {"pl", "+", DMGL_ANSI}, /* ansi */
175 {"apl", "+=", DMGL_ANSI}, /* ansi */
176 {"minus", "-", 0}, /* old */
177 {"mi", "-", DMGL_ANSI}, /* ansi */
178 {"ami", "-=", DMGL_ANSI}, /* ansi */
179 {"mult", "*", 0}, /* old */
180 {"ml", "*", DMGL_ANSI}, /* ansi */
181 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
182 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
183 {"convert", "+", 0}, /* old (unary +) */
184 {"negate", "-", 0}, /* old (unary -) */
185 {"trunc_mod", "%", 0}, /* old */
186 {"md", "%", DMGL_ANSI}, /* ansi */
187 {"amd", "%=", DMGL_ANSI}, /* ansi */
188 {"trunc_div", "/", 0}, /* old */
189 {"dv", "/", DMGL_ANSI}, /* ansi */
190 {"adv", "/=", DMGL_ANSI}, /* ansi */
191 {"truth_andif", "&&", 0}, /* old */
192 {"aa", "&&", DMGL_ANSI}, /* ansi */
193 {"truth_orif", "||", 0}, /* old */
194 {"oo", "||", DMGL_ANSI}, /* ansi */
195 {"truth_not", "!", 0}, /* old */
196 {"nt", "!", DMGL_ANSI}, /* ansi */
197 {"postincrement","++", 0}, /* old */
198 {"pp", "++", DMGL_ANSI}, /* ansi */
199 {"postdecrement","--", 0}, /* old */
200 {"mm", "--", DMGL_ANSI}, /* ansi */
201 {"bit_ior", "|", 0}, /* old */
202 {"or", "|", DMGL_ANSI}, /* ansi */
203 {"aor", "|=", DMGL_ANSI}, /* ansi */
204 {"bit_xor", "^", 0}, /* old */
205 {"er", "^", DMGL_ANSI}, /* ansi */
206 {"aer", "^=", DMGL_ANSI}, /* ansi */
207 {"bit_and", "&", 0}, /* old */
208 {"ad", "&", DMGL_ANSI}, /* ansi */
209 {"aad", "&=", DMGL_ANSI}, /* ansi */
210 {"bit_not", "~", 0}, /* old */
211 {"co", "~", DMGL_ANSI}, /* ansi */
212 {"call", "()", 0}, /* old */
213 {"cl", "()", DMGL_ANSI}, /* ansi */
214 {"alshift", "<<", 0}, /* old */
215 {"ls", "<<", DMGL_ANSI}, /* ansi */
216 {"als", "<<=", DMGL_ANSI}, /* ansi */
217 {"arshift", ">>", 0}, /* old */
218 {"rs", ">>", DMGL_ANSI}, /* ansi */
219 {"ars", ">>=", DMGL_ANSI}, /* ansi */
220 {"component", "->", 0}, /* old */
221 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
222 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
223 {"indirect", "*", 0}, /* old */
224 {"method_call", "->()", 0}, /* old */
225 {"addr", "&", 0}, /* old (unary &) */
226 {"array", "[]", 0}, /* old */
227 {"vc", "[]", DMGL_ANSI}, /* ansi */
228 {"compound", ", ", 0}, /* old */
229 {"cm", ", ", DMGL_ANSI}, /* ansi */
230 {"cond", "?:", 0}, /* old */
231 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
232 {"max", ">?", 0}, /* old */
233 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
234 {"min", "<?", 0}, /* old */
235 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
236 {"nop", "", 0}, /* old (for operator=) */
237 {"rm", "->*", DMGL_ANSI}, /* ansi */
238 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
241 /* These values are used to indicate the various type varieties.
242 They are all non-zero so that they can be used as `success'
243 values. */
244 typedef enum type_kind_t
246 tk_none,
247 tk_pointer,
248 tk_reference,
249 tk_rvalue_reference,
250 tk_integral,
251 tk_bool,
252 tk_char,
253 tk_real
254 } type_kind_t;
256 const struct demangler_engine libiberty_demanglers[] =
259 NO_DEMANGLING_STYLE_STRING,
260 no_demangling,
261 "Demangling disabled"
265 AUTO_DEMANGLING_STYLE_STRING,
266 auto_demangling,
267 "Automatic selection based on executable"
271 GNU_DEMANGLING_STYLE_STRING,
272 gnu_demangling,
273 "GNU (g++) style demangling"
277 LUCID_DEMANGLING_STYLE_STRING,
278 lucid_demangling,
279 "Lucid (lcc) style demangling"
283 ARM_DEMANGLING_STYLE_STRING,
284 arm_demangling,
285 "ARM style demangling"
289 HP_DEMANGLING_STYLE_STRING,
290 hp_demangling,
291 "HP (aCC) style demangling"
295 EDG_DEMANGLING_STYLE_STRING,
296 edg_demangling,
297 "EDG style demangling"
301 GNU_V3_DEMANGLING_STYLE_STRING,
302 gnu_v3_demangling,
303 "GNU (g++) V3 ABI-style demangling"
307 JAVA_DEMANGLING_STYLE_STRING,
308 java_demangling,
309 "Java style demangling"
313 GNAT_DEMANGLING_STYLE_STRING,
314 gnat_demangling,
315 "GNAT style demangling"
319 DLANG_DEMANGLING_STYLE_STRING,
320 dlang_demangling,
321 "DLANG style demangling"
325 RUST_DEMANGLING_STYLE_STRING,
326 rust_demangling,
327 "Rust style demangling"
331 NULL, unknown_demangling, NULL
335 #define STRING_EMPTY(str) ((str) -> b == (str) -> p)
336 #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
337 string_append(str, " ");}
338 #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
340 /* The scope separator appropriate for the language being demangled. */
342 #define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
344 #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
345 #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
347 /* Prototypes for local functions */
349 static void delete_work_stuff (struct work_stuff *);
351 static void delete_non_B_K_work_stuff (struct work_stuff *);
353 static char *mop_up (struct work_stuff *, string *, int);
355 static void squangle_mop_up (struct work_stuff *);
357 static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *);
359 #if 0
360 static int
361 demangle_method_args (struct work_stuff *, const char **, string *);
362 #endif
364 static char *
365 internal_cplus_demangle (struct work_stuff *, const char *);
367 static int
368 demangle_template_template_parm (struct work_stuff *work,
369 const char **, string *);
371 static int
372 demangle_template (struct work_stuff *work, const char **, string *,
373 string *, int, int);
375 static int
376 arm_pt (struct work_stuff *, const char *, int, const char **,
377 const char **);
379 static int
380 demangle_class_name (struct work_stuff *, const char **, string *);
382 static int
383 demangle_qualified (struct work_stuff *, const char **, string *,
384 int, int);
386 static int demangle_class (struct work_stuff *, const char **, string *);
388 static int demangle_fund_type (struct work_stuff *, const char **, string *);
390 static int demangle_signature (struct work_stuff *, const char **, string *);
392 static int demangle_prefix (struct work_stuff *, const char **, string *);
394 static int gnu_special (struct work_stuff *, const char **, string *);
396 static int arm_special (const char **, string *);
398 static void string_need (string *, int);
400 static void string_delete (string *);
402 static void
403 string_init (string *);
405 static void string_clear (string *);
407 #if 0
408 static int string_empty (string *);
409 #endif
411 static void string_append (string *, const char *);
413 static void string_appends (string *, string *);
415 static void string_appendn (string *, const char *, int);
417 static void string_prepend (string *, const char *);
419 static void string_prependn (string *, const char *, int);
421 static void string_append_template_idx (string *, int);
423 static int get_count (const char **, int *);
425 static int consume_count (const char **);
427 static int consume_count_with_underscores (const char**);
429 static int demangle_args (struct work_stuff *, const char **, string *);
431 static int demangle_nested_args (struct work_stuff*, const char**, string*);
433 static int do_type (struct work_stuff *, const char **, string *);
435 static int do_arg (struct work_stuff *, const char **, string *);
437 static int
438 demangle_function_name (struct work_stuff *, const char **, string *,
439 const char *);
441 static int
442 iterate_demangle_function (struct work_stuff *,
443 const char **, string *, const char *);
445 static void remember_type (struct work_stuff *, const char *, int);
447 static void push_processed_type (struct work_stuff *, int);
449 static void pop_processed_type (struct work_stuff *);
451 static void remember_Btype (struct work_stuff *, const char *, int, int);
453 static int register_Btype (struct work_stuff *);
455 static void remember_Ktype (struct work_stuff *, const char *, int);
457 static void forget_types (struct work_stuff *);
459 static void forget_B_and_K_types (struct work_stuff *);
461 static void string_prepends (string *, string *);
463 static int
464 demangle_template_value_parm (struct work_stuff*, const char**,
465 string*, type_kind_t);
467 static int
468 do_hpacc_template_const_value (struct work_stuff *, const char **, string *);
470 static int
471 do_hpacc_template_literal (struct work_stuff *, const char **, string *);
473 static int snarf_numeric_literal (const char **, string *);
475 /* There is a TYPE_QUAL value for each type qualifier. They can be
476 combined by bitwise-or to form the complete set of qualifiers for a
477 type. */
479 #define TYPE_UNQUALIFIED 0x0
480 #define TYPE_QUAL_CONST 0x1
481 #define TYPE_QUAL_VOLATILE 0x2
482 #define TYPE_QUAL_RESTRICT 0x4
484 static int code_for_qualifier (int);
486 static const char* qualifier_string (int);
488 static const char* demangle_qualifier (int);
490 static int demangle_expression (struct work_stuff *, const char **, string *,
491 type_kind_t);
493 static int
494 demangle_integral_value (struct work_stuff *, const char **, string *);
496 static int
497 demangle_real_value (struct work_stuff *, const char **, string *);
499 static void
500 demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
502 static void
503 recursively_demangle (struct work_stuff *, const char **, string *, int);
505 /* Translate count to integer, consuming tokens in the process.
506 Conversion terminates on the first non-digit character.
508 Trying to consume something that isn't a count results in no
509 consumption of input and a return of -1.
511 Overflow consumes the rest of the digits, and returns -1. */
513 static int
514 consume_count (const char **type)
516 int count = 0;
518 if (! ISDIGIT ((unsigned char)**type))
519 return -1;
521 while (ISDIGIT ((unsigned char)**type))
523 const int digit = **type - '0';
524 /* Check for overflow. */
525 if (count > ((INT_MAX - digit) / 10))
527 while (ISDIGIT ((unsigned char) **type))
528 (*type)++;
529 return -1;
532 count *= 10;
533 count += digit;
534 (*type)++;
537 if (count < 0)
538 count = -1;
540 return (count);
544 /* Like consume_count, but for counts that are preceded and followed
545 by '_' if they are greater than 10. Also, -1 is returned for
546 failure, since 0 can be a valid value. */
548 static int
549 consume_count_with_underscores (const char **mangled)
551 int idx;
553 if (**mangled == '_')
555 (*mangled)++;
556 if (!ISDIGIT ((unsigned char)**mangled))
557 return -1;
559 idx = consume_count (mangled);
560 if (**mangled != '_')
561 /* The trailing underscore was missing. */
562 return -1;
564 (*mangled)++;
566 else
568 if (**mangled < '0' || **mangled > '9')
569 return -1;
571 idx = **mangled - '0';
572 (*mangled)++;
575 return idx;
578 /* C is the code for a type-qualifier. Return the TYPE_QUAL
579 corresponding to this qualifier. */
581 static int
582 code_for_qualifier (int c)
584 switch (c)
586 case 'C':
587 return TYPE_QUAL_CONST;
589 case 'V':
590 return TYPE_QUAL_VOLATILE;
592 case 'u':
593 return TYPE_QUAL_RESTRICT;
595 default:
596 break;
599 /* C was an invalid qualifier. */
600 abort ();
603 /* Return the string corresponding to the qualifiers given by
604 TYPE_QUALS. */
606 static const char*
607 qualifier_string (int type_quals)
609 switch (type_quals)
611 case TYPE_UNQUALIFIED:
612 return "";
614 case TYPE_QUAL_CONST:
615 return "const";
617 case TYPE_QUAL_VOLATILE:
618 return "volatile";
620 case TYPE_QUAL_RESTRICT:
621 return "__restrict";
623 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
624 return "const volatile";
626 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
627 return "const __restrict";
629 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
630 return "volatile __restrict";
632 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
633 return "const volatile __restrict";
635 default:
636 break;
639 /* TYPE_QUALS was an invalid qualifier set. */
640 abort ();
643 /* C is the code for a type-qualifier. Return the string
644 corresponding to this qualifier. This function should only be
645 called with a valid qualifier code. */
647 static const char*
648 demangle_qualifier (int c)
650 return qualifier_string (code_for_qualifier (c));
654 cplus_demangle_opname (const char *opname, char *result, int options)
656 int len, len1, ret;
657 string type;
658 struct work_stuff work[1];
659 const char *tem;
661 len = strlen(opname);
662 result[0] = '\0';
663 ret = 0;
664 memset ((char *) work, 0, sizeof (work));
665 work->options = options;
667 if (opname[0] == '_' && opname[1] == '_'
668 && opname[2] == 'o' && opname[3] == 'p')
670 /* ANSI. */
671 /* type conversion operator. */
672 tem = opname + 4;
673 if (do_type (work, &tem, &type))
675 strcat (result, "operator ");
676 strncat (result, type.b, type.p - type.b);
677 string_delete (&type);
678 ret = 1;
681 else if (opname[0] == '_' && opname[1] == '_'
682 && ISLOWER((unsigned char)opname[2])
683 && ISLOWER((unsigned char)opname[3]))
685 if (opname[4] == '\0')
687 /* Operator. */
688 size_t i;
689 for (i = 0; i < ARRAY_SIZE (optable); i++)
691 if (strlen (optable[i].in) == 2
692 && memcmp (optable[i].in, opname + 2, 2) == 0)
694 strcat (result, "operator");
695 strcat (result, optable[i].out);
696 ret = 1;
697 break;
701 else
703 if (opname[2] == 'a' && opname[5] == '\0')
705 /* Assignment. */
706 size_t i;
707 for (i = 0; i < ARRAY_SIZE (optable); i++)
709 if (strlen (optable[i].in) == 3
710 && memcmp (optable[i].in, opname + 2, 3) == 0)
712 strcat (result, "operator");
713 strcat (result, optable[i].out);
714 ret = 1;
715 break;
721 else if (len >= 3
722 && opname[0] == 'o'
723 && opname[1] == 'p'
724 && strchr (cplus_markers, opname[2]) != NULL)
726 /* see if it's an assignment expression */
727 if (len >= 10 /* op$assign_ */
728 && memcmp (opname + 3, "assign_", 7) == 0)
730 size_t i;
731 for (i = 0; i < ARRAY_SIZE (optable); i++)
733 len1 = len - 10;
734 if ((int) strlen (optable[i].in) == len1
735 && memcmp (optable[i].in, opname + 10, len1) == 0)
737 strcat (result, "operator");
738 strcat (result, optable[i].out);
739 strcat (result, "=");
740 ret = 1;
741 break;
745 else
747 size_t i;
748 for (i = 0; i < ARRAY_SIZE (optable); i++)
750 len1 = len - 3;
751 if ((int) strlen (optable[i].in) == len1
752 && memcmp (optable[i].in, opname + 3, len1) == 0)
754 strcat (result, "operator");
755 strcat (result, optable[i].out);
756 ret = 1;
757 break;
762 else if (len >= 5 && memcmp (opname, "type", 4) == 0
763 && strchr (cplus_markers, opname[4]) != NULL)
765 /* type conversion operator */
766 tem = opname + 5;
767 if (do_type (work, &tem, &type))
769 strcat (result, "operator ");
770 strncat (result, type.b, type.p - type.b);
771 string_delete (&type);
772 ret = 1;
775 squangle_mop_up (work);
776 return ret;
780 /* Takes operator name as e.g. "++" and returns mangled
781 operator name (e.g. "postincrement_expr"), or NULL if not found.
783 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
784 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
786 const char *
787 cplus_mangle_opname (const char *opname, int options)
789 size_t i;
790 int len;
792 len = strlen (opname);
793 for (i = 0; i < ARRAY_SIZE (optable); i++)
795 if ((int) strlen (optable[i].out) == len
796 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
797 && memcmp (optable[i].out, opname, len) == 0)
798 return optable[i].in;
800 return (0);
803 /* Add a routine to set the demangling style to be sure it is valid and
804 allow for any demangler initialization that maybe necessary. */
806 enum demangling_styles
807 cplus_demangle_set_style (enum demangling_styles style)
809 const struct demangler_engine *demangler = libiberty_demanglers;
811 for (; demangler->demangling_style != unknown_demangling; ++demangler)
812 if (style == demangler->demangling_style)
814 current_demangling_style = style;
815 return current_demangling_style;
818 return unknown_demangling;
821 /* Do string name to style translation */
823 enum demangling_styles
824 cplus_demangle_name_to_style (const char *name)
826 const struct demangler_engine *demangler = libiberty_demanglers;
828 for (; demangler->demangling_style != unknown_demangling; ++demangler)
829 if (strcmp (name, demangler->demangling_style_name) == 0)
830 return demangler->demangling_style;
832 return unknown_demangling;
835 /* char *cplus_demangle (const char *mangled, int options)
837 If MANGLED is a mangled function name produced by GNU C++, then
838 a pointer to a @code{malloc}ed string giving a C++ representation
839 of the name will be returned; otherwise NULL will be returned.
840 It is the caller's responsibility to free the string which
841 is returned.
843 The OPTIONS arg may contain one or more of the following bits:
845 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
846 included.
847 DMGL_PARAMS Function parameters are included.
849 For example,
851 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
852 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
853 cplus_demangle ("foo__1Ai", 0) => "A::foo"
855 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
856 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
857 cplus_demangle ("foo__1Afe", 0) => "A::foo"
859 Note that any leading underscores, or other such characters prepended by
860 the compilation system, are presumed to have already been stripped from
861 MANGLED. */
863 char *
864 cplus_demangle (const char *mangled, int options)
866 char *ret;
867 struct work_stuff work[1];
869 if (current_demangling_style == no_demangling)
870 return xstrdup (mangled);
872 memset ((char *) work, 0, sizeof (work));
873 work->options = options;
874 if ((work->options & DMGL_STYLE_MASK) == 0)
875 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
877 /* The V3 ABI demangling is implemented elsewhere. */
878 if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
880 ret = cplus_demangle_v3 (mangled, work->options);
881 if (GNU_V3_DEMANGLING)
882 return ret;
884 if (ret)
886 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
887 The subtitutions are always smaller, so do in place changes. */
888 if (rust_is_mangled (ret))
889 rust_demangle_sym (ret);
890 else if (RUST_DEMANGLING)
892 free (ret);
893 ret = NULL;
897 if (ret || RUST_DEMANGLING)
898 return ret;
901 if (JAVA_DEMANGLING)
903 ret = java_demangle_v3 (mangled);
904 if (ret)
905 return ret;
908 if (GNAT_DEMANGLING)
909 return ada_demangle (mangled, options);
911 if (DLANG_DEMANGLING)
913 ret = dlang_demangle (mangled, options);
914 if (ret)
915 return ret;
918 ret = internal_cplus_demangle (work, mangled);
919 squangle_mop_up (work);
920 return (ret);
923 char *
924 rust_demangle (const char *mangled, int options)
926 /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
927 char *ret = cplus_demangle_v3 (mangled, options);
929 /* The Rust subtitutions are always smaller, so do in place changes. */
930 if (ret != NULL)
932 if (rust_is_mangled (ret))
933 rust_demangle_sym (ret);
934 else
936 free (ret);
937 ret = NULL;
941 return ret;
944 /* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
946 char *
947 ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
949 int len0;
950 const char* p;
951 char *d;
952 char *demangled = NULL;
954 /* Discard leading _ada_, which is used for library level subprograms. */
955 if (strncmp (mangled, "_ada_", 5) == 0)
956 mangled += 5;
958 /* All ada unit names are lower-case. */
959 if (!ISLOWER (mangled[0]))
960 goto unknown;
962 /* Most of the demangling will trivially remove chars. Operator names
963 may add one char but because they are always preceeded by '__' which is
964 replaced by '.', they eventually never expand the size.
965 A few special names such as '___elabs' add a few chars (at most 7), but
966 they occur only once. */
967 len0 = strlen (mangled) + 7 + 1;
968 demangled = XNEWVEC (char, len0);
970 d = demangled;
971 p = mangled;
972 while (1)
974 /* An entity names is expected. */
975 if (ISLOWER (*p))
977 /* An identifier, which is always lower case. */
979 *d++ = *p++;
980 while (ISLOWER(*p) || ISDIGIT (*p)
981 || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
983 else if (p[0] == 'O')
985 /* An operator name. */
986 static const char * const operators[][2] =
987 {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
988 {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
989 {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="},
990 {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"},
991 {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"},
992 {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"},
993 {"Oexpon", "**"}, {NULL, NULL}};
994 int k;
996 for (k = 0; operators[k][0] != NULL; k++)
998 size_t slen = strlen (operators[k][0]);
999 if (strncmp (p, operators[k][0], slen) == 0)
1001 p += slen;
1002 slen = strlen (operators[k][1]);
1003 *d++ = '"';
1004 memcpy (d, operators[k][1], slen);
1005 d += slen;
1006 *d++ = '"';
1007 break;
1010 /* Operator not found. */
1011 if (operators[k][0] == NULL)
1012 goto unknown;
1014 else
1016 /* Not a GNAT encoding. */
1017 goto unknown;
1020 /* The name can be directly followed by some uppercase letters. */
1021 if (p[0] == 'T' && p[1] == 'K')
1023 /* Task stuff. */
1024 if (p[2] == 'B' && p[3] == 0)
1026 /* Subprogram for task body. */
1027 break;
1029 else if (p[2] == '_' && p[3] == '_')
1031 /* Inner declarations in a task. */
1032 p += 4;
1033 *d++ = '.';
1034 continue;
1036 else
1037 goto unknown;
1039 if (p[0] == 'E' && p[1] == 0)
1041 /* Exception name. */
1042 goto unknown;
1044 if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
1046 /* Protected type subprogram. */
1047 break;
1049 if ((*p == 'N' || *p == 'S') && p[1] == 0)
1051 /* Enumerated type name table. */
1052 goto unknown;
1054 if (p[0] == 'X')
1056 /* Body nested. */
1057 p++;
1058 while (p[0] == 'n' || p[0] == 'b')
1059 p++;
1061 if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
1063 /* Stream operations. */
1064 const char *name;
1065 switch (p[1])
1067 case 'R':
1068 name = "'Read";
1069 break;
1070 case 'W':
1071 name = "'Write";
1072 break;
1073 case 'I':
1074 name = "'Input";
1075 break;
1076 case 'O':
1077 name = "'Output";
1078 break;
1079 default:
1080 goto unknown;
1082 p += 2;
1083 strcpy (d, name);
1084 d += strlen (name);
1086 else if (p[0] == 'D')
1088 /* Controlled type operation. */
1089 const char *name;
1090 switch (p[1])
1092 case 'F':
1093 name = ".Finalize";
1094 break;
1095 case 'A':
1096 name = ".Adjust";
1097 break;
1098 default:
1099 goto unknown;
1101 strcpy (d, name);
1102 d += strlen (name);
1103 break;
1106 if (p[0] == '_')
1108 /* Separator. */
1109 if (p[1] == '_')
1111 /* Standard separator. Handled first. */
1112 p += 2;
1114 if (ISDIGIT (*p))
1116 /* Overloading number. */
1118 p++;
1119 while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
1120 if (*p == 'X')
1122 p++;
1123 while (p[0] == 'n' || p[0] == 'b')
1124 p++;
1127 else if (p[0] == '_' && p[1] != '_')
1129 /* Special names. */
1130 static const char * const special[][2] = {
1131 { "_elabb", "'Elab_Body" },
1132 { "_elabs", "'Elab_Spec" },
1133 { "_size", "'Size" },
1134 { "_alignment", "'Alignment" },
1135 { "_assign", ".\":=\"" },
1136 { NULL, NULL }
1138 int k;
1140 for (k = 0; special[k][0] != NULL; k++)
1142 size_t slen = strlen (special[k][0]);
1143 if (strncmp (p, special[k][0], slen) == 0)
1145 p += slen;
1146 slen = strlen (special[k][1]);
1147 memcpy (d, special[k][1], slen);
1148 d += slen;
1149 break;
1152 if (special[k][0] != NULL)
1153 break;
1154 else
1155 goto unknown;
1157 else
1159 *d++ = '.';
1160 continue;
1163 else if (p[1] == 'B' || p[1] == 'E')
1165 /* Entry Body or barrier Evaluation. */
1166 p += 2;
1167 while (ISDIGIT (*p))
1168 p++;
1169 if (p[0] == 's' && p[1] == 0)
1170 break;
1171 else
1172 goto unknown;
1174 else
1175 goto unknown;
1178 if (p[0] == '.' && ISDIGIT (p[1]))
1180 /* Nested subprogram. */
1181 p += 2;
1182 while (ISDIGIT (*p))
1183 p++;
1185 if (*p == 0)
1187 /* End of mangled name. */
1188 break;
1190 else
1191 goto unknown;
1193 *d = 0;
1194 return demangled;
1196 unknown:
1197 XDELETEVEC (demangled);
1198 len0 = strlen (mangled);
1199 demangled = XNEWVEC (char, len0 + 3);
1201 if (mangled[0] == '<')
1202 strcpy (demangled, mangled);
1203 else
1204 sprintf (demangled, "<%s>", mangled);
1206 return demangled;
1209 /* This function performs most of what cplus_demangle use to do, but
1210 to be able to demangle a name with a B, K or n code, we need to
1211 have a longer term memory of what types have been seen. The original
1212 now initializes and cleans up the squangle code info, while internal
1213 calls go directly to this routine to avoid resetting that info. */
1215 static char *
1216 internal_cplus_demangle (struct work_stuff *work, const char *mangled)
1219 string decl;
1220 int success = 0;
1221 char *demangled = NULL;
1222 int s1, s2, s3, s4;
1223 s1 = work->constructor;
1224 s2 = work->destructor;
1225 s3 = work->static_type;
1226 s4 = work->type_quals;
1227 work->constructor = work->destructor = 0;
1228 work->type_quals = TYPE_UNQUALIFIED;
1229 work->dllimported = 0;
1231 if ((mangled != NULL) && (*mangled != '\0'))
1233 string_init (&decl);
1235 /* First check to see if gnu style demangling is active and if the
1236 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1237 recognize one of the gnu special forms rather than looking for a
1238 standard prefix. In particular, don't worry about whether there
1239 is a "__" string in the mangled string. Consider "_$_5__foo" for
1240 example. */
1242 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1244 success = gnu_special (work, &mangled, &decl);
1245 if (!success)
1247 delete_work_stuff (work);
1248 string_delete (&decl);
1251 if (!success)
1253 success = demangle_prefix (work, &mangled, &decl);
1255 if (success && (*mangled != '\0'))
1257 success = demangle_signature (work, &mangled, &decl);
1259 if (work->constructor == 2)
1261 string_prepend (&decl, "global constructors keyed to ");
1262 work->constructor = 0;
1264 else if (work->destructor == 2)
1266 string_prepend (&decl, "global destructors keyed to ");
1267 work->destructor = 0;
1269 else if (work->dllimported == 1)
1271 string_prepend (&decl, "import stub for ");
1272 work->dllimported = 0;
1274 demangled = mop_up (work, &decl, success);
1276 work->constructor = s1;
1277 work->destructor = s2;
1278 work->static_type = s3;
1279 work->type_quals = s4;
1280 return demangled;
1284 /* Clear out and squangling related storage */
1285 static void
1286 squangle_mop_up (struct work_stuff *work)
1288 /* clean up the B and K type mangling types. */
1289 forget_B_and_K_types (work);
1290 if (work -> btypevec != NULL)
1292 free ((char *) work -> btypevec);
1293 work->btypevec = NULL;
1294 work->bsize = 0;
1296 if (work -> ktypevec != NULL)
1298 free ((char *) work -> ktypevec);
1299 work->ktypevec = NULL;
1300 work->ksize = 0;
1305 /* Copy the work state and storage. */
1307 static void
1308 work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from)
1310 int i;
1312 delete_work_stuff (to);
1314 /* Shallow-copy scalars. */
1315 memcpy (to, from, sizeof (*to));
1317 /* Deep-copy dynamic storage. */
1318 if (from->typevec_size)
1319 to->typevec = XNEWVEC (char *, from->typevec_size);
1321 for (i = 0; i < from->ntypes; i++)
1323 int len = strlen (from->typevec[i]) + 1;
1325 to->typevec[i] = XNEWVEC (char, len);
1326 memcpy (to->typevec[i], from->typevec[i], len);
1329 if (from->ksize)
1330 to->ktypevec = XNEWVEC (char *, from->ksize);
1332 for (i = 0; i < from->numk; i++)
1334 int len = strlen (from->ktypevec[i]) + 1;
1336 to->ktypevec[i] = XNEWVEC (char, len);
1337 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1340 if (from->bsize)
1341 to->btypevec = XNEWVEC (char *, from->bsize);
1343 for (i = 0; i < from->numb; i++)
1345 int len = strlen (from->btypevec[i]) + 1;
1347 to->btypevec[i] = XNEWVEC (char , len);
1348 memcpy (to->btypevec[i], from->btypevec[i], len);
1351 if (from->proctypevec)
1352 to->proctypevec =
1353 XDUPVEC (int, from->proctypevec, from->proctypevec_size);
1355 if (from->ntmpl_args)
1356 to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args);
1358 for (i = 0; i < from->ntmpl_args; i++)
1360 int len = strlen (from->tmpl_argvec[i]) + 1;
1362 to->tmpl_argvec[i] = XNEWVEC (char, len);
1363 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1366 if (from->previous_argument)
1368 to->previous_argument = XNEW (string);
1369 string_init (to->previous_argument);
1370 string_appends (to->previous_argument, from->previous_argument);
1375 /* Delete dynamic stuff in work_stuff that is not to be re-used. */
1377 static void
1378 delete_non_B_K_work_stuff (struct work_stuff *work)
1380 /* Discard the remembered types, if any. */
1382 forget_types (work);
1383 if (work->typevec != NULL)
1385 free ((char *) work->typevec);
1386 work->typevec = NULL;
1387 work->typevec_size = 0;
1389 if (work->proctypevec != NULL)
1391 free (work->proctypevec);
1392 work->proctypevec = NULL;
1393 work->proctypevec_size = 0;
1395 if (work->tmpl_argvec)
1397 int i;
1399 for (i = 0; i < work->ntmpl_args; i++)
1400 free ((char*) work->tmpl_argvec[i]);
1402 free ((char*) work->tmpl_argvec);
1403 work->tmpl_argvec = NULL;
1405 if (work->previous_argument)
1407 string_delete (work->previous_argument);
1408 free ((char*) work->previous_argument);
1409 work->previous_argument = NULL;
1414 /* Delete all dynamic storage in work_stuff. */
1415 static void
1416 delete_work_stuff (struct work_stuff *work)
1418 delete_non_B_K_work_stuff (work);
1419 squangle_mop_up (work);
1423 /* Clear out any mangled storage */
1425 static char *
1426 mop_up (struct work_stuff *work, string *declp, int success)
1428 char *demangled = NULL;
1430 delete_non_B_K_work_stuff (work);
1432 /* If demangling was successful, ensure that the demangled string is null
1433 terminated and return it. Otherwise, free the demangling decl. */
1435 if (!success)
1437 string_delete (declp);
1439 else
1441 string_appendn (declp, "", 1);
1442 demangled = declp->b;
1444 return (demangled);
1449 LOCAL FUNCTION
1451 demangle_signature -- demangle the signature part of a mangled name
1453 SYNOPSIS
1455 static int
1456 demangle_signature (struct work_stuff *work, const char **mangled,
1457 string *declp);
1459 DESCRIPTION
1461 Consume and demangle the signature portion of the mangled name.
1463 DECLP is the string where demangled output is being built. At
1464 entry it contains the demangled root name from the mangled name
1465 prefix. I.E. either a demangled operator name or the root function
1466 name. In some special cases, it may contain nothing.
1468 *MANGLED points to the current unconsumed location in the mangled
1469 name. As tokens are consumed and demangling is performed, the
1470 pointer is updated to continuously point at the next token to
1471 be consumed.
1473 Demangling GNU style mangled names is nasty because there is no
1474 explicit token that marks the start of the outermost function
1475 argument list. */
1477 static int
1478 demangle_signature (struct work_stuff *work,
1479 const char **mangled, string *declp)
1481 int success = 1;
1482 int func_done = 0;
1483 int expect_func = 0;
1484 int expect_return_type = 0;
1485 const char *oldmangled = NULL;
1486 string trawname;
1487 string tname;
1489 while (success && (**mangled != '\0'))
1491 switch (**mangled)
1493 case 'Q':
1494 oldmangled = *mangled;
1495 success = demangle_qualified (work, mangled, declp, 1, 0);
1496 if (success)
1497 remember_type (work, oldmangled, *mangled - oldmangled);
1498 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1499 expect_func = 1;
1500 oldmangled = NULL;
1501 break;
1503 case 'K':
1504 oldmangled = *mangled;
1505 success = demangle_qualified (work, mangled, declp, 1, 0);
1506 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1508 expect_func = 1;
1510 oldmangled = NULL;
1511 break;
1513 case 'S':
1514 /* Static member function */
1515 if (oldmangled == NULL)
1517 oldmangled = *mangled;
1519 (*mangled)++;
1520 work -> static_type = 1;
1521 break;
1523 case 'C':
1524 case 'V':
1525 case 'u':
1526 work->type_quals |= code_for_qualifier (**mangled);
1528 /* a qualified member function */
1529 if (oldmangled == NULL)
1530 oldmangled = *mangled;
1531 (*mangled)++;
1532 break;
1534 case 'L':
1535 /* Local class name follows after "Lnnn_" */
1536 if (HP_DEMANGLING)
1538 while (**mangled && (**mangled != '_'))
1539 (*mangled)++;
1540 if (!**mangled)
1541 success = 0;
1542 else
1543 (*mangled)++;
1545 else
1546 success = 0;
1547 break;
1549 case '0': case '1': case '2': case '3': case '4':
1550 case '5': case '6': case '7': case '8': case '9':
1551 if (oldmangled == NULL)
1553 oldmangled = *mangled;
1555 work->temp_start = -1; /* uppermost call to demangle_class */
1556 success = demangle_class (work, mangled, declp);
1557 if (success)
1559 remember_type (work, oldmangled, *mangled - oldmangled);
1561 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
1563 /* EDG and others will have the "F", so we let the loop cycle
1564 if we are looking at one. */
1565 if (**mangled != 'F')
1566 expect_func = 1;
1568 oldmangled = NULL;
1569 break;
1571 case 'B':
1573 string s;
1574 success = do_type (work, mangled, &s);
1575 if (success)
1577 string_append (&s, SCOPE_STRING (work));
1578 string_prepends (declp, &s);
1579 string_delete (&s);
1581 oldmangled = NULL;
1582 expect_func = 1;
1584 break;
1586 case 'F':
1587 /* Function */
1588 /* ARM/HP style demangling includes a specific 'F' character after
1589 the class name. For GNU style, it is just implied. So we can
1590 safely just consume any 'F' at this point and be compatible
1591 with either style. */
1593 oldmangled = NULL;
1594 func_done = 1;
1595 (*mangled)++;
1597 /* For lucid/ARM/HP style we have to forget any types we might
1598 have remembered up to this point, since they were not argument
1599 types. GNU style considers all types seen as available for
1600 back references. See comment in demangle_args() */
1602 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
1604 forget_types (work);
1606 success = demangle_args (work, mangled, declp);
1607 /* After picking off the function args, we expect to either
1608 find the function return type (preceded by an '_') or the
1609 end of the string. */
1610 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1612 ++(*mangled);
1613 /* At this level, we do not care about the return type. */
1614 success = do_type (work, mangled, &tname);
1615 string_delete (&tname);
1618 break;
1620 case 't':
1621 /* G++ Template */
1622 string_init(&trawname);
1623 string_init(&tname);
1624 if (oldmangled == NULL)
1626 oldmangled = *mangled;
1628 success = demangle_template (work, mangled, &tname,
1629 &trawname, 1, 1);
1630 if (success)
1632 remember_type (work, oldmangled, *mangled - oldmangled);
1634 string_append (&tname, SCOPE_STRING (work));
1636 string_prepends(declp, &tname);
1637 if (work -> destructor & 1)
1639 string_prepend (&trawname, "~");
1640 string_appends (declp, &trawname);
1641 work->destructor -= 1;
1643 if ((work->constructor & 1) || (work->destructor & 1))
1645 string_appends (declp, &trawname);
1646 work->constructor -= 1;
1648 string_delete(&trawname);
1649 string_delete(&tname);
1650 oldmangled = NULL;
1651 expect_func = 1;
1652 break;
1654 case '_':
1655 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
1657 /* Read the return type. */
1658 string return_type;
1660 (*mangled)++;
1661 success = do_type (work, mangled, &return_type);
1662 APPEND_BLANK (&return_type);
1664 string_prepends (declp, &return_type);
1665 string_delete (&return_type);
1666 break;
1668 else
1669 /* At the outermost level, we cannot have a return type specified,
1670 so if we run into another '_' at this point we are dealing with
1671 a mangled name that is either bogus, or has been mangled by
1672 some algorithm we don't know how to deal with. So just
1673 reject the entire demangling. */
1674 /* However, "_nnn" is an expected suffix for alternate entry point
1675 numbered nnn for a function, with HP aCC, so skip over that
1676 without reporting failure. pai/1997-09-04 */
1677 if (HP_DEMANGLING)
1679 (*mangled)++;
1680 while (**mangled && ISDIGIT ((unsigned char)**mangled))
1681 (*mangled)++;
1683 else
1684 success = 0;
1685 break;
1687 case 'H':
1688 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1690 /* A G++ template function. Read the template arguments. */
1691 success = demangle_template (work, mangled, declp, 0, 0,
1693 if (!(work->constructor & 1))
1694 expect_return_type = 1;
1695 if (!**mangled)
1696 success = 0;
1697 else
1698 (*mangled)++;
1699 break;
1701 /* fall through */
1703 default:
1704 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1706 /* Assume we have stumbled onto the first outermost function
1707 argument token, and start processing args. */
1708 func_done = 1;
1709 success = demangle_args (work, mangled, declp);
1711 else
1713 /* Non-GNU demanglers use a specific token to mark the start
1714 of the outermost function argument tokens. Typically 'F',
1715 for ARM/HP-demangling, for example. So if we find something
1716 we are not prepared for, it must be an error. */
1717 success = 0;
1719 break;
1722 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1725 if (success && expect_func)
1727 func_done = 1;
1728 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1730 forget_types (work);
1732 success = demangle_args (work, mangled, declp);
1733 /* Since template include the mangling of their return types,
1734 we must set expect_func to 0 so that we don't try do
1735 demangle more arguments the next time we get here. */
1736 expect_func = 0;
1740 if (success && !func_done)
1742 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1744 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1745 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1746 first case, and need to ensure that the '(void)' gets added to
1747 the current declp. Note that with ARM/HP, the first case
1748 represents the name of a static data member 'foo::bar',
1749 which is in the current declp, so we leave it alone. */
1750 success = demangle_args (work, mangled, declp);
1753 if (success && PRINT_ARG_TYPES)
1755 if (work->static_type)
1756 string_append (declp, " static");
1757 if (work->type_quals != TYPE_UNQUALIFIED)
1759 APPEND_BLANK (declp);
1760 string_append (declp, qualifier_string (work->type_quals));
1764 return (success);
1767 #if 0
1769 static int
1770 demangle_method_args (struct work_stuff *work, const char **mangled,
1771 string *declp)
1773 int success = 0;
1775 if (work -> static_type)
1777 string_append (declp, *mangled + 1);
1778 *mangled += strlen (*mangled);
1779 success = 1;
1781 else
1783 success = demangle_args (work, mangled, declp);
1785 return (success);
1788 #endif
1790 static int
1791 demangle_template_template_parm (struct work_stuff *work,
1792 const char **mangled, string *tname)
1794 int i;
1795 int r;
1796 int need_comma = 0;
1797 int success = 1;
1798 string temp;
1800 string_append (tname, "template <");
1801 /* get size of template parameter list */
1802 if (get_count (mangled, &r))
1804 for (i = 0; i < r; i++)
1806 if (need_comma)
1808 string_append (tname, ", ");
1811 /* Z for type parameters */
1812 if (**mangled == 'Z')
1814 (*mangled)++;
1815 string_append (tname, "class");
1817 /* z for template parameters */
1818 else if (**mangled == 'z')
1820 (*mangled)++;
1821 success =
1822 demangle_template_template_parm (work, mangled, tname);
1823 if (!success)
1825 break;
1828 else
1830 /* temp is initialized in do_type */
1831 success = do_type (work, mangled, &temp);
1832 if (success)
1834 string_appends (tname, &temp);
1836 string_delete(&temp);
1837 if (!success)
1839 break;
1842 need_comma = 1;
1846 if (tname->p[-1] == '>')
1847 string_append (tname, " ");
1848 string_append (tname, "> class");
1849 return (success);
1852 static int
1853 demangle_expression (struct work_stuff *work, const char **mangled,
1854 string *s, type_kind_t tk)
1856 int need_operator = 0;
1857 int success;
1859 success = 1;
1860 string_appendn (s, "(", 1);
1861 (*mangled)++;
1862 while (success && **mangled != 'W' && **mangled != '\0')
1864 if (need_operator)
1866 size_t i;
1867 size_t len;
1869 success = 0;
1871 len = strlen (*mangled);
1873 for (i = 0; i < ARRAY_SIZE (optable); ++i)
1875 size_t l = strlen (optable[i].in);
1877 if (l <= len
1878 && memcmp (optable[i].in, *mangled, l) == 0)
1880 string_appendn (s, " ", 1);
1881 string_append (s, optable[i].out);
1882 string_appendn (s, " ", 1);
1883 success = 1;
1884 (*mangled) += l;
1885 break;
1889 if (!success)
1890 break;
1892 else
1893 need_operator = 1;
1895 success = demangle_template_value_parm (work, mangled, s, tk);
1898 if (**mangled != 'W')
1899 success = 0;
1900 else
1902 string_appendn (s, ")", 1);
1903 (*mangled)++;
1906 return success;
1909 static int
1910 demangle_integral_value (struct work_stuff *work,
1911 const char **mangled, string *s)
1913 int success;
1915 if (**mangled == 'E')
1916 success = demangle_expression (work, mangled, s, tk_integral);
1917 else if (**mangled == 'Q' || **mangled == 'K')
1918 success = demangle_qualified (work, mangled, s, 0, 1);
1919 else
1921 int value;
1923 /* By default, we let the number decide whether we shall consume an
1924 underscore. */
1925 int multidigit_without_leading_underscore = 0;
1926 int leave_following_underscore = 0;
1928 success = 0;
1930 if (**mangled == '_')
1932 if (mangled[0][1] == 'm')
1934 /* Since consume_count_with_underscores does not handle the
1935 `m'-prefix we must do it here, using consume_count and
1936 adjusting underscores: we have to consume the underscore
1937 matching the prepended one. */
1938 multidigit_without_leading_underscore = 1;
1939 string_appendn (s, "-", 1);
1940 (*mangled) += 2;
1942 else
1944 /* Do not consume a following underscore;
1945 consume_count_with_underscores will consume what
1946 should be consumed. */
1947 leave_following_underscore = 1;
1950 else
1952 /* Negative numbers are indicated with a leading `m'. */
1953 if (**mangled == 'm')
1955 string_appendn (s, "-", 1);
1956 (*mangled)++;
1958 /* Since consume_count_with_underscores does not handle
1959 multi-digit numbers that do not start with an underscore,
1960 and this number can be an integer template parameter,
1961 we have to call consume_count. */
1962 multidigit_without_leading_underscore = 1;
1963 /* These multi-digit numbers never end on an underscore,
1964 so if there is one then don't eat it. */
1965 leave_following_underscore = 1;
1968 /* We must call consume_count if we expect to remove a trailing
1969 underscore, since consume_count_with_underscores expects
1970 the leading underscore (that we consumed) if it is to handle
1971 multi-digit numbers. */
1972 if (multidigit_without_leading_underscore)
1973 value = consume_count (mangled);
1974 else
1975 value = consume_count_with_underscores (mangled);
1977 if (value != -1)
1979 char buf[INTBUF_SIZE];
1980 sprintf (buf, "%d", value);
1981 string_append (s, buf);
1983 /* Numbers not otherwise delimited, might have an underscore
1984 appended as a delimeter, which we should skip.
1986 ??? This used to always remove a following underscore, which
1987 is wrong. If other (arbitrary) cases are followed by an
1988 underscore, we need to do something more radical. */
1990 if ((value > 9 || multidigit_without_leading_underscore)
1991 && ! leave_following_underscore
1992 && **mangled == '_')
1993 (*mangled)++;
1995 /* All is well. */
1996 success = 1;
2000 return success;
2003 /* Demangle the real value in MANGLED. */
2005 static int
2006 demangle_real_value (struct work_stuff *work,
2007 const char **mangled, string *s)
2009 if (**mangled == 'E')
2010 return demangle_expression (work, mangled, s, tk_real);
2012 if (**mangled == 'm')
2014 string_appendn (s, "-", 1);
2015 (*mangled)++;
2017 while (ISDIGIT ((unsigned char)**mangled))
2019 string_appendn (s, *mangled, 1);
2020 (*mangled)++;
2022 if (**mangled == '.') /* fraction */
2024 string_appendn (s, ".", 1);
2025 (*mangled)++;
2026 while (ISDIGIT ((unsigned char)**mangled))
2028 string_appendn (s, *mangled, 1);
2029 (*mangled)++;
2032 if (**mangled == 'e') /* exponent */
2034 string_appendn (s, "e", 1);
2035 (*mangled)++;
2036 while (ISDIGIT ((unsigned char)**mangled))
2038 string_appendn (s, *mangled, 1);
2039 (*mangled)++;
2043 return 1;
2046 static int
2047 demangle_template_value_parm (struct work_stuff *work, const char **mangled,
2048 string *s, type_kind_t tk)
2050 int success = 1;
2052 if (**mangled == 'Y')
2054 /* The next argument is a template parameter. */
2055 int idx;
2057 (*mangled)++;
2058 idx = consume_count_with_underscores (mangled);
2059 if (idx == -1
2060 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2061 || consume_count_with_underscores (mangled) == -1)
2062 return -1;
2063 if (work->tmpl_argvec)
2064 string_append (s, work->tmpl_argvec[idx]);
2065 else
2066 string_append_template_idx (s, idx);
2068 else if (tk == tk_integral)
2069 success = demangle_integral_value (work, mangled, s);
2070 else if (tk == tk_char)
2072 char tmp[2];
2073 int val;
2074 if (**mangled == 'm')
2076 string_appendn (s, "-", 1);
2077 (*mangled)++;
2079 string_appendn (s, "'", 1);
2080 val = consume_count(mangled);
2081 if (val <= 0)
2082 success = 0;
2083 else
2085 tmp[0] = (char)val;
2086 tmp[1] = '\0';
2087 string_appendn (s, &tmp[0], 1);
2088 string_appendn (s, "'", 1);
2091 else if (tk == tk_bool)
2093 int val = consume_count (mangled);
2094 if (val == 0)
2095 string_appendn (s, "false", 5);
2096 else if (val == 1)
2097 string_appendn (s, "true", 4);
2098 else
2099 success = 0;
2101 else if (tk == tk_real)
2102 success = demangle_real_value (work, mangled, s);
2103 else if (tk == tk_pointer || tk == tk_reference
2104 || tk == tk_rvalue_reference)
2106 if (**mangled == 'Q')
2107 success = demangle_qualified (work, mangled, s,
2108 /*isfuncname=*/0,
2109 /*append=*/1);
2110 else
2112 int symbol_len = consume_count (mangled);
2113 if (symbol_len == -1
2114 || symbol_len > (long) strlen (*mangled))
2115 return -1;
2116 if (symbol_len == 0)
2117 string_appendn (s, "0", 1);
2118 else
2120 char *p = XNEWVEC (char, symbol_len + 1), *q;
2121 strncpy (p, *mangled, symbol_len);
2122 p [symbol_len] = '\0';
2123 /* We use cplus_demangle here, rather than
2124 internal_cplus_demangle, because the name of the entity
2125 mangled here does not make use of any of the squangling
2126 or type-code information we have built up thus far; it is
2127 mangled independently. */
2128 q = cplus_demangle (p, work->options);
2129 if (tk == tk_pointer)
2130 string_appendn (s, "&", 1);
2131 /* FIXME: Pointer-to-member constants should get a
2132 qualifying class name here. */
2133 if (q)
2135 string_append (s, q);
2136 free (q);
2138 else
2139 string_append (s, p);
2140 free (p);
2142 *mangled += symbol_len;
2146 return success;
2149 /* Demangle the template name in MANGLED. The full name of the
2150 template (e.g., S<int>) is placed in TNAME. The name without the
2151 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2152 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2153 not a function template. If both IS_TYPE and REMEMBER are nonzero,
2154 the template is remembered in the list of back-referenceable
2155 types. */
2157 static int
2158 demangle_template (struct work_stuff *work, const char **mangled,
2159 string *tname, string *trawname,
2160 int is_type, int remember)
2162 int i;
2163 int r;
2164 int need_comma = 0;
2165 int success = 0;
2166 int is_java_array = 0;
2167 string temp;
2169 (*mangled)++;
2170 if (is_type)
2172 /* get template name */
2173 if (**mangled == 'z')
2175 int idx;
2176 (*mangled)++;
2177 if (**mangled == '\0')
2178 return (0);
2179 (*mangled)++;
2181 idx = consume_count_with_underscores (mangled);
2182 if (idx == -1
2183 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2184 || consume_count_with_underscores (mangled) == -1)
2185 return (0);
2187 if (work->tmpl_argvec)
2189 string_append (tname, work->tmpl_argvec[idx]);
2190 if (trawname)
2191 string_append (trawname, work->tmpl_argvec[idx]);
2193 else
2195 string_append_template_idx (tname, idx);
2196 if (trawname)
2197 string_append_template_idx (trawname, idx);
2200 else
2202 if ((r = consume_count (mangled)) <= 0
2203 || (int) strlen (*mangled) < r)
2205 return (0);
2207 is_java_array = (work -> options & DMGL_JAVA)
2208 && strncmp (*mangled, "JArray1Z", 8) == 0;
2209 if (! is_java_array)
2211 string_appendn (tname, *mangled, r);
2213 if (trawname)
2214 string_appendn (trawname, *mangled, r);
2215 *mangled += r;
2218 if (!is_java_array)
2219 string_append (tname, "<");
2220 /* get size of template parameter list */
2221 if (!get_count (mangled, &r))
2223 return (0);
2225 if (!is_type)
2227 /* Create an array for saving the template argument values. */
2228 work->tmpl_argvec = XNEWVEC (char *, r);
2229 work->ntmpl_args = r;
2230 for (i = 0; i < r; i++)
2231 work->tmpl_argvec[i] = 0;
2233 for (i = 0; i < r; i++)
2235 if (need_comma)
2237 string_append (tname, ", ");
2239 /* Z for type parameters */
2240 if (**mangled == 'Z')
2242 (*mangled)++;
2243 /* temp is initialized in do_type */
2244 success = do_type (work, mangled, &temp);
2245 if (success)
2247 string_appends (tname, &temp);
2249 if (!is_type)
2251 /* Save the template argument. */
2252 int len = temp.p - temp.b;
2253 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2254 memcpy (work->tmpl_argvec[i], temp.b, len);
2255 work->tmpl_argvec[i][len] = '\0';
2258 string_delete(&temp);
2259 if (!success)
2261 break;
2264 /* z for template parameters */
2265 else if (**mangled == 'z')
2267 int r2;
2268 (*mangled)++;
2269 success = demangle_template_template_parm (work, mangled, tname);
2271 if (success
2272 && (r2 = consume_count (mangled)) > 0
2273 && (int) strlen (*mangled) >= r2)
2275 string_append (tname, " ");
2276 string_appendn (tname, *mangled, r2);
2277 if (!is_type)
2279 /* Save the template argument. */
2280 int len = r2;
2281 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2282 memcpy (work->tmpl_argvec[i], *mangled, len);
2283 work->tmpl_argvec[i][len] = '\0';
2285 *mangled += r2;
2287 if (!success)
2289 break;
2292 else
2294 string param;
2295 string* s;
2297 /* otherwise, value parameter */
2299 /* temp is initialized in do_type */
2300 success = do_type (work, mangled, &temp);
2301 string_delete(&temp);
2302 if (!success)
2303 break;
2305 if (!is_type)
2307 s = &param;
2308 string_init (s);
2310 else
2311 s = tname;
2313 success = demangle_template_value_parm (work, mangled, s,
2314 (type_kind_t) success);
2316 if (!success)
2318 if (!is_type)
2319 string_delete (s);
2320 success = 0;
2321 break;
2324 if (!is_type)
2326 int len = s->p - s->b;
2327 work->tmpl_argvec[i] = XNEWVEC (char, len + 1);
2328 memcpy (work->tmpl_argvec[i], s->b, len);
2329 work->tmpl_argvec[i][len] = '\0';
2331 string_appends (tname, s);
2332 string_delete (s);
2335 need_comma = 1;
2337 if (is_java_array)
2339 string_append (tname, "[]");
2341 else
2343 if (tname->p[-1] == '>')
2344 string_append (tname, " ");
2345 string_append (tname, ">");
2348 if (is_type && remember)
2350 const int bindex = register_Btype (work);
2351 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2355 if (work -> static_type)
2357 string_append (declp, *mangled + 1);
2358 *mangled += strlen (*mangled);
2359 success = 1;
2361 else
2363 success = demangle_args (work, mangled, declp);
2367 return (success);
2370 static int
2371 arm_pt (struct work_stuff *work, const char *mangled,
2372 int n, const char **anchor, const char **args)
2374 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2375 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2376 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__")))
2378 int len;
2379 *args = *anchor + 6;
2380 len = consume_count (args);
2381 if (len == -1)
2382 return 0;
2383 if (*args + len == mangled + n && **args == '_')
2385 ++*args;
2386 return 1;
2389 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2391 if ((*anchor = strstr (mangled, "__tm__"))
2392 || (*anchor = strstr (mangled, "__ps__"))
2393 || (*anchor = strstr (mangled, "__pt__")))
2395 int len;
2396 *args = *anchor + 6;
2397 len = consume_count (args);
2398 if (len == -1)
2399 return 0;
2400 if (*args + len == mangled + n && **args == '_')
2402 ++*args;
2403 return 1;
2406 else if ((*anchor = strstr (mangled, "__S")))
2408 int len;
2409 *args = *anchor + 3;
2410 len = consume_count (args);
2411 if (len == -1)
2412 return 0;
2413 if (*args + len == mangled + n && **args == '_')
2415 ++*args;
2416 return 1;
2421 return 0;
2424 static void
2425 demangle_arm_hp_template (struct work_stuff *work, const char **mangled,
2426 int n, string *declp)
2428 const char *p;
2429 const char *args;
2430 const char *e = *mangled + n;
2431 string arg;
2433 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2434 template args */
2435 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
2437 char *start_spec_args = NULL;
2438 int hold_options;
2440 /* First check for and omit template specialization pseudo-arguments,
2441 such as in "Spec<#1,#1.*>" */
2442 start_spec_args = strchr (*mangled, '<');
2443 if (start_spec_args && (start_spec_args - *mangled < n))
2444 string_appendn (declp, *mangled, start_spec_args - *mangled);
2445 else
2446 string_appendn (declp, *mangled, n);
2447 (*mangled) += n + 1;
2448 string_init (&arg);
2449 if (work->temp_start == -1) /* non-recursive call */
2450 work->temp_start = declp->p - declp->b;
2452 /* We want to unconditionally demangle parameter types in
2453 template parameters. */
2454 hold_options = work->options;
2455 work->options |= DMGL_PARAMS;
2457 string_append (declp, "<");
2458 while (1)
2460 string_delete (&arg);
2461 switch (**mangled)
2463 case 'T':
2464 /* 'T' signals a type parameter */
2465 (*mangled)++;
2466 if (!do_type (work, mangled, &arg))
2467 goto hpacc_template_args_done;
2468 break;
2470 case 'U':
2471 case 'S':
2472 /* 'U' or 'S' signals an integral value */
2473 if (!do_hpacc_template_const_value (work, mangled, &arg))
2474 goto hpacc_template_args_done;
2475 break;
2477 case 'A':
2478 /* 'A' signals a named constant expression (literal) */
2479 if (!do_hpacc_template_literal (work, mangled, &arg))
2480 goto hpacc_template_args_done;
2481 break;
2483 default:
2484 /* Today, 1997-09-03, we have only the above types
2485 of template parameters */
2486 /* FIXME: maybe this should fail and return null */
2487 goto hpacc_template_args_done;
2489 string_appends (declp, &arg);
2490 /* Check if we're at the end of template args.
2491 0 if at end of static member of template class,
2492 _ if done with template args for a function */
2493 if ((**mangled == '\000') || (**mangled == '_'))
2494 break;
2495 else
2496 string_append (declp, ",");
2498 hpacc_template_args_done:
2499 string_append (declp, ">");
2500 string_delete (&arg);
2501 if (**mangled == '_')
2502 (*mangled)++;
2503 work->options = hold_options;
2504 return;
2506 /* ARM template? (Also handles HP cfront extensions) */
2507 else if (arm_pt (work, *mangled, n, &p, &args))
2509 int hold_options;
2510 string type_str;
2512 string_init (&arg);
2513 string_appendn (declp, *mangled, p - *mangled);
2514 if (work->temp_start == -1) /* non-recursive call */
2515 work->temp_start = declp->p - declp->b;
2517 /* We want to unconditionally demangle parameter types in
2518 template parameters. */
2519 hold_options = work->options;
2520 work->options |= DMGL_PARAMS;
2522 string_append (declp, "<");
2523 /* should do error checking here */
2524 while (args < e) {
2525 string_delete (&arg);
2527 /* Check for type or literal here */
2528 switch (*args)
2530 /* HP cfront extensions to ARM for template args */
2531 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2532 /* FIXME: We handle only numeric literals for HP cfront */
2533 case 'X':
2534 /* A typed constant value follows */
2535 args++;
2536 if (!do_type (work, &args, &type_str))
2537 goto cfront_template_args_done;
2538 string_append (&arg, "(");
2539 string_appends (&arg, &type_str);
2540 string_delete (&type_str);
2541 string_append (&arg, ")");
2542 if (*args != 'L')
2543 goto cfront_template_args_done;
2544 args++;
2545 /* Now snarf a literal value following 'L' */
2546 if (!snarf_numeric_literal (&args, &arg))
2547 goto cfront_template_args_done;
2548 break;
2550 case 'L':
2551 /* Snarf a literal following 'L' */
2552 args++;
2553 if (!snarf_numeric_literal (&args, &arg))
2554 goto cfront_template_args_done;
2555 break;
2556 default:
2557 /* Not handling other HP cfront stuff */
2559 const char* old_args = args;
2560 if (!do_type (work, &args, &arg))
2561 goto cfront_template_args_done;
2563 /* Fail if we didn't make any progress: prevent infinite loop. */
2564 if (args == old_args)
2566 work->options = hold_options;
2567 return;
2571 string_appends (declp, &arg);
2572 string_append (declp, ",");
2574 cfront_template_args_done:
2575 string_delete (&arg);
2576 if (args >= e)
2577 --declp->p; /* remove extra comma */
2578 string_append (declp, ">");
2579 work->options = hold_options;
2581 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2582 && (*mangled)[9] == 'N'
2583 && (*mangled)[8] == (*mangled)[10]
2584 && strchr (cplus_markers, (*mangled)[8]))
2586 /* A member of the anonymous namespace. */
2587 string_append (declp, "{anonymous}");
2589 else
2591 if (work->temp_start == -1) /* non-recursive call only */
2592 work->temp_start = 0; /* disable in recursive calls */
2593 string_appendn (declp, *mangled, n);
2595 *mangled += n;
2598 /* Extract a class name, possibly a template with arguments, from the
2599 mangled string; qualifiers, local class indicators, etc. have
2600 already been dealt with */
2602 static int
2603 demangle_class_name (struct work_stuff *work, const char **mangled,
2604 string *declp)
2606 int n;
2607 int success = 0;
2609 n = consume_count (mangled);
2610 if (n == -1)
2611 return 0;
2612 if ((int) strlen (*mangled) >= n)
2614 demangle_arm_hp_template (work, mangled, n, declp);
2615 success = 1;
2618 return (success);
2623 LOCAL FUNCTION
2625 demangle_class -- demangle a mangled class sequence
2627 SYNOPSIS
2629 static int
2630 demangle_class (struct work_stuff *work, const char **mangled,
2631 strint *declp)
2633 DESCRIPTION
2635 DECLP points to the buffer into which demangling is being done.
2637 *MANGLED points to the current token to be demangled. On input,
2638 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2639 On exit, it points to the next token after the mangled class on
2640 success, or the first unconsumed token on failure.
2642 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2643 we are demangling a constructor or destructor. In this case
2644 we prepend "class::class" or "class::~class" to DECLP.
2646 Otherwise, we prepend "class::" to the current DECLP.
2648 Reset the constructor/destructor flags once they have been
2649 "consumed". This allows demangle_class to be called later during
2650 the same demangling, to do normal class demangling.
2652 Returns 1 if demangling is successful, 0 otherwise.
2656 static int
2657 demangle_class (struct work_stuff *work, const char **mangled, string *declp)
2659 int success = 0;
2660 int btype;
2661 string class_name;
2662 char *save_class_name_end = 0;
2664 string_init (&class_name);
2665 btype = register_Btype (work);
2666 if (demangle_class_name (work, mangled, &class_name))
2668 save_class_name_end = class_name.p;
2669 if ((work->constructor & 1) || (work->destructor & 1))
2671 /* adjust so we don't include template args */
2672 if (work->temp_start && (work->temp_start != -1))
2674 class_name.p = class_name.b + work->temp_start;
2676 string_prepends (declp, &class_name);
2677 if (work -> destructor & 1)
2679 string_prepend (declp, "~");
2680 work -> destructor -= 1;
2682 else
2684 work -> constructor -= 1;
2687 class_name.p = save_class_name_end;
2688 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2689 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
2690 string_prepend (declp, SCOPE_STRING (work));
2691 string_prepends (declp, &class_name);
2692 success = 1;
2694 string_delete (&class_name);
2695 return (success);
2699 /* Called when there's a "__" in the mangled name, with `scan' pointing to
2700 the rightmost guess.
2702 Find the correct "__"-sequence where the function name ends and the
2703 signature starts, which is ambiguous with GNU mangling.
2704 Call demangle_signature here, so we can make sure we found the right
2705 one; *mangled will be consumed so caller will not make further calls to
2706 demangle_signature. */
2708 static int
2709 iterate_demangle_function (struct work_stuff *work, const char **mangled,
2710 string *declp, const char *scan)
2712 const char *mangle_init = *mangled;
2713 int success = 0;
2714 string decl_init;
2715 struct work_stuff work_init;
2717 if (*(scan + 2) == '\0')
2718 return 0;
2720 /* Do not iterate for some demangling modes, or if there's only one
2721 "__"-sequence. This is the normal case. */
2722 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2723 || strstr (scan + 2, "__") == NULL)
2724 return demangle_function_name (work, mangled, declp, scan);
2726 /* Save state so we can restart if the guess at the correct "__" was
2727 wrong. */
2728 string_init (&decl_init);
2729 string_appends (&decl_init, declp);
2730 memset (&work_init, 0, sizeof work_init);
2731 work_stuff_copy_to_from (&work_init, work);
2733 /* Iterate over occurrences of __, allowing names and types to have a
2734 "__" sequence in them. We must start with the first (not the last)
2735 occurrence, since "__" most often occur between independent mangled
2736 parts, hence starting at the last occurence inside a signature
2737 might get us a "successful" demangling of the signature. */
2739 while (scan[2])
2741 if (demangle_function_name (work, mangled, declp, scan))
2743 success = demangle_signature (work, mangled, declp);
2744 if (success)
2745 break;
2748 /* Reset demangle state for the next round. */
2749 *mangled = mangle_init;
2750 string_clear (declp);
2751 string_appends (declp, &decl_init);
2752 work_stuff_copy_to_from (work, &work_init);
2754 /* Leave this underscore-sequence. */
2755 scan += 2;
2757 /* Scan for the next "__" sequence. */
2758 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2759 scan++;
2761 /* Move to last "__" in this sequence. */
2762 while (*scan && *scan == '_')
2763 scan++;
2764 scan -= 2;
2767 /* Delete saved state. */
2768 delete_work_stuff (&work_init);
2769 string_delete (&decl_init);
2771 return success;
2776 LOCAL FUNCTION
2778 demangle_prefix -- consume the mangled name prefix and find signature
2780 SYNOPSIS
2782 static int
2783 demangle_prefix (struct work_stuff *work, const char **mangled,
2784 string *declp);
2786 DESCRIPTION
2788 Consume and demangle the prefix of the mangled name.
2789 While processing the function name root, arrange to call
2790 demangle_signature if the root is ambiguous.
2792 DECLP points to the string buffer into which demangled output is
2793 placed. On entry, the buffer is empty. On exit it contains
2794 the root function name, the demangled operator name, or in some
2795 special cases either nothing or the completely demangled result.
2797 MANGLED points to the current pointer into the mangled name. As each
2798 token of the mangled name is consumed, it is updated. Upon entry
2799 the current mangled name pointer points to the first character of
2800 the mangled name. Upon exit, it should point to the first character
2801 of the signature if demangling was successful, or to the first
2802 unconsumed character if demangling of the prefix was unsuccessful.
2804 Returns 1 on success, 0 otherwise.
2807 static int
2808 demangle_prefix (struct work_stuff *work, const char **mangled,
2809 string *declp)
2811 int success = 1;
2812 const char *scan;
2813 int i;
2815 if (strlen(*mangled) > 6
2816 && (strncmp(*mangled, "_imp__", 6) == 0
2817 || strncmp(*mangled, "__imp_", 6) == 0))
2819 /* it's a symbol imported from a PE dynamic library. Check for both
2820 new style prefix _imp__ and legacy __imp_ used by older versions
2821 of dlltool. */
2822 (*mangled) += 6;
2823 work->dllimported = 1;
2825 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
2827 char *marker = strchr (cplus_markers, (*mangled)[8]);
2828 if (marker != NULL && *marker == (*mangled)[10])
2830 if ((*mangled)[9] == 'D')
2832 /* it's a GNU global destructor to be executed at program exit */
2833 (*mangled) += 11;
2834 work->destructor = 2;
2835 if (gnu_special (work, mangled, declp))
2836 return success;
2838 else if ((*mangled)[9] == 'I')
2840 /* it's a GNU global constructor to be executed at program init */
2841 (*mangled) += 11;
2842 work->constructor = 2;
2843 if (gnu_special (work, mangled, declp))
2844 return success;
2848 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
2850 /* it's a ARM global destructor to be executed at program exit */
2851 (*mangled) += 7;
2852 work->destructor = 2;
2854 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
2856 /* it's a ARM global constructor to be executed at program initial */
2857 (*mangled) += 7;
2858 work->constructor = 2;
2861 /* This block of code is a reduction in strength time optimization
2863 scan = strstr (*mangled, "__"); */
2866 scan = *mangled;
2868 do {
2869 scan = strchr (scan, '_');
2870 } while (scan != NULL && *++scan != '_');
2872 if (scan != NULL) --scan;
2875 if (scan != NULL)
2877 /* We found a sequence of two or more '_', ensure that we start at
2878 the last pair in the sequence. */
2879 i = strspn (scan, "_");
2880 if (i > 2)
2882 scan += (i - 2);
2886 if (scan == NULL)
2888 success = 0;
2890 else if (work -> static_type)
2892 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
2894 success = 0;
2897 else if ((scan == *mangled)
2898 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
2899 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
2901 /* The ARM says nothing about the mangling of local variables.
2902 But cfront mangles local variables by prepending __<nesting_level>
2903 to them. As an extension to ARM demangling we handle this case. */
2904 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
2905 && ISDIGIT ((unsigned char)scan[2]))
2907 *mangled = scan + 2;
2908 consume_count (mangled);
2909 string_append (declp, *mangled);
2910 *mangled += strlen (*mangled);
2911 success = 1;
2913 else
2915 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2916 names like __Q2_3foo3bar for nested type names. So don't accept
2917 this style of constructor for cfront demangling. A GNU
2918 style member-template constructor starts with 'H'. */
2919 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
2920 work -> constructor += 1;
2921 *mangled = scan + 2;
2924 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2926 /* Cfront-style parameterized type. Handled later as a signature. */
2927 success = 1;
2929 /* ARM template? */
2930 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2932 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2933 || (scan[2] == 'p' && scan[3] == 's')
2934 || (scan[2] == 'p' && scan[3] == 't')))
2936 /* EDG-style parameterized type. Handled later as a signature. */
2937 success = 1;
2939 /* EDG template? */
2940 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2942 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
2943 && (scan[2] != 't'))
2945 /* Mangled name starts with "__". Skip over any leading '_' characters,
2946 then find the next "__" that separates the prefix from the signature.
2948 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
2949 || (arm_special (mangled, declp) == 0))
2951 while (*scan == '_')
2953 scan++;
2955 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2957 /* No separator (I.E. "__not_mangled"), or empty signature
2958 (I.E. "__not_mangled_either__") */
2959 success = 0;
2961 else
2962 return iterate_demangle_function (work, mangled, declp, scan);
2965 else if (*(scan + 2) != '\0')
2967 /* Mangled name does not start with "__" but does have one somewhere
2968 in there with non empty stuff after it. Looks like a global
2969 function name. Iterate over all "__":s until the right
2970 one is found. */
2971 return iterate_demangle_function (work, mangled, declp, scan);
2973 else
2975 /* Doesn't look like a mangled name */
2976 success = 0;
2979 if (!success && (work->constructor == 2 || work->destructor == 2))
2981 string_append (declp, *mangled);
2982 *mangled += strlen (*mangled);
2983 success = 1;
2985 return (success);
2990 LOCAL FUNCTION
2992 gnu_special -- special handling of gnu mangled strings
2994 SYNOPSIS
2996 static int
2997 gnu_special (struct work_stuff *work, const char **mangled,
2998 string *declp);
3001 DESCRIPTION
3003 Process some special GNU style mangling forms that don't fit
3004 the normal pattern. For example:
3006 _$_3foo (destructor for class foo)
3007 _vt$foo (foo virtual table)
3008 _vt$foo$bar (foo::bar virtual table)
3009 __vt_foo (foo virtual table, new style with thunks)
3010 _3foo$varname (static data member)
3011 _Q22rs2tu$vw (static data member)
3012 __t6vector1Zii (constructor with template)
3013 __thunk_4__$_7ostream (virtual function thunk)
3016 static int
3017 gnu_special (struct work_stuff *work, const char **mangled, string *declp)
3019 int n;
3020 int success = 1;
3021 const char *p;
3023 if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
3024 && strchr (cplus_markers, (*mangled)[1]) != NULL
3025 && (*mangled)[2] == '_')
3027 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
3028 (*mangled) += 3;
3029 work -> destructor += 1;
3031 else if ((*mangled)[0] == '_'
3032 && (((*mangled)[1] == '_'
3033 && (*mangled)[2] == 'v'
3034 && (*mangled)[3] == 't'
3035 && (*mangled)[4] == '_')
3036 || ((*mangled)[1] == 'v'
3037 && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
3038 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
3040 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
3041 and create the decl. Note that we consume the entire mangled
3042 input string, which means that demangle_signature has no work
3043 to do. */
3044 if ((*mangled)[2] == 'v')
3045 (*mangled) += 5; /* New style, with thunks: "__vt_" */
3046 else
3047 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
3048 while (**mangled != '\0')
3050 switch (**mangled)
3052 case 'Q':
3053 case 'K':
3054 success = demangle_qualified (work, mangled, declp, 0, 1);
3055 break;
3056 case 't':
3057 success = demangle_template (work, mangled, declp, 0, 1,
3059 break;
3060 default:
3061 if (ISDIGIT((unsigned char)*mangled[0]))
3063 n = consume_count(mangled);
3064 /* We may be seeing a too-large size, or else a
3065 ".<digits>" indicating a static local symbol. In
3066 any case, declare victory and move on; *don't* try
3067 to use n to allocate. */
3068 if (n > (int) strlen (*mangled))
3070 success = 1;
3071 break;
3073 else if (n == -1)
3075 success = 0;
3076 break;
3079 else
3081 n = strcspn (*mangled, cplus_markers);
3083 string_appendn (declp, *mangled, n);
3084 (*mangled) += n;
3087 p = strpbrk (*mangled, cplus_markers);
3088 if (success && ((p == NULL) || (p == *mangled)))
3090 if (p != NULL)
3092 string_append (declp, SCOPE_STRING (work));
3093 (*mangled)++;
3096 else
3098 success = 0;
3099 break;
3102 if (success)
3103 string_append (declp, " virtual table");
3105 else if ((*mangled)[0] == '_'
3106 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
3107 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
3109 /* static data member, "_3foo$varname" for example */
3110 (*mangled)++;
3111 switch (**mangled)
3113 case 'Q':
3114 case 'K':
3115 success = demangle_qualified (work, mangled, declp, 0, 1);
3116 break;
3117 case 't':
3118 success = demangle_template (work, mangled, declp, 0, 1, 1);
3119 break;
3120 default:
3121 n = consume_count (mangled);
3122 if (n < 0 || n > (long) strlen (*mangled))
3124 success = 0;
3125 break;
3128 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
3129 && (*mangled)[9] == 'N'
3130 && (*mangled)[8] == (*mangled)[10]
3131 && strchr (cplus_markers, (*mangled)[8]))
3133 /* A member of the anonymous namespace. There's information
3134 about what identifier or filename it was keyed to, but
3135 it's just there to make the mangled name unique; we just
3136 step over it. */
3137 string_append (declp, "{anonymous}");
3138 (*mangled) += n;
3140 /* Now p points to the marker before the N, so we need to
3141 update it to the first marker after what we consumed. */
3142 p = strpbrk (*mangled, cplus_markers);
3143 break;
3146 string_appendn (declp, *mangled, n);
3147 (*mangled) += n;
3149 if (success && (p == *mangled))
3151 /* Consumed everything up to the cplus_marker, append the
3152 variable name. */
3153 (*mangled)++;
3154 string_append (declp, SCOPE_STRING (work));
3155 n = strlen (*mangled);
3156 string_appendn (declp, *mangled, n);
3157 (*mangled) += n;
3159 else
3161 success = 0;
3164 else if (strncmp (*mangled, "__thunk_", 8) == 0)
3166 int delta;
3168 (*mangled) += 8;
3169 delta = consume_count (mangled);
3170 if (delta == -1)
3171 success = 0;
3172 else if (**mangled != '_')
3173 success = 0;
3174 else
3176 char *method = internal_cplus_demangle (work, ++*mangled);
3178 if (method)
3180 char buf[50];
3181 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3182 string_append (declp, buf);
3183 string_append (declp, method);
3184 free (method);
3185 n = strlen (*mangled);
3186 (*mangled) += n;
3188 else
3190 success = 0;
3194 else if (strncmp (*mangled, "__t", 3) == 0
3195 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3197 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3198 (*mangled) += 4;
3199 switch (**mangled)
3201 case 'Q':
3202 case 'K':
3203 success = demangle_qualified (work, mangled, declp, 0, 1);
3204 break;
3205 case 't':
3206 success = demangle_template (work, mangled, declp, 0, 1, 1);
3207 break;
3208 default:
3209 success = do_type (work, mangled, declp);
3210 break;
3212 if (success && **mangled != '\0')
3213 success = 0;
3214 if (success)
3215 string_append (declp, p);
3217 else
3219 success = 0;
3221 return (success);
3224 static void
3225 recursively_demangle(struct work_stuff *work, const char **mangled,
3226 string *result, int namelength)
3228 char * recurse = (char *)NULL;
3229 char * recurse_dem = (char *)NULL;
3231 recurse = XNEWVEC (char, namelength + 1);
3232 memcpy (recurse, *mangled, namelength);
3233 recurse[namelength] = '\000';
3235 recurse_dem = cplus_demangle (recurse, work->options);
3237 if (recurse_dem)
3239 string_append (result, recurse_dem);
3240 free (recurse_dem);
3242 else
3244 string_appendn (result, *mangled, namelength);
3246 free (recurse);
3247 *mangled += namelength;
3252 LOCAL FUNCTION
3254 arm_special -- special handling of ARM/lucid mangled strings
3256 SYNOPSIS
3258 static int
3259 arm_special (const char **mangled,
3260 string *declp);
3263 DESCRIPTION
3265 Process some special ARM style mangling forms that don't fit
3266 the normal pattern. For example:
3268 __vtbl__3foo (foo virtual table)
3269 __vtbl__3foo__3bar (bar::foo virtual table)
3273 static int
3274 arm_special (const char **mangled, string *declp)
3276 int n;
3277 int success = 1;
3278 const char *scan;
3280 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3282 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3283 and create the decl. Note that we consume the entire mangled
3284 input string, which means that demangle_signature has no work
3285 to do. */
3286 scan = *mangled + ARM_VTABLE_STRLEN;
3287 while (*scan != '\0') /* first check it can be demangled */
3289 n = consume_count (&scan);
3290 if (n == -1)
3292 return (0); /* no good */
3294 scan += n;
3295 if (scan[0] == '_' && scan[1] == '_')
3297 scan += 2;
3300 (*mangled) += ARM_VTABLE_STRLEN;
3301 while (**mangled != '\0')
3303 n = consume_count (mangled);
3304 if (n == -1
3305 || n > (long) strlen (*mangled))
3306 return 0;
3307 string_prependn (declp, *mangled, n);
3308 (*mangled) += n;
3309 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3311 string_prepend (declp, "::");
3312 (*mangled) += 2;
3315 string_append (declp, " virtual table");
3317 else
3319 success = 0;
3321 return (success);
3326 LOCAL FUNCTION
3328 demangle_qualified -- demangle 'Q' qualified name strings
3330 SYNOPSIS
3332 static int
3333 demangle_qualified (struct work_stuff *, const char *mangled,
3334 string *result, int isfuncname, int append);
3336 DESCRIPTION
3338 Demangle a qualified name, such as "Q25Outer5Inner" which is
3339 the mangled form of "Outer::Inner". The demangled output is
3340 prepended or appended to the result string according to the
3341 state of the append flag.
3343 If isfuncname is nonzero, then the qualified name we are building
3344 is going to be used as a member function name, so if it is a
3345 constructor or destructor function, append an appropriate
3346 constructor or destructor name. I.E. for the above example,
3347 the result for use as a constructor is "Outer::Inner::Inner"
3348 and the result for use as a destructor is "Outer::Inner::~Inner".
3350 BUGS
3352 Numeric conversion is ASCII dependent (FIXME).
3356 static int
3357 demangle_qualified (struct work_stuff *work, const char **mangled,
3358 string *result, int isfuncname, int append)
3360 int qualifiers = 0;
3361 int success = 1;
3362 char num[2];
3363 string temp;
3364 string last_name;
3365 int bindex = register_Btype (work);
3367 /* We only make use of ISFUNCNAME if the entity is a constructor or
3368 destructor. */
3369 isfuncname = (isfuncname
3370 && ((work->constructor & 1) || (work->destructor & 1)));
3372 string_init (&temp);
3373 string_init (&last_name);
3375 if ((*mangled)[0] == 'K')
3377 /* Squangling qualified name reuse */
3378 int idx;
3379 (*mangled)++;
3380 idx = consume_count_with_underscores (mangled);
3381 if (idx == -1 || idx >= work -> numk)
3382 success = 0;
3383 else
3384 string_append (&temp, work -> ktypevec[idx]);
3386 else
3387 switch ((*mangled)[1])
3389 case '_':
3390 /* GNU mangled name with more than 9 classes. The count is preceded
3391 by an underscore (to distinguish it from the <= 9 case) and followed
3392 by an underscore. */
3393 (*mangled)++;
3394 qualifiers = consume_count_with_underscores (mangled);
3395 if (qualifiers == -1)
3396 success = 0;
3397 break;
3399 case '1':
3400 case '2':
3401 case '3':
3402 case '4':
3403 case '5':
3404 case '6':
3405 case '7':
3406 case '8':
3407 case '9':
3408 /* The count is in a single digit. */
3409 num[0] = (*mangled)[1];
3410 num[1] = '\0';
3411 qualifiers = atoi (num);
3413 /* If there is an underscore after the digit, skip it. This is
3414 said to be for ARM-qualified names, but the ARM makes no
3415 mention of such an underscore. Perhaps cfront uses one. */
3416 if ((*mangled)[2] == '_')
3418 (*mangled)++;
3420 (*mangled) += 2;
3421 break;
3423 case '0':
3424 default:
3425 success = 0;
3428 if (!success)
3429 return success;
3431 /* Pick off the names and collect them in the temp buffer in the order
3432 in which they are found, separated by '::'. */
3434 while (qualifiers-- > 0)
3436 int remember_K = 1;
3437 string_clear (&last_name);
3439 if (*mangled[0] == '_')
3440 (*mangled)++;
3442 if (*mangled[0] == 't')
3444 /* Here we always append to TEMP since we will want to use
3445 the template name without the template parameters as a
3446 constructor or destructor name. The appropriate
3447 (parameter-less) value is returned by demangle_template
3448 in LAST_NAME. We do not remember the template type here,
3449 in order to match the G++ mangling algorithm. */
3450 success = demangle_template(work, mangled, &temp,
3451 &last_name, 1, 0);
3452 if (!success)
3453 break;
3455 else if (*mangled[0] == 'K')
3457 int idx;
3458 (*mangled)++;
3459 idx = consume_count_with_underscores (mangled);
3460 if (idx == -1 || idx >= work->numk)
3461 success = 0;
3462 else
3463 string_append (&temp, work->ktypevec[idx]);
3464 remember_K = 0;
3466 if (!success) break;
3468 else
3470 if (EDG_DEMANGLING)
3472 int namelength;
3473 /* Now recursively demangle the qualifier
3474 * This is necessary to deal with templates in
3475 * mangling styles like EDG */
3476 namelength = consume_count (mangled);
3477 if (namelength == -1)
3479 success = 0;
3480 break;
3482 recursively_demangle(work, mangled, &temp, namelength);
3484 else
3486 string_delete (&last_name);
3487 success = do_type (work, mangled, &last_name);
3488 if (!success)
3489 break;
3490 string_appends (&temp, &last_name);
3494 if (remember_K)
3495 remember_Ktype (work, temp.b, LEN_STRING (&temp));
3497 if (qualifiers > 0)
3498 string_append (&temp, SCOPE_STRING (work));
3501 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3503 /* If we are using the result as a function name, we need to append
3504 the appropriate '::' separated constructor or destructor name.
3505 We do this here because this is the most convenient place, where
3506 we already have a pointer to the name and the length of the name. */
3508 if (isfuncname)
3510 string_append (&temp, SCOPE_STRING (work));
3511 if (work -> destructor & 1)
3512 string_append (&temp, "~");
3513 string_appends (&temp, &last_name);
3516 /* Now either prepend the temp buffer to the result, or append it,
3517 depending upon the state of the append flag. */
3519 if (append)
3520 string_appends (result, &temp);
3521 else
3523 if (!STRING_EMPTY (result))
3524 string_append (&temp, SCOPE_STRING (work));
3525 string_prepends (result, &temp);
3528 string_delete (&last_name);
3529 string_delete (&temp);
3530 return (success);
3535 LOCAL FUNCTION
3537 get_count -- convert an ascii count to integer, consuming tokens
3539 SYNOPSIS
3541 static int
3542 get_count (const char **type, int *count)
3544 DESCRIPTION
3546 Assume that *type points at a count in a mangled name; set
3547 *count to its value, and set *type to the next character after
3548 the count. There are some weird rules in effect here.
3550 If *type does not point at a string of digits, return zero.
3552 If *type points at a string of digits followed by an
3553 underscore, set *count to their value as an integer, advance
3554 *type to point *after the underscore, and return 1.
3556 If *type points at a string of digits not followed by an
3557 underscore, consume only the first digit. Set *count to its
3558 value as an integer, leave *type pointing after that digit,
3559 and return 1.
3561 The excuse for this odd behavior: in the ARM and HP demangling
3562 styles, a type can be followed by a repeat count of the form
3563 `Nxy', where:
3565 `x' is a single digit specifying how many additional copies
3566 of the type to append to the argument list, and
3568 `y' is one or more digits, specifying the zero-based index of
3569 the first repeated argument in the list. Yes, as you're
3570 unmangling the name you can figure this out yourself, but
3571 it's there anyway.
3573 So, for example, in `bar__3fooFPiN51', the first argument is a
3574 pointer to an integer (`Pi'), and then the next five arguments
3575 are the same (`N5'), and the first repeat is the function's
3576 second argument (`1').
3579 static int
3580 get_count (const char **type, int *count)
3582 const char *p;
3583 int n;
3585 if (!ISDIGIT ((unsigned char)**type))
3586 return (0);
3587 else
3589 *count = **type - '0';
3590 (*type)++;
3591 if (ISDIGIT ((unsigned char)**type))
3593 p = *type;
3594 n = *count;
3597 n *= 10;
3598 n += *p - '0';
3599 p++;
3601 while (ISDIGIT ((unsigned char)*p));
3602 if (*p == '_')
3604 *type = p + 1;
3605 *count = n;
3609 return (1);
3612 /* RESULT will be initialised here; it will be freed on failure. The
3613 value returned is really a type_kind_t. */
3615 static int
3616 do_type (struct work_stuff *work, const char **mangled, string *result)
3618 int n;
3619 int i;
3620 int is_proctypevec;
3621 int done;
3622 int success;
3623 string decl;
3624 const char *remembered_type;
3625 int type_quals;
3626 type_kind_t tk = tk_none;
3628 string_init (&decl);
3629 string_init (result);
3631 done = 0;
3632 success = 1;
3633 is_proctypevec = 0;
3634 while (success && !done)
3636 int member;
3637 switch (**mangled)
3640 /* A pointer type */
3641 case 'P':
3642 case 'p':
3643 (*mangled)++;
3644 if (! (work -> options & DMGL_JAVA))
3645 string_prepend (&decl, "*");
3646 if (tk == tk_none)
3647 tk = tk_pointer;
3648 break;
3650 /* A reference type */
3651 case 'R':
3652 (*mangled)++;
3653 string_prepend (&decl, "&");
3654 if (tk == tk_none)
3655 tk = tk_reference;
3656 break;
3658 /* An rvalue reference type */
3659 case 'O':
3660 (*mangled)++;
3661 string_prepend (&decl, "&&");
3662 if (tk == tk_none)
3663 tk = tk_rvalue_reference;
3664 break;
3666 /* An array */
3667 case 'A':
3669 ++(*mangled);
3670 if (!STRING_EMPTY (&decl)
3671 && (decl.b[0] == '*' || decl.b[0] == '&'))
3673 string_prepend (&decl, "(");
3674 string_append (&decl, ")");
3676 string_append (&decl, "[");
3677 if (**mangled != '_')
3678 success = demangle_template_value_parm (work, mangled, &decl,
3679 tk_integral);
3680 if (**mangled == '_')
3681 ++(*mangled);
3682 string_append (&decl, "]");
3683 break;
3686 /* A back reference to a previously seen type */
3687 case 'T':
3688 (*mangled)++;
3689 if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes)
3691 success = 0;
3693 else
3694 for (i = 0; i < work->nproctypes; i++)
3695 if (work -> proctypevec [i] == n)
3696 success = 0;
3698 if (success)
3700 is_proctypevec = 1;
3701 push_processed_type (work, n);
3702 remembered_type = work->typevec[n];
3703 mangled = &remembered_type;
3705 break;
3707 /* A function */
3708 case 'F':
3709 (*mangled)++;
3710 if (!STRING_EMPTY (&decl)
3711 && (decl.b[0] == '*' || decl.b[0] == '&'))
3713 string_prepend (&decl, "(");
3714 string_append (&decl, ")");
3716 /* After picking off the function args, we expect to either find the
3717 function return type (preceded by an '_') or the end of the
3718 string. */
3719 if (!demangle_nested_args (work, mangled, &decl)
3720 || (**mangled != '_' && **mangled != '\0'))
3722 success = 0;
3723 break;
3725 if (success && (**mangled == '_'))
3726 (*mangled)++;
3727 break;
3729 case 'M':
3731 type_quals = TYPE_UNQUALIFIED;
3733 member = **mangled == 'M';
3734 (*mangled)++;
3736 string_append (&decl, ")");
3738 /* We don't need to prepend `::' for a qualified name;
3739 demangle_qualified will do that for us. */
3740 if (**mangled != 'Q')
3741 string_prepend (&decl, SCOPE_STRING (work));
3743 if (ISDIGIT ((unsigned char)**mangled))
3745 n = consume_count (mangled);
3746 if (n == -1
3747 || (int) strlen (*mangled) < n)
3749 success = 0;
3750 break;
3752 string_prependn (&decl, *mangled, n);
3753 *mangled += n;
3755 else if (**mangled == 'X' || **mangled == 'Y')
3757 string temp;
3758 do_type (work, mangled, &temp);
3759 string_prepends (&decl, &temp);
3760 string_delete (&temp);
3762 else if (**mangled == 't')
3764 string temp;
3765 string_init (&temp);
3766 success = demangle_template (work, mangled, &temp,
3767 NULL, 1, 1);
3768 if (success)
3770 string_prependn (&decl, temp.b, temp.p - temp.b);
3771 string_delete (&temp);
3773 else
3775 string_delete (&temp);
3776 break;
3779 else if (**mangled == 'Q')
3781 success = demangle_qualified (work, mangled, &decl,
3782 /*isfuncnam=*/0,
3783 /*append=*/0);
3784 if (!success)
3785 break;
3787 else
3789 success = 0;
3790 break;
3793 string_prepend (&decl, "(");
3794 if (member)
3796 switch (**mangled)
3798 case 'C':
3799 case 'V':
3800 case 'u':
3801 type_quals |= code_for_qualifier (**mangled);
3802 (*mangled)++;
3803 break;
3805 default:
3806 break;
3809 if (*(*mangled) != 'F')
3811 success = 0;
3812 break;
3814 (*mangled)++;
3816 if ((member && !demangle_nested_args (work, mangled, &decl))
3817 || **mangled != '_')
3819 success = 0;
3820 break;
3822 (*mangled)++;
3823 if (! PRINT_ANSI_QUALIFIERS)
3825 break;
3827 if (type_quals != TYPE_UNQUALIFIED)
3829 APPEND_BLANK (&decl);
3830 string_append (&decl, qualifier_string (type_quals));
3832 break;
3834 case 'G':
3835 (*mangled)++;
3836 break;
3838 case 'C':
3839 case 'V':
3840 case 'u':
3841 if (PRINT_ANSI_QUALIFIERS)
3843 if (!STRING_EMPTY (&decl))
3844 string_prepend (&decl, " ");
3846 string_prepend (&decl, demangle_qualifier (**mangled));
3848 (*mangled)++;
3849 break;
3854 /* fall through */
3855 default:
3856 done = 1;
3857 break;
3861 if (success) switch (**mangled)
3863 /* A qualified name, such as "Outer::Inner". */
3864 case 'Q':
3865 case 'K':
3867 success = demangle_qualified (work, mangled, result, 0, 1);
3868 break;
3871 /* A back reference to a previously seen squangled type */
3872 case 'B':
3873 (*mangled)++;
3874 if (!get_count (mangled, &n) || n < 0 || n >= work -> numb)
3875 success = 0;
3876 else
3877 string_append (result, work->btypevec[n]);
3878 break;
3880 case 'X':
3881 case 'Y':
3882 /* A template parm. We substitute the corresponding argument. */
3884 int idx;
3886 (*mangled)++;
3887 idx = consume_count_with_underscores (mangled);
3889 if (idx == -1
3890 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3891 || consume_count_with_underscores (mangled) == -1)
3893 success = 0;
3894 break;
3897 if (work->tmpl_argvec)
3898 string_append (result, work->tmpl_argvec[idx]);
3899 else
3900 string_append_template_idx (result, idx);
3902 success = 1;
3904 break;
3906 default:
3907 success = demangle_fund_type (work, mangled, result);
3908 if (tk == tk_none)
3909 tk = (type_kind_t) success;
3910 break;
3913 if (success)
3915 if (!STRING_EMPTY (&decl))
3917 string_append (result, " ");
3918 string_appends (result, &decl);
3921 else
3922 string_delete (result);
3923 string_delete (&decl);
3925 if (is_proctypevec)
3926 pop_processed_type (work);
3928 if (success)
3929 /* Assume an integral type, if we're not sure. */
3930 return (int) ((tk == tk_none) ? tk_integral : tk);
3931 else
3932 return 0;
3935 /* Given a pointer to a type string that represents a fundamental type
3936 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3937 string in which the demangled output is being built in RESULT, and
3938 the WORK structure, decode the types and add them to the result.
3940 For example:
3942 "Ci" => "const int"
3943 "Sl" => "signed long"
3944 "CUs" => "const unsigned short"
3946 The value returned is really a type_kind_t. */
3948 static int
3949 demangle_fund_type (struct work_stuff *work,
3950 const char **mangled, string *result)
3952 int done = 0;
3953 int success = 1;
3954 char buf[INTBUF_SIZE + 5 /* 'int%u_t' */];
3955 unsigned int dec = 0;
3956 type_kind_t tk = tk_integral;
3958 /* First pick off any type qualifiers. There can be more than one. */
3960 while (!done)
3962 switch (**mangled)
3964 case 'C':
3965 case 'V':
3966 case 'u':
3967 if (PRINT_ANSI_QUALIFIERS)
3969 if (!STRING_EMPTY (result))
3970 string_prepend (result, " ");
3971 string_prepend (result, demangle_qualifier (**mangled));
3973 (*mangled)++;
3974 break;
3975 case 'U':
3976 (*mangled)++;
3977 APPEND_BLANK (result);
3978 string_append (result, "unsigned");
3979 break;
3980 case 'S': /* signed char only */
3981 (*mangled)++;
3982 APPEND_BLANK (result);
3983 string_append (result, "signed");
3984 break;
3985 case 'J':
3986 (*mangled)++;
3987 APPEND_BLANK (result);
3988 string_append (result, "__complex");
3989 break;
3990 default:
3991 done = 1;
3992 break;
3996 /* Now pick off the fundamental type. There can be only one. */
3998 switch (**mangled)
4000 case '\0':
4001 case '_':
4002 break;
4003 case 'v':
4004 (*mangled)++;
4005 APPEND_BLANK (result);
4006 string_append (result, "void");
4007 break;
4008 case 'x':
4009 (*mangled)++;
4010 APPEND_BLANK (result);
4011 string_append (result, "long long");
4012 break;
4013 case 'l':
4014 (*mangled)++;
4015 APPEND_BLANK (result);
4016 string_append (result, "long");
4017 break;
4018 case 'i':
4019 (*mangled)++;
4020 APPEND_BLANK (result);
4021 string_append (result, "int");
4022 break;
4023 case 's':
4024 (*mangled)++;
4025 APPEND_BLANK (result);
4026 string_append (result, "short");
4027 break;
4028 case 'b':
4029 (*mangled)++;
4030 APPEND_BLANK (result);
4031 string_append (result, "bool");
4032 tk = tk_bool;
4033 break;
4034 case 'c':
4035 (*mangled)++;
4036 APPEND_BLANK (result);
4037 string_append (result, "char");
4038 tk = tk_char;
4039 break;
4040 case 'w':
4041 (*mangled)++;
4042 APPEND_BLANK (result);
4043 string_append (result, "wchar_t");
4044 tk = tk_char;
4045 break;
4046 case 'r':
4047 (*mangled)++;
4048 APPEND_BLANK (result);
4049 string_append (result, "long double");
4050 tk = tk_real;
4051 break;
4052 case 'd':
4053 (*mangled)++;
4054 APPEND_BLANK (result);
4055 string_append (result, "double");
4056 tk = tk_real;
4057 break;
4058 case 'f':
4059 (*mangled)++;
4060 APPEND_BLANK (result);
4061 string_append (result, "float");
4062 tk = tk_real;
4063 break;
4064 case 'G':
4065 (*mangled)++;
4066 if (!ISDIGIT ((unsigned char)**mangled))
4068 success = 0;
4069 break;
4071 /* fall through */
4072 case 'I':
4073 (*mangled)++;
4074 if (**mangled == '_')
4076 int i;
4077 (*mangled)++;
4078 for (i = 0;
4079 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
4080 (*mangled)++, i++)
4081 buf[i] = **mangled;
4082 if (**mangled != '_')
4084 success = 0;
4085 break;
4087 buf[i] = '\0';
4088 (*mangled)++;
4090 else
4092 strncpy (buf, *mangled, 2);
4093 buf[2] = '\0';
4094 *mangled += min (strlen (*mangled), 2);
4096 sscanf (buf, "%x", &dec);
4097 sprintf (buf, "int%u_t", dec);
4098 APPEND_BLANK (result);
4099 string_append (result, buf);
4100 break;
4102 /* fall through */
4103 /* An explicit type, such as "6mytype" or "7integer" */
4104 case '0':
4105 case '1':
4106 case '2':
4107 case '3':
4108 case '4':
4109 case '5':
4110 case '6':
4111 case '7':
4112 case '8':
4113 case '9':
4115 int bindex = register_Btype (work);
4116 string btype;
4117 string_init (&btype);
4118 if (demangle_class_name (work, mangled, &btype)) {
4119 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
4120 APPEND_BLANK (result);
4121 string_appends (result, &btype);
4123 else
4124 success = 0;
4125 string_delete (&btype);
4126 break;
4128 case 't':
4130 string btype;
4131 string_init (&btype);
4132 success = demangle_template (work, mangled, &btype, 0, 1, 1);
4133 string_appends (result, &btype);
4134 string_delete (&btype);
4135 break;
4137 default:
4138 success = 0;
4139 break;
4142 return success ? ((int) tk) : 0;
4146 /* Handle a template's value parameter for HP aCC (extension from ARM)
4147 **mangled points to 'S' or 'U' */
4149 static int
4150 do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED,
4151 const char **mangled, string *result)
4153 int unsigned_const;
4155 if (**mangled != 'U' && **mangled != 'S')
4156 return 0;
4158 unsigned_const = (**mangled == 'U');
4160 (*mangled)++;
4162 switch (**mangled)
4164 case 'N':
4165 string_append (result, "-");
4166 /* fall through */
4167 case 'P':
4168 (*mangled)++;
4169 break;
4170 case 'M':
4171 /* special case for -2^31 */
4172 string_append (result, "-2147483648");
4173 (*mangled)++;
4174 return 1;
4175 default:
4176 return 0;
4179 /* We have to be looking at an integer now */
4180 if (!(ISDIGIT ((unsigned char)**mangled)))
4181 return 0;
4183 /* We only deal with integral values for template
4184 parameters -- so it's OK to look only for digits */
4185 while (ISDIGIT ((unsigned char)**mangled))
4187 char_str[0] = **mangled;
4188 string_append (result, char_str);
4189 (*mangled)++;
4192 if (unsigned_const)
4193 string_append (result, "U");
4195 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4196 with L or LL suffixes. pai/1997-09-03 */
4198 return 1; /* success */
4201 /* Handle a template's literal parameter for HP aCC (extension from ARM)
4202 **mangled is pointing to the 'A' */
4204 static int
4205 do_hpacc_template_literal (struct work_stuff *work, const char **mangled,
4206 string *result)
4208 int literal_len = 0;
4209 char * recurse;
4210 char * recurse_dem;
4212 if (**mangled != 'A')
4213 return 0;
4215 (*mangled)++;
4217 literal_len = consume_count (mangled);
4219 if (literal_len <= 0
4220 || literal_len > (long) strlen (*mangled))
4221 return 0;
4223 /* Literal parameters are names of arrays, functions, etc. and the
4224 canonical representation uses the address operator */
4225 string_append (result, "&");
4227 /* Now recursively demangle the literal name */
4228 recurse = XNEWVEC (char, literal_len + 1);
4229 memcpy (recurse, *mangled, literal_len);
4230 recurse[literal_len] = '\000';
4232 recurse_dem = cplus_demangle (recurse, work->options);
4234 if (recurse_dem)
4236 string_append (result, recurse_dem);
4237 free (recurse_dem);
4239 else
4241 string_appendn (result, *mangled, literal_len);
4243 (*mangled) += literal_len;
4244 free (recurse);
4246 return 1;
4249 static int
4250 snarf_numeric_literal (const char **args, string *arg)
4252 if (**args == '-')
4254 char_str[0] = '-';
4255 string_append (arg, char_str);
4256 (*args)++;
4258 else if (**args == '+')
4259 (*args)++;
4261 if (!ISDIGIT ((unsigned char)**args))
4262 return 0;
4264 while (ISDIGIT ((unsigned char)**args))
4266 char_str[0] = **args;
4267 string_append (arg, char_str);
4268 (*args)++;
4271 return 1;
4274 /* Demangle the next argument, given by MANGLED into RESULT, which
4275 *should be an uninitialized* string. It will be initialized here,
4276 and free'd should anything go wrong. */
4278 static int
4279 do_arg (struct work_stuff *work, const char **mangled, string *result)
4281 /* Remember where we started so that we can record the type, for
4282 non-squangling type remembering. */
4283 const char *start = *mangled;
4285 string_init (result);
4287 if (work->nrepeats > 0)
4289 --work->nrepeats;
4291 if (work->previous_argument == 0)
4292 return 0;
4294 /* We want to reissue the previous type in this argument list. */
4295 string_appends (result, work->previous_argument);
4296 return 1;
4299 if (**mangled == 'n')
4301 /* A squangling-style repeat. */
4302 (*mangled)++;
4303 work->nrepeats = consume_count(mangled);
4305 if (work->nrepeats <= 0)
4306 /* This was not a repeat count after all. */
4307 return 0;
4309 if (work->nrepeats > 9)
4311 if (**mangled != '_')
4312 /* The repeat count should be followed by an '_' in this
4313 case. */
4314 return 0;
4315 else
4316 (*mangled)++;
4319 /* Now, the repeat is all set up. */
4320 return do_arg (work, mangled, result);
4323 /* Save the result in WORK->previous_argument so that we can find it
4324 if it's repeated. Note that saving START is not good enough: we
4325 do not want to add additional types to the back-referenceable
4326 type vector when processing a repeated type. */
4327 if (work->previous_argument)
4328 string_delete (work->previous_argument);
4329 else
4330 work->previous_argument = XNEW (string);
4332 if (!do_type (work, mangled, work->previous_argument))
4333 return 0;
4335 string_appends (result, work->previous_argument);
4337 remember_type (work, start, *mangled - start);
4338 return 1;
4341 static void
4342 push_processed_type (struct work_stuff *work, int typevec_index)
4344 if (work->nproctypes >= work->proctypevec_size)
4346 if (!work->proctypevec_size)
4348 work->proctypevec_size = 4;
4349 work->proctypevec = XNEWVEC (int, work->proctypevec_size);
4351 else
4353 if (work->proctypevec_size < 16)
4354 /* Double when small. */
4355 work->proctypevec_size *= 2;
4356 else
4358 /* Grow slower when large. */
4359 if (work->proctypevec_size > (INT_MAX / 3) * 2)
4360 xmalloc_failed (INT_MAX);
4361 work->proctypevec_size = (work->proctypevec_size * 3 / 2);
4363 work->proctypevec
4364 = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size);
4367 work->proctypevec [work->nproctypes++] = typevec_index;
4370 static void
4371 pop_processed_type (struct work_stuff *work)
4373 work->nproctypes--;
4376 static void
4377 remember_type (struct work_stuff *work, const char *start, int len)
4379 char *tem;
4381 if (work->forgetting_types)
4382 return;
4384 if (work -> ntypes >= work -> typevec_size)
4386 if (work -> typevec_size == 0)
4388 work -> typevec_size = 3;
4389 work -> typevec = XNEWVEC (char *, work->typevec_size);
4391 else
4393 if (work -> typevec_size > INT_MAX / 2)
4394 xmalloc_failed (INT_MAX);
4395 work -> typevec_size *= 2;
4396 work -> typevec
4397 = XRESIZEVEC (char *, work->typevec, work->typevec_size);
4400 tem = XNEWVEC (char, len + 1);
4401 memcpy (tem, start, len);
4402 tem[len] = '\0';
4403 work -> typevec[work -> ntypes++] = tem;
4407 /* Remember a K type class qualifier. */
4408 static void
4409 remember_Ktype (struct work_stuff *work, const char *start, int len)
4411 char *tem;
4413 if (work -> numk >= work -> ksize)
4415 if (work -> ksize == 0)
4417 work -> ksize = 5;
4418 work -> ktypevec = XNEWVEC (char *, work->ksize);
4420 else
4422 if (work -> ksize > INT_MAX / 2)
4423 xmalloc_failed (INT_MAX);
4424 work -> ksize *= 2;
4425 work -> ktypevec
4426 = XRESIZEVEC (char *, work->ktypevec, work->ksize);
4429 tem = XNEWVEC (char, len + 1);
4430 memcpy (tem, start, len);
4431 tem[len] = '\0';
4432 work -> ktypevec[work -> numk++] = tem;
4435 /* Register a B code, and get an index for it. B codes are registered
4436 as they are seen, rather than as they are completed, so map<temp<char> >
4437 registers map<temp<char> > as B0, and temp<char> as B1 */
4439 static int
4440 register_Btype (struct work_stuff *work)
4442 int ret;
4444 if (work -> numb >= work -> bsize)
4446 if (work -> bsize == 0)
4448 work -> bsize = 5;
4449 work -> btypevec = XNEWVEC (char *, work->bsize);
4451 else
4453 if (work -> bsize > INT_MAX / 2)
4454 xmalloc_failed (INT_MAX);
4455 work -> bsize *= 2;
4456 work -> btypevec
4457 = XRESIZEVEC (char *, work->btypevec, work->bsize);
4460 ret = work -> numb++;
4461 work -> btypevec[ret] = NULL;
4462 return(ret);
4465 /* Store a value into a previously registered B code type. */
4467 static void
4468 remember_Btype (struct work_stuff *work, const char *start,
4469 int len, int index)
4471 char *tem;
4473 tem = XNEWVEC (char, len + 1);
4474 memcpy (tem, start, len);
4475 tem[len] = '\0';
4476 work -> btypevec[index] = tem;
4479 /* Lose all the info related to B and K type codes. */
4480 static void
4481 forget_B_and_K_types (struct work_stuff *work)
4483 int i;
4485 while (work -> numk > 0)
4487 i = --(work -> numk);
4488 if (work -> ktypevec[i] != NULL)
4490 free (work -> ktypevec[i]);
4491 work -> ktypevec[i] = NULL;
4495 while (work -> numb > 0)
4497 i = --(work -> numb);
4498 if (work -> btypevec[i] != NULL)
4500 free (work -> btypevec[i]);
4501 work -> btypevec[i] = NULL;
4505 /* Forget the remembered types, but not the type vector itself. */
4507 static void
4508 forget_types (struct work_stuff *work)
4510 int i;
4512 while (work -> ntypes > 0)
4514 i = --(work -> ntypes);
4515 if (work -> typevec[i] != NULL)
4517 free (work -> typevec[i]);
4518 work -> typevec[i] = NULL;
4523 /* Process the argument list part of the signature, after any class spec
4524 has been consumed, as well as the first 'F' character (if any). For
4525 example:
4527 "__als__3fooRT0" => process "RT0"
4528 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4530 DECLP must be already initialised, usually non-empty. It won't be freed
4531 on failure.
4533 Note that g++ differs significantly from ARM and lucid style mangling
4534 with regards to references to previously seen types. For example, given
4535 the source fragment:
4537 class foo {
4538 public:
4539 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4542 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4543 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4545 g++ produces the names:
4547 __3fooiRT0iT2iT2
4548 foo__FiR3fooiT1iT1
4550 while lcc (and presumably other ARM style compilers as well) produces:
4552 foo__FiR3fooT1T2T1T2
4553 __ct__3fooFiR3fooT1T2T1T2
4555 Note that g++ bases its type numbers starting at zero and counts all
4556 previously seen types, while lucid/ARM bases its type numbers starting
4557 at one and only considers types after it has seen the 'F' character
4558 indicating the start of the function args. For lucid/ARM style, we
4559 account for this difference by discarding any previously seen types when
4560 we see the 'F' character, and subtracting one from the type number
4561 reference.
4565 static int
4566 demangle_args (struct work_stuff *work, const char **mangled,
4567 string *declp)
4569 string arg;
4570 int need_comma = 0;
4571 int r;
4572 int t;
4573 const char *tem;
4574 char temptype;
4576 if (PRINT_ARG_TYPES)
4578 string_append (declp, "(");
4579 if (**mangled == '\0')
4581 string_append (declp, "void");
4585 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4586 || work->nrepeats > 0)
4588 if ((**mangled == 'N') || (**mangled == 'T'))
4590 temptype = *(*mangled)++;
4592 if (temptype == 'N')
4594 if (!get_count (mangled, &r))
4596 return (0);
4599 else
4601 r = 1;
4603 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
4605 /* If we have 10 or more types we might have more than a 1 digit
4606 index so we'll have to consume the whole count here. This
4607 will lose if the next thing is a type name preceded by a
4608 count but it's impossible to demangle that case properly
4609 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4610 Pc, ...)" or "(..., type12, char *, ...)" */
4611 if ((t = consume_count(mangled)) <= 0)
4613 return (0);
4616 else
4618 if (!get_count (mangled, &t))
4620 return (0);
4623 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4625 t--;
4627 /* Validate the type index. Protect against illegal indices from
4628 malformed type strings. */
4629 if ((t < 0) || (t >= work -> ntypes))
4631 return (0);
4633 while (work->nrepeats > 0 || --r >= 0)
4635 tem = work -> typevec[t];
4636 if (need_comma && PRINT_ARG_TYPES)
4638 string_append (declp, ", ");
4640 push_processed_type (work, t);
4641 if (!do_arg (work, &tem, &arg))
4643 pop_processed_type (work);
4644 return (0);
4646 pop_processed_type (work);
4647 if (PRINT_ARG_TYPES)
4649 string_appends (declp, &arg);
4651 string_delete (&arg);
4652 need_comma = 1;
4655 else
4657 if (need_comma && PRINT_ARG_TYPES)
4658 string_append (declp, ", ");
4659 if (!do_arg (work, mangled, &arg))
4660 return (0);
4661 if (PRINT_ARG_TYPES)
4662 string_appends (declp, &arg);
4663 string_delete (&arg);
4664 need_comma = 1;
4668 if (**mangled == 'e')
4670 (*mangled)++;
4671 if (PRINT_ARG_TYPES)
4673 if (need_comma)
4675 string_append (declp, ",");
4677 string_append (declp, "...");
4681 if (PRINT_ARG_TYPES)
4683 string_append (declp, ")");
4685 return (1);
4688 /* Like demangle_args, but for demangling the argument lists of function
4689 and method pointers or references, not top-level declarations. */
4691 static int
4692 demangle_nested_args (struct work_stuff *work, const char **mangled,
4693 string *declp)
4695 string* saved_previous_argument;
4696 int result;
4697 int saved_nrepeats;
4699 /* The G++ name-mangling algorithm does not remember types on nested
4700 argument lists, unless -fsquangling is used, and in that case the
4701 type vector updated by remember_type is not used. So, we turn
4702 off remembering of types here. */
4703 ++work->forgetting_types;
4705 /* For the repeat codes used with -fsquangling, we must keep track of
4706 the last argument. */
4707 saved_previous_argument = work->previous_argument;
4708 saved_nrepeats = work->nrepeats;
4709 work->previous_argument = 0;
4710 work->nrepeats = 0;
4712 /* Actually demangle the arguments. */
4713 result = demangle_args (work, mangled, declp);
4715 /* Restore the previous_argument field. */
4716 if (work->previous_argument)
4718 string_delete (work->previous_argument);
4719 free ((char *) work->previous_argument);
4721 work->previous_argument = saved_previous_argument;
4722 --work->forgetting_types;
4723 work->nrepeats = saved_nrepeats;
4725 return result;
4728 /* Returns 1 if a valid function name was found or 0 otherwise. */
4730 static int
4731 demangle_function_name (struct work_stuff *work, const char **mangled,
4732 string *declp, const char *scan)
4734 size_t i;
4735 string type;
4736 const char *tem;
4738 string_appendn (declp, (*mangled), scan - (*mangled));
4739 string_need (declp, 1);
4740 *(declp -> p) = '\0';
4742 /* Consume the function name, including the "__" separating the name
4743 from the signature. We are guaranteed that SCAN points to the
4744 separator. */
4746 (*mangled) = scan + 2;
4747 /* We may be looking at an instantiation of a template function:
4748 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4749 following _F marks the start of the function arguments. Handle
4750 the template arguments first. */
4752 if (HP_DEMANGLING && (**mangled == 'X'))
4754 demangle_arm_hp_template (work, mangled, 0, declp);
4755 /* This leaves MANGLED pointing to the 'F' marking func args */
4758 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
4761 /* See if we have an ARM style constructor or destructor operator.
4762 If so, then just record it, clear the decl, and return.
4763 We can't build the actual constructor/destructor decl until later,
4764 when we recover the class name from the signature. */
4766 if (strcmp (declp -> b, "__ct") == 0)
4768 work -> constructor += 1;
4769 string_clear (declp);
4770 return 1;
4772 else if (strcmp (declp -> b, "__dt") == 0)
4774 work -> destructor += 1;
4775 string_clear (declp);
4776 return 1;
4780 if (declp->p - declp->b >= 3
4781 && declp->b[0] == 'o'
4782 && declp->b[1] == 'p'
4783 && strchr (cplus_markers, declp->b[2]) != NULL)
4785 /* see if it's an assignment expression */
4786 if (declp->p - declp->b >= 10 /* op$assign_ */
4787 && memcmp (declp->b + 3, "assign_", 7) == 0)
4789 for (i = 0; i < ARRAY_SIZE (optable); i++)
4791 int len = declp->p - declp->b - 10;
4792 if ((int) strlen (optable[i].in) == len
4793 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4795 string_clear (declp);
4796 string_append (declp, "operator");
4797 string_append (declp, optable[i].out);
4798 string_append (declp, "=");
4799 break;
4803 else
4805 for (i = 0; i < ARRAY_SIZE (optable); i++)
4807 int len = declp->p - declp->b - 3;
4808 if ((int) strlen (optable[i].in) == len
4809 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4811 string_clear (declp);
4812 string_append (declp, "operator");
4813 string_append (declp, optable[i].out);
4814 break;
4819 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4820 && strchr (cplus_markers, declp->b[4]) != NULL)
4822 /* type conversion operator */
4823 tem = declp->b + 5;
4824 if (do_type (work, &tem, &type))
4826 string_clear (declp);
4827 string_append (declp, "operator ");
4828 string_appends (declp, &type);
4829 string_delete (&type);
4832 else if (declp->b[0] == '_' && declp->b[1] == '_'
4833 && declp->b[2] == 'o' && declp->b[3] == 'p')
4835 /* ANSI. */
4836 /* type conversion operator. */
4837 tem = declp->b + 4;
4838 if (do_type (work, &tem, &type))
4840 string_clear (declp);
4841 string_append (declp, "operator ");
4842 string_appends (declp, &type);
4843 string_delete (&type);
4846 else if (declp->b[0] == '_' && declp->b[1] == '_'
4847 && ISLOWER((unsigned char)declp->b[2])
4848 && ISLOWER((unsigned char)declp->b[3]))
4850 if (declp->b[4] == '\0')
4852 /* Operator. */
4853 for (i = 0; i < ARRAY_SIZE (optable); i++)
4855 if (strlen (optable[i].in) == 2
4856 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4858 string_clear (declp);
4859 string_append (declp, "operator");
4860 string_append (declp, optable[i].out);
4861 break;
4865 else
4867 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4869 /* Assignment. */
4870 for (i = 0; i < ARRAY_SIZE (optable); i++)
4872 if (strlen (optable[i].in) == 3
4873 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4875 string_clear (declp);
4876 string_append (declp, "operator");
4877 string_append (declp, optable[i].out);
4878 break;
4885 /* If a function name was obtained but it's not valid, we were not
4886 successful. */
4887 if (LEN_STRING (declp) == 1 && declp->b[0] == '.')
4888 return 0;
4889 else
4890 return 1;
4893 /* a mini string-handling package */
4895 static void
4896 string_need (string *s, int n)
4898 int tem;
4900 if (s->b == NULL)
4902 if (n < 32)
4904 n = 32;
4906 s->p = s->b = XNEWVEC (char, n);
4907 s->e = s->b + n;
4909 else if (s->e - s->p < n)
4911 tem = s->p - s->b;
4912 if (n > INT_MAX / 2 - tem)
4913 xmalloc_failed (INT_MAX);
4914 n += tem;
4915 n *= 2;
4916 s->b = XRESIZEVEC (char, s->b, n);
4917 s->p = s->b + tem;
4918 s->e = s->b + n;
4922 static void
4923 string_delete (string *s)
4925 if (s->b != NULL)
4927 free (s->b);
4928 s->b = s->e = s->p = NULL;
4932 static void
4933 string_init (string *s)
4935 s->b = s->p = s->e = NULL;
4938 static void
4939 string_clear (string *s)
4941 s->p = s->b;
4944 #if 0
4946 static int
4947 string_empty (string *s)
4949 return (s->b == s->p);
4952 #endif
4954 static void
4955 string_append (string *p, const char *s)
4957 int n;
4958 if (s == NULL || *s == '\0')
4959 return;
4960 n = strlen (s);
4961 string_need (p, n);
4962 memcpy (p->p, s, n);
4963 p->p += n;
4966 static void
4967 string_appends (string *p, string *s)
4969 int n;
4971 if (s->b != s->p)
4973 n = s->p - s->b;
4974 string_need (p, n);
4975 memcpy (p->p, s->b, n);
4976 p->p += n;
4980 static void
4981 string_appendn (string *p, const char *s, int n)
4983 if (n != 0)
4985 string_need (p, n);
4986 memcpy (p->p, s, n);
4987 p->p += n;
4991 static void
4992 string_prepend (string *p, const char *s)
4994 if (s != NULL && *s != '\0')
4996 string_prependn (p, s, strlen (s));
5000 static void
5001 string_prepends (string *p, string *s)
5003 if (s->b != s->p)
5005 string_prependn (p, s->b, s->p - s->b);
5009 static void
5010 string_prependn (string *p, const char *s, int n)
5012 char *q;
5014 if (n != 0)
5016 string_need (p, n);
5017 for (q = p->p - 1; q >= p->b; q--)
5019 q[n] = q[0];
5021 memcpy (p->b, s, n);
5022 p->p += n;
5026 static void
5027 string_append_template_idx (string *s, int idx)
5029 char buf[INTBUF_SIZE + 1 /* 'T' */];
5030 sprintf(buf, "T%d", idx);
5031 string_append (s, buf);