]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/cplus-dem.c
c-tree.texi, tm.texi: Consistently put NULL and NULL_TREE inside @code.
[thirdparty/gcc.git] / libiberty / cplus-dem.c
CommitLineData
2363489c 1/* Demangler for GNU C++
2f26c11d 2 Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
3b60dd8e 3 2000, 2001 Free Software Foundation, Inc.
6599da04
JM
4 Written by James Clark (jjc@jclark.uucp)
5 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
70d5ccef 6 Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
2363489c 7
6599da04
JM
8This file is part of the libiberty library.
9Libiberty is free software; you can redistribute it and/or
10modify it under the terms of the GNU Library General Public
11License as published by the Free Software Foundation; either
12version 2 of the License, or (at your option) any later version.
13
14Libiberty is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17Library General Public License for more details.
18
19You should have received a copy of the GNU Library General Public
20License along with libiberty; see the file COPYING.LIB. If
21not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22Boston, MA 02111-1307, USA. */
23
24/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
25
26 This file imports xmalloc and xrealloc, which are like malloc and
27 realloc except that they generate a fatal error if there is no
28 available memory. */
29
30/* This file lives in both GCC and libiberty. When making changes, please
31 try not to break either. */
32
a7825625
KG
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
f6bbde28
ZW
37#include "safe-ctype.h"
38
9ee02b5c 39#include <sys/types.h>
6599da04
JM
40#include <string.h>
41#include <stdio.h>
42
9ee02b5c
JL
43#ifdef HAVE_STDLIB_H
44#include <stdlib.h>
a7825625
KG
45#else
46char * malloc ();
47char * realloc ();
9ee02b5c
JL
48#endif
49
6599da04
JM
50#include <demangle.h>
51#undef CURRENT_DEMANGLING_STYLE
52#define CURRENT_DEMANGLING_STYLE work->options
53
9b1a92d8 54#include "libiberty.h"
6599da04 55
cf183ac2 56static char *ada_demangle PARAMS ((const char *, int));
61ab980a 57
53504016
SG
58#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
59
b60fe4a7
MM
60/* A value at least one greater than the maximum number of characters
61 that will be output when using the `%d' format with `printf'. */
62#define INTBUF_SIZE 32
63
2a138827
KG
64extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
65
6599da04
JM
66static const char *mystrstr PARAMS ((const char *, const char *));
67
68static const char *
69mystrstr (s1, s2)
70 const char *s1, *s2;
71{
72 register const char *p = s1;
73 register int len = strlen (s2);
74
75 for (; (p = strchr (p, *s2)) != 0; p++)
76 {
77 if (strncmp (p, s2, len) == 0)
78 {
79 return (p);
80 }
81 }
82 return (0);
83}
84
85/* In order to allow a single demangler executable to demangle strings
86 using various common values of CPLUS_MARKER, as well as any specific
87 one set at compile time, we maintain a string containing all the
88 commonly used ones, and check to see if the marker we are looking for
89 is in that string. CPLUS_MARKER is usually '$' on systems where the
90 assembler can deal with that. Where the assembler can't, it's usually
91 '.' (but on many systems '.' is used for other things). We put the
92 current defined CPLUS_MARKER first (which defaults to '$'), followed
93 by the next most common value, followed by an explicit '$' in case
94 the value of CPLUS_MARKER is not '$'.
95
96 We could avoid this if we could just get g++ to tell us what the actual
97 cplus marker character is as part of the debug information, perhaps by
98 ensuring that it is the character that terminates the gcc<n>_compiled
99 marker symbol (FIXME). */
100
101#if !defined (CPLUS_MARKER)
102#define CPLUS_MARKER '$'
103#endif
104
c6e13630 105enum demangling_styles current_demangling_style = auto_demangling;
6599da04
JM
106
107static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' };
108
70d5ccef
DT
109static char char_str[2] = { '\000', '\000' };
110
6599da04
JM
111void
112set_cplus_marker_for_demangling (ch)
113 int ch;
114{
115 cplus_markers[0] = ch;
116}
117
9923cc56
MM
118typedef struct string /* Beware: these aren't required to be */
119{ /* '\0' terminated. */
120 char *b; /* pointer to start of string */
121 char *p; /* pointer after last character */
122 char *e; /* pointer after end of allocated space */
123} string;
124
6599da04
JM
125/* Stuff that is shared between sub-routines.
126 Using a shared structure allows cplus_demangle to be reentrant. */
127
128struct work_stuff
129{
130 int options;
131 char **typevec;
5e5199e8
AM
132 char **ktypevec;
133 char **btypevec;
134 int numk;
135 int numb;
136 int ksize;
137 int bsize;
6599da04
JM
138 int ntypes;
139 int typevec_size;
140 int constructor;
141 int destructor;
142 int static_type; /* A static member function */
2363489c 143 int temp_start; /* index in demangled to start of template args */
91063b51 144 int type_quals; /* The type qualifiers. */
9b559a27 145 int dllimported; /* Symbol imported from a PE DLL */
a3a5b5b7
MM
146 char **tmpl_argvec; /* Template function arguments. */
147 int ntmpl_args; /* The number of template function arguments. */
9923cc56
MM
148 int forgetting_types; /* Nonzero if we are not remembering the types
149 we see. */
150 string* previous_argument; /* The last function argument demangled. */
151 int nrepeats; /* The number of times to repeat the previous
152 argument. */
6599da04
JM
153};
154
155#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
156#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
157
158static const struct optable
159{
160 const char *in;
161 const char *out;
162 int flags;
163} optable[] = {
164 {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */
165 {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */
166 {"new", " new", 0}, /* old (1.91, and 1.x) */
167 {"delete", " delete", 0}, /* old (1.91, and 1.x) */
168 {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */
169 {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */
170 {"as", "=", DMGL_ANSI}, /* ansi */
171 {"ne", "!=", DMGL_ANSI}, /* old, ansi */
172 {"eq", "==", DMGL_ANSI}, /* old, ansi */
173 {"ge", ">=", DMGL_ANSI}, /* old, ansi */
174 {"gt", ">", DMGL_ANSI}, /* old, ansi */
175 {"le", "<=", DMGL_ANSI}, /* old, ansi */
176 {"lt", "<", DMGL_ANSI}, /* old, ansi */
177 {"plus", "+", 0}, /* old */
178 {"pl", "+", DMGL_ANSI}, /* ansi */
179 {"apl", "+=", DMGL_ANSI}, /* ansi */
180 {"minus", "-", 0}, /* old */
181 {"mi", "-", DMGL_ANSI}, /* ansi */
182 {"ami", "-=", DMGL_ANSI}, /* ansi */
183 {"mult", "*", 0}, /* old */
184 {"ml", "*", DMGL_ANSI}, /* ansi */
185 {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */
186 {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */
187 {"convert", "+", 0}, /* old (unary +) */
188 {"negate", "-", 0}, /* old (unary -) */
189 {"trunc_mod", "%", 0}, /* old */
190 {"md", "%", DMGL_ANSI}, /* ansi */
191 {"amd", "%=", DMGL_ANSI}, /* ansi */
192 {"trunc_div", "/", 0}, /* old */
193 {"dv", "/", DMGL_ANSI}, /* ansi */
194 {"adv", "/=", DMGL_ANSI}, /* ansi */
195 {"truth_andif", "&&", 0}, /* old */
196 {"aa", "&&", DMGL_ANSI}, /* ansi */
197 {"truth_orif", "||", 0}, /* old */
198 {"oo", "||", DMGL_ANSI}, /* ansi */
199 {"truth_not", "!", 0}, /* old */
200 {"nt", "!", DMGL_ANSI}, /* ansi */
201 {"postincrement","++", 0}, /* old */
202 {"pp", "++", DMGL_ANSI}, /* ansi */
203 {"postdecrement","--", 0}, /* old */
204 {"mm", "--", DMGL_ANSI}, /* ansi */
205 {"bit_ior", "|", 0}, /* old */
206 {"or", "|", DMGL_ANSI}, /* ansi */
207 {"aor", "|=", DMGL_ANSI}, /* ansi */
208 {"bit_xor", "^", 0}, /* old */
209 {"er", "^", DMGL_ANSI}, /* ansi */
210 {"aer", "^=", DMGL_ANSI}, /* ansi */
211 {"bit_and", "&", 0}, /* old */
212 {"ad", "&", DMGL_ANSI}, /* ansi */
213 {"aad", "&=", DMGL_ANSI}, /* ansi */
214 {"bit_not", "~", 0}, /* old */
215 {"co", "~", DMGL_ANSI}, /* ansi */
216 {"call", "()", 0}, /* old */
217 {"cl", "()", DMGL_ANSI}, /* ansi */
218 {"alshift", "<<", 0}, /* old */
219 {"ls", "<<", DMGL_ANSI}, /* ansi */
220 {"als", "<<=", DMGL_ANSI}, /* ansi */
221 {"arshift", ">>", 0}, /* old */
222 {"rs", ">>", DMGL_ANSI}, /* ansi */
223 {"ars", ">>=", DMGL_ANSI}, /* ansi */
224 {"component", "->", 0}, /* old */
225 {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */
226 {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */
227 {"indirect", "*", 0}, /* old */
228 {"method_call", "->()", 0}, /* old */
229 {"addr", "&", 0}, /* old (unary &) */
230 {"array", "[]", 0}, /* old */
231 {"vc", "[]", DMGL_ANSI}, /* ansi */
232 {"compound", ", ", 0}, /* old */
233 {"cm", ", ", DMGL_ANSI}, /* ansi */
234 {"cond", "?:", 0}, /* old */
235 {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */
236 {"max", ">?", 0}, /* old */
237 {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */
238 {"min", "<?", 0}, /* old */
239 {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */
240 {"nop", "", 0}, /* old (for operator=) */
f9c85454
MM
241 {"rm", "->*", DMGL_ANSI}, /* ansi */
242 {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */
6599da04
JM
243};
244
4d17a06f
MM
245/* These values are used to indicate the various type varieties.
246 They are all non-zero so that they can be used as `success'
247 values. */
2363489c
UD
248typedef enum type_kind_t
249{
4d17a06f
MM
250 tk_none,
251 tk_pointer,
ec2288ff 252 tk_reference,
2363489c 253 tk_integral,
4d17a06f 254 tk_bool,
2363489c 255 tk_char,
4d17a06f
MM
256 tk_real
257} type_kind_t;
2363489c 258
24eaa47a
KB
259struct demangler_engine libiberty_demanglers[] =
260{
261 {
262 AUTO_DEMANGLING_STYLE_STRING,
263 auto_demangling,
264 "Automatic selection based on executable"
265 }
266 ,
267 {
268 GNU_DEMANGLING_STYLE_STRING,
269 gnu_demangling,
270 "GNU (g++) style demangling"
271 }
272 ,
273 {
274 LUCID_DEMANGLING_STYLE_STRING,
275 lucid_demangling,
276 "Lucid (lcc) style demangling"
277 }
278 ,
279 {
280 ARM_DEMANGLING_STYLE_STRING,
281 arm_demangling,
282 "ARM style demangling"
283 }
284 ,
285 {
286 HP_DEMANGLING_STYLE_STRING,
287 hp_demangling,
288 "HP (aCC) style demangling"
289 }
290 ,
291 {
292 EDG_DEMANGLING_STYLE_STRING,
293 edg_demangling,
294 "EDG style demangling"
295 }
296 ,
69afa80d 297 {
c6e13630
JM
298 GNU_V3_DEMANGLING_STYLE_STRING,
299 gnu_v3_demangling,
300 "GNU (g++) V3 ABI-style demangling"
69afa80d
AS
301 }
302 ,
61ab980a
KB
303 {
304 JAVA_DEMANGLING_STYLE_STRING,
305 java_demangling,
306 "Java style demangling"
307 }
308 ,
309 {
310 GNAT_DEMANGLING_STYLE_STRING,
311 gnat_demangling,
312 "GNAT style demangling"
313 }
314 ,
24eaa47a
KB
315 {
316 NULL, unknown_demangling, NULL
317 }
318};
319
6599da04
JM
320#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
321#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
322 string_prepend(str, " ");}
323#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
324 string_append(str, " ");}
5e5199e8 325#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
6599da04 326
9923cc56 327/* The scope separator appropriate for the language being demangled. */
3510075c
JL
328
329#define SCOPE_STRING(work) ((work->options & DMGL_JAVA) ? "." : "::")
9923cc56 330
6599da04
JM
331#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
332#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
333
334/* Prototypes for local functions */
335
3388651c
DB
336static void
337delete_work_stuff PARAMS ((struct work_stuff *));
338
339static void
340delete_non_B_K_work_stuff PARAMS ((struct work_stuff *));
341
6599da04
JM
342static char *
343mop_up PARAMS ((struct work_stuff *, string *, int));
344
d6f4ec51 345static void
5e5199e8
AM
346squangle_mop_up PARAMS ((struct work_stuff *));
347
3388651c
DB
348static void
349work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
350
6599da04
JM
351#if 0
352static int
5e5199e8 353demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
6599da04
JM
354#endif
355
5e5199e8 356static char *
d6f4ec51 357internal_cplus_demangle PARAMS ((struct work_stuff *, const char *));
5e5199e8 358
9ee02b5c 359static int
2363489c 360demangle_template_template_parm PARAMS ((struct work_stuff *work,
9ee02b5c
JL
361 const char **, string *));
362
6599da04
JM
363static int
364demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
9923cc56 365 string *, int, int));
6599da04
JM
366
367static int
368arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
369 const char **));
370
6599da04
JM
371static int
372demangle_class_name PARAMS ((struct work_stuff *, const char **, string *));
373
374static int
375demangle_qualified PARAMS ((struct work_stuff *, const char **, string *,
376 int, int));
377
378static int
379demangle_class PARAMS ((struct work_stuff *, const char **, string *));
380
381static int
382demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *));
383
384static int
385demangle_signature PARAMS ((struct work_stuff *, const char **, string *));
386
387static int
388demangle_prefix PARAMS ((struct work_stuff *, const char **, string *));
389
390static int
391gnu_special PARAMS ((struct work_stuff *, const char **, string *));
392
393static int
9ee02b5c 394arm_special PARAMS ((const char **, string *));
6599da04
JM
395
396static void
397string_need PARAMS ((string *, int));
398
399static void
400string_delete PARAMS ((string *));
401
402static void
403string_init PARAMS ((string *));
404
405static void
406string_clear PARAMS ((string *));
407
408#if 0
409static int
410string_empty PARAMS ((string *));
411#endif
412
413static void
414string_append PARAMS ((string *, const char *));
415
416static void
417string_appends PARAMS ((string *, string *));
418
419static void
420string_appendn PARAMS ((string *, const char *, int));
421
422static void
423string_prepend PARAMS ((string *, const char *));
424
425static void
426string_prependn PARAMS ((string *, const char *, int));
427
b60fe4a7
MM
428static void
429string_append_template_idx PARAMS ((string *, int));
430
6599da04
JM
431static int
432get_count PARAMS ((const char **, int *));
433
434static int
435consume_count PARAMS ((const char **));
436
2363489c 437static int
a3a5b5b7
MM
438consume_count_with_underscores PARAMS ((const char**));
439
6599da04
JM
440static int
441demangle_args PARAMS ((struct work_stuff *, const char **, string *));
442
9923cc56
MM
443static int
444demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
445
6599da04
JM
446static int
447do_type PARAMS ((struct work_stuff *, const char **, string *));
448
449static int
450do_arg PARAMS ((struct work_stuff *, const char **, string *));
451
452static void
453demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
454 const char *));
455
3388651c
DB
456static int
457iterate_demangle_function PARAMS ((struct work_stuff *,
458 const char **, string *, const char *));
459
6599da04
JM
460static void
461remember_type PARAMS ((struct work_stuff *, const char *, int));
462
5e5199e8
AM
463static void
464remember_Btype PARAMS ((struct work_stuff *, const char *, int, int));
465
466static int
467register_Btype PARAMS ((struct work_stuff *));
468
469static void
470remember_Ktype PARAMS ((struct work_stuff *, const char *, int));
471
6599da04
JM
472static void
473forget_types PARAMS ((struct work_stuff *));
474
5e5199e8
AM
475static void
476forget_B_and_K_types PARAMS ((struct work_stuff *));
477
6599da04
JM
478static void
479string_prepends PARAMS ((string *, string *));
480
2363489c
UD
481static int
482demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
4d17a06f 483 string*, type_kind_t));
f9c85454 484
2363489c 485static int
70d5ccef
DT
486do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *));
487
2363489c 488static int
70d5ccef
DT
489do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *));
490
2363489c 491static int
087aa398 492snarf_numeric_literal PARAMS ((const char **, string *));
70d5ccef 493
91063b51
MM
494/* There is a TYPE_QUAL value for each type qualifier. They can be
495 combined by bitwise-or to form the complete set of qualifiers for a
496 type. */
497
498#define TYPE_UNQUALIFIED 0x0
499#define TYPE_QUAL_CONST 0x1
500#define TYPE_QUAL_VOLATILE 0x2
501#define TYPE_QUAL_RESTRICT 0x4
502
2363489c 503static int
087aa398 504code_for_qualifier PARAMS ((int));
91063b51
MM
505
506static const char*
507qualifier_string PARAMS ((int));
508
509static const char*
087aa398 510demangle_qualifier PARAMS ((int));
91063b51 511
b60fe4a7
MM
512static int
513demangle_expression PARAMS ((struct work_stuff *, const char **, string *,
514 type_kind_t));
515
2a138827
KG
516static int
517demangle_integral_value PARAMS ((struct work_stuff *, const char **,
518 string *));
519
b60fe4a7
MM
520static int
521demangle_real_value PARAMS ((struct work_stuff *, const char **, string *));
522
2a138827
KG
523static void
524demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int,
525 string *));
526
527static void
528recursively_demangle PARAMS ((struct work_stuff *, const char **, string *,
529 int));
530
8bcc782c 531static void
cf183ac2 532grow_vect PARAMS ((void **, size_t *, size_t, int));
8bcc782c 533
9d229989
JB
534/* Translate count to integer, consuming tokens in the process.
535 Conversion terminates on the first non-digit character.
536
537 Trying to consume something that isn't a count results in no
538 consumption of input and a return of -1.
539
540 Overflow consumes the rest of the digits, and returns -1. */
6599da04
JM
541
542static int
543consume_count (type)
544 const char **type;
545{
9d229989
JB
546 int count = 0;
547
f6bbde28 548 if (! ISDIGIT ((unsigned char)**type))
9d229989 549 return -1;
6599da04 550
f6bbde28 551 while (ISDIGIT ((unsigned char)**type))
6599da04
JM
552 {
553 count *= 10;
9d229989
JB
554
555 /* Check for overflow.
556 We assume that count is represented using two's-complement;
557 no power of two is divisible by ten, so if an overflow occurs
558 when multiplying by ten, the result will not be a multiple of
559 ten. */
560 if ((count % 10) != 0)
4cc48683 561 {
f6bbde28 562 while (ISDIGIT ((unsigned char) **type))
9d229989
JB
563 (*type)++;
564 return -1;
4cc48683 565 }
9d229989
JB
566
567 count += **type - '0';
6599da04
JM
568 (*type)++;
569 }
9d229989 570
6599da04
JM
571 return (count);
572}
573
a3a5b5b7 574
9ee02b5c 575/* Like consume_count, but for counts that are preceded and followed
a3a5b5b7
MM
576 by '_' if they are greater than 10. Also, -1 is returned for
577 failure, since 0 can be a valid value. */
578
579static int
580consume_count_with_underscores (mangled)
581 const char **mangled;
582{
583 int idx;
584
585 if (**mangled == '_')
586 {
587 (*mangled)++;
f6bbde28 588 if (!ISDIGIT ((unsigned char)**mangled))
a3a5b5b7
MM
589 return -1;
590
591 idx = consume_count (mangled);
592 if (**mangled != '_')
593 /* The trailing underscore was missing. */
594 return -1;
2363489c 595
a3a5b5b7
MM
596 (*mangled)++;
597 }
598 else
599 {
600 if (**mangled < '0' || **mangled > '9')
601 return -1;
2363489c 602
a3a5b5b7
MM
603 idx = **mangled - '0';
604 (*mangled)++;
605 }
606
607 return idx;
608}
609
91063b51
MM
610/* C is the code for a type-qualifier. Return the TYPE_QUAL
611 corresponding to this qualifier. */
612
613static int
614code_for_qualifier (c)
087aa398 615 int c;
91063b51 616{
2363489c 617 switch (c)
91063b51
MM
618 {
619 case 'C':
620 return TYPE_QUAL_CONST;
621
622 case 'V':
623 return TYPE_QUAL_VOLATILE;
2363489c 624
91063b51
MM
625 case 'u':
626 return TYPE_QUAL_RESTRICT;
627
628 default:
629 break;
630 }
631
632 /* C was an invalid qualifier. */
633 abort ();
634}
635
636/* Return the string corresponding to the qualifiers given by
637 TYPE_QUALS. */
638
639static const char*
640qualifier_string (type_quals)
641 int type_quals;
642{
643 switch (type_quals)
644 {
645 case TYPE_UNQUALIFIED:
646 return "";
647
648 case TYPE_QUAL_CONST:
649 return "const";
650
651 case TYPE_QUAL_VOLATILE:
652 return "volatile";
653
654 case TYPE_QUAL_RESTRICT:
655 return "__restrict";
656
657 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
658 return "const volatile";
659
660 case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
661 return "const __restrict";
662
663 case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
664 return "volatile __restrict";
665
666 case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
667 return "const volatile __restrict";
668
669 default:
670 break;
671 }
672
673 /* TYPE_QUALS was an invalid qualifier set. */
674 abort ();
675}
676
677/* C is the code for a type-qualifier. Return the string
678 corresponding to this qualifier. This function should only be
679 called with a valid qualifier code. */
680
681static const char*
682demangle_qualifier (c)
087aa398 683 int c;
91063b51
MM
684{
685 return qualifier_string (code_for_qualifier (c));
686}
687
6599da04
JM
688int
689cplus_demangle_opname (opname, result, options)
690 const char *opname;
691 char *result;
692 int options;
693{
d6f4ec51 694 int len, len1, ret;
6599da04
JM
695 string type;
696 struct work_stuff work[1];
697 const char *tem;
698
699 len = strlen(opname);
700 result[0] = '\0';
701 ret = 0;
63586755 702 memset ((char *) work, 0, sizeof (work));
6599da04 703 work->options = options;
2363489c 704
6599da04
JM
705 if (opname[0] == '_' && opname[1] == '_'
706 && opname[2] == 'o' && opname[3] == 'p')
707 {
708 /* ANSI. */
709 /* type conversion operator. */
710 tem = opname + 4;
711 if (do_type (work, &tem, &type))
712 {
713 strcat (result, "operator ");
714 strncat (result, type.b, type.p - type.b);
715 string_delete (&type);
716 ret = 1;
717 }
718 }
719 else if (opname[0] == '_' && opname[1] == '_'
f6bbde28
ZW
720 && ISLOWER((unsigned char)opname[2])
721 && ISLOWER((unsigned char)opname[3]))
6599da04
JM
722 {
723 if (opname[4] == '\0')
724 {
725 /* Operator. */
d6f4ec51 726 size_t i;
2f26c11d 727 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
728 {
729 if (strlen (optable[i].in) == 2
730 && memcmp (optable[i].in, opname + 2, 2) == 0)
731 {
732 strcat (result, "operator");
733 strcat (result, optable[i].out);
734 ret = 1;
735 break;
736 }
737 }
738 }
739 else
740 {
741 if (opname[2] == 'a' && opname[5] == '\0')
742 {
743 /* Assignment. */
d6f4ec51 744 size_t i;
2f26c11d 745 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
746 {
747 if (strlen (optable[i].in) == 3
748 && memcmp (optable[i].in, opname + 2, 3) == 0)
749 {
750 strcat (result, "operator");
751 strcat (result, optable[i].out);
752 ret = 1;
753 break;
2363489c 754 }
6599da04
JM
755 }
756 }
757 }
758 }
2363489c 759 else if (len >= 3
6599da04
JM
760 && opname[0] == 'o'
761 && opname[1] == 'p'
762 && strchr (cplus_markers, opname[2]) != NULL)
763 {
764 /* see if it's an assignment expression */
765 if (len >= 10 /* op$assign_ */
766 && memcmp (opname + 3, "assign_", 7) == 0)
767 {
d6f4ec51 768 size_t i;
2f26c11d 769 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
770 {
771 len1 = len - 10;
91e0f659 772 if ((int) strlen (optable[i].in) == len1
6599da04
JM
773 && memcmp (optable[i].in, opname + 10, len1) == 0)
774 {
775 strcat (result, "operator");
776 strcat (result, optable[i].out);
777 strcat (result, "=");
778 ret = 1;
779 break;
780 }
781 }
782 }
783 else
784 {
d6f4ec51 785 size_t i;
2f26c11d 786 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
787 {
788 len1 = len - 3;
2363489c 789 if ((int) strlen (optable[i].in) == len1
6599da04
JM
790 && memcmp (optable[i].in, opname + 3, len1) == 0)
791 {
792 strcat (result, "operator");
793 strcat (result, optable[i].out);
794 ret = 1;
795 break;
796 }
797 }
798 }
799 }
800 else if (len >= 5 && memcmp (opname, "type", 4) == 0
801 && strchr (cplus_markers, opname[4]) != NULL)
802 {
803 /* type conversion operator */
804 tem = opname + 5;
805 if (do_type (work, &tem, &type))
806 {
807 strcat (result, "operator ");
808 strncat (result, type.b, type.p - type.b);
809 string_delete (&type);
810 ret = 1;
811 }
812 }
5e5199e8 813 squangle_mop_up (work);
6599da04
JM
814 return ret;
815
816}
24eaa47a 817
6599da04
JM
818/* Takes operator name as e.g. "++" and returns mangled
819 operator name (e.g. "postincrement_expr"), or NULL if not found.
820
821 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
822 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
823
824const char *
825cplus_mangle_opname (opname, options)
826 const char *opname;
827 int options;
828{
d6f4ec51 829 size_t i;
6599da04
JM
830 int len;
831
832 len = strlen (opname);
2f26c11d 833 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04 834 {
91e0f659 835 if ((int) strlen (optable[i].out) == len
6599da04
JM
836 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
837 && memcmp (optable[i].out, opname, len) == 0)
838 return optable[i].in;
839 }
840 return (0);
841}
842
24eaa47a
KB
843/* Add a routine to set the demangling style to be sure it is valid and
844 allow for any demangler initialization that maybe necessary. */
845
846enum demangling_styles
847cplus_demangle_set_style (style)
848 enum demangling_styles style;
849{
850 struct demangler_engine *demangler = libiberty_demanglers;
851
852 for (; demangler->demangling_style != unknown_demangling; ++demangler)
853 if (style == demangler->demangling_style)
854 {
855 current_demangling_style = style;
856 return current_demangling_style;
857 }
858
859 return unknown_demangling;
860}
861
862/* Do string name to style translation */
863
864enum demangling_styles
865cplus_demangle_name_to_style (name)
866 const char *name;
867{
868 struct demangler_engine *demangler = libiberty_demanglers;
869
870 for (; demangler->demangling_style != unknown_demangling; ++demangler)
871 if (strcmp (name, demangler->demangling_style_name) == 0)
872 return demangler->demangling_style;
873
874 return unknown_demangling;
875}
876
6599da04
JM
877/* char *cplus_demangle (const char *mangled, int options)
878
879 If MANGLED is a mangled function name produced by GNU C++, then
880 a pointer to a malloced string giving a C++ representation
881 of the name will be returned; otherwise NULL will be returned.
882 It is the caller's responsibility to free the string which
883 is returned.
884
885 The OPTIONS arg may contain one or more of the following bits:
886
887 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
888 included.
889 DMGL_PARAMS Function parameters are included.
890
891 For example,
2363489c 892
6599da04
JM
893 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
894 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
895 cplus_demangle ("foo__1Ai", 0) => "A::foo"
896
897 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
898 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
899 cplus_demangle ("foo__1Afe", 0) => "A::foo"
900
901 Note that any leading underscores, or other such characters prepended by
902 the compilation system, are presumed to have already been stripped from
903 MANGLED. */
904
905char *
906cplus_demangle (mangled, options)
907 const char *mangled;
908 int options;
909{
5e5199e8
AM
910 char *ret;
911 struct work_stuff work[1];
912 memset ((char *) work, 0, sizeof (work));
cf183ac2
HPN
913 work->options = options;
914 if ((work->options & DMGL_STYLE_MASK) == 0)
915 work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
5e5199e8 916
c6e13630
JM
917 /* The V3 ABI demangling is implemented elsewhere. */
918 if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
919 {
920 ret = cplus_demangle_v3 (mangled);
921 if (ret || GNU_V3_DEMANGLING)
922 return ret;
923 }
69afa80d 924
3b60dd8e
BM
925 if (JAVA_DEMANGLING)
926 {
927 ret = java_demangle_v3 (mangled);
928 if (ret)
929 return ret;
930 }
931
61ab980a
KB
932 if (GNAT_DEMANGLING)
933 return ada_demangle(mangled,options);
934
d6f4ec51 935 ret = internal_cplus_demangle (work, mangled);
5e5199e8
AM
936 squangle_mop_up (work);
937 return (ret);
938}
5e5199e8 939
2363489c 940
61ab980a
KB
941/* Assuming *OLD_VECT points to an array of *SIZE objects of size
942 ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
cf183ac2
HPN
943 updating *OLD_VECT and *SIZE as necessary. */
944
61ab980a 945static void
0437a5a8 946grow_vect (old_vect, size, min_size, element_size)
cf183ac2
HPN
947 void **old_vect;
948 size_t *size;
0437a5a8
KB
949 size_t min_size;
950 int element_size;
61ab980a 951{
cf183ac2
HPN
952 if (*size < min_size)
953 {
954 *size *= 2;
955 if (*size < min_size)
956 *size = min_size;
957 *old_vect = xrealloc (*old_vect, *size * element_size);
958 }
61ab980a
KB
959}
960
961/* Demangle ada names:
962 1. Discard final __{DIGIT}+ or ${DIGIT}+
963 2. Convert other instances of embedded "__" to `.'.
964 3. Discard leading _ada_.
cf183ac2 965 4. Remove everything after first ___ if it is followed by 'X'.
61ab980a 966 5. Put symbols that should be suppressed in <...> brackets.
cf183ac2
HPN
967 The resulting string is valid until the next call of ada_demangle. */
968
61ab980a 969static char *
0437a5a8 970ada_demangle (mangled, option)
cf183ac2 971 const char *mangled;
29120f44 972 int option ATTRIBUTE_UNUSED;
61ab980a
KB
973{
974 int i, j;
975 int len0;
976 const char* p;
cf183ac2 977 char *demangled = NULL;
61ab980a
KB
978 int at_start_name;
979 int changed;
cf183ac2 980 char *demangling_buffer = NULL;
61ab980a
KB
981 size_t demangling_buffer_size = 0;
982
983 changed = 0;
984
985 if (strncmp (mangled, "_ada_", 5) == 0)
986 {
987 mangled += 5;
988 changed = 1;
989 }
990
991 if (mangled[0] == '_' || mangled[0] == '<')
992 goto Suppress;
993
994 p = strstr (mangled, "___");
995 if (p == NULL)
996 len0 = strlen (mangled);
997 else
998 {
999 if (p[3] == 'X')
1000 {
1001 len0 = p - mangled;
1002 changed = 1;
1003 }
1004 else
1005 goto Suppress;
1006 }
1007
cf183ac2
HPN
1008 /* Make demangled big enough for possible expansion by operator name. */
1009 grow_vect ((void **) &(demangling_buffer),
61ab980a
KB
1010 &demangling_buffer_size, 2 * len0 + 1,
1011 sizeof (char));
1012 demangled = demangling_buffer;
1013
f6bbde28
ZW
1014 if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
1015 for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
61ab980a 1016 ;
cf183ac2 1017 if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
61ab980a
KB
1018 {
1019 len0 = i - 1;
1020 changed = 1;
1021 }
1022 else if (mangled[i] == '$')
1023 {
1024 len0 = i;
1025 changed = 1;
1026 }
1027 }
1028
f6bbde28 1029 for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
8bcc782c 1030 i += 1, j += 1)
61ab980a
KB
1031 demangled[j] = mangled[i];
1032
1033 at_start_name = 1;
1034 while (i < len0)
1035 {
1036 at_start_name = 0;
1037
cf183ac2 1038 if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
61ab980a
KB
1039 {
1040 demangled[j] = '.';
1041 changed = at_start_name = 1;
1042 i += 2; j += 1;
1043 }
1044 else
1045 {
1046 demangled[j] = mangled[i];
1047 i += 1; j += 1;
1048 }
1049 }
1050 demangled[j] = '\000';
1051
1052 for (i = 0; demangled[i] != '\0'; i += 1)
f6bbde28 1053 if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
61ab980a
KB
1054 goto Suppress;
1055
1056 if (! changed)
1057 return NULL;
1058 else
1059 return demangled;
1060
1061 Suppress:
cf183ac2 1062 grow_vect ((void **) &(demangling_buffer),
61ab980a
KB
1063 &demangling_buffer_size, strlen (mangled) + 3,
1064 sizeof (char));
1065 demangled = demangling_buffer;
1066 if (mangled[0] == '<')
1067 strcpy (demangled, mangled);
1068 else
1069 sprintf (demangled, "<%s>", mangled);
1070
1071 return demangled;
1072}
1073
2363489c 1074/* This function performs most of what cplus_demangle use to do, but
5e5199e8
AM
1075 to be able to demangle a name with a B, K or n code, we need to
1076 have a longer term memory of what types have been seen. The original
1077 now intializes and cleans up the squangle code info, while internal
1078 calls go directly to this routine to avoid resetting that info. */
1079
1080static char *
d6f4ec51 1081internal_cplus_demangle (work, mangled)
5e5199e8
AM
1082 struct work_stuff *work;
1083 const char *mangled;
5e5199e8
AM
1084{
1085
6599da04
JM
1086 string decl;
1087 int success = 0;
6599da04 1088 char *demangled = NULL;
cf183ac2 1089 int s1, s2, s3, s4;
5e5199e8
AM
1090 s1 = work->constructor;
1091 s2 = work->destructor;
1092 s3 = work->static_type;
91063b51 1093 s4 = work->type_quals;
5e5199e8 1094 work->constructor = work->destructor = 0;
91063b51 1095 work->type_quals = TYPE_UNQUALIFIED;
9b559a27 1096 work->dllimported = 0;
6599da04
JM
1097
1098 if ((mangled != NULL) && (*mangled != '\0'))
1099 {
6599da04
JM
1100 string_init (&decl);
1101
1102 /* First check to see if gnu style demangling is active and if the
1103 string to be demangled contains a CPLUS_MARKER. If so, attempt to
1104 recognize one of the gnu special forms rather than looking for a
1105 standard prefix. In particular, don't worry about whether there
1106 is a "__" string in the mangled string. Consider "_$_5__foo" for
1107 example. */
1108
1109 if ((AUTO_DEMANGLING || GNU_DEMANGLING))
1110 {
1111 success = gnu_special (work, &mangled, &decl);
1112 }
1113 if (!success)
1114 {
1115 success = demangle_prefix (work, &mangled, &decl);
1116 }
1117 if (success && (*mangled != '\0'))
1118 {
1119 success = demangle_signature (work, &mangled, &decl);
1120 }
1121 if (work->constructor == 2)
1122 {
5e5199e8 1123 string_prepend (&decl, "global constructors keyed to ");
6599da04
JM
1124 work->constructor = 0;
1125 }
1126 else if (work->destructor == 2)
1127 {
5e5199e8 1128 string_prepend (&decl, "global destructors keyed to ");
6599da04
JM
1129 work->destructor = 0;
1130 }
9b559a27
MK
1131 else if (work->dllimported == 1)
1132 {
1133 string_prepend (&decl, "import stub for ");
1134 work->dllimported = 0;
1135 }
6599da04
JM
1136 demangled = mop_up (work, &decl, success);
1137 }
5e5199e8
AM
1138 work->constructor = s1;
1139 work->destructor = s2;
1140 work->static_type = s3;
91063b51 1141 work->type_quals = s4;
cf183ac2 1142 return demangled;
6599da04
JM
1143}
1144
5e5199e8
AM
1145
1146/* Clear out and squangling related storage */
d6f4ec51 1147static void
5e5199e8
AM
1148squangle_mop_up (work)
1149 struct work_stuff *work;
1150{
1151 /* clean up the B and K type mangling types. */
1152 forget_B_and_K_types (work);
1153 if (work -> btypevec != NULL)
1154 {
1155 free ((char *) work -> btypevec);
1156 }
1157 if (work -> ktypevec != NULL)
1158 {
1159 free ((char *) work -> ktypevec);
1160 }
1161}
1162
5e5199e8 1163
3388651c
DB
1164/* Copy the work state and storage. */
1165
1166static void
1167work_stuff_copy_to_from (to, from)
1168 struct work_stuff *to;
1169 struct work_stuff *from;
6599da04 1170{
3388651c
DB
1171 int i;
1172
1173 delete_work_stuff (to);
1174
1175 /* Shallow-copy scalars. */
1176 memcpy (to, from, sizeof (*to));
1177
1178 /* Deep-copy dynamic storage. */
1179 if (from->typevec_size)
1180 to->typevec
1181 = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0]));
1182
1183 for (i = 0; i < from->ntypes; i++)
1184 {
1185 int len = strlen (from->typevec[i]) + 1;
1186
1187 to->typevec[i] = xmalloc (len);
1188 memcpy (to->typevec[i], from->typevec[i], len);
1189 }
1190
1191 if (from->ksize)
1192 to->ktypevec
1193 = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0]));
1194
1195 for (i = 0; i < from->numk; i++)
1196 {
1197 int len = strlen (from->ktypevec[i]) + 1;
1198
1199 to->ktypevec[i] = xmalloc (len);
1200 memcpy (to->ktypevec[i], from->ktypevec[i], len);
1201 }
6599da04 1202
3388651c
DB
1203 if (from->bsize)
1204 to->btypevec
1205 = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0]));
1206
1207 for (i = 0; i < from->numb; i++)
1208 {
1209 int len = strlen (from->btypevec[i]) + 1;
1210
1211 to->btypevec[i] = xmalloc (len);
1212 memcpy (to->btypevec[i], from->btypevec[i], len);
1213 }
1214
1215 if (from->ntmpl_args)
1216 to->tmpl_argvec
1217 = xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0]));
1218
1219 for (i = 0; i < from->ntmpl_args; i++)
1220 {
1221 int len = strlen (from->tmpl_argvec[i]) + 1;
1222
1223 to->tmpl_argvec[i] = xmalloc (len);
1224 memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len);
1225 }
1226
1227 if (from->previous_argument)
1228 {
1229 to->previous_argument = (string*) xmalloc (sizeof (string));
1230 string_init (to->previous_argument);
1231 string_appends (to->previous_argument, from->previous_argument);
1232 }
1233}
1234
1235
1236/* Delete dynamic stuff in work_stuff that is not to be re-used. */
1237
1238static void
1239delete_non_B_K_work_stuff (work)
1240 struct work_stuff *work;
1241{
6599da04 1242 /* Discard the remembered types, if any. */
2363489c 1243
6599da04
JM
1244 forget_types (work);
1245 if (work -> typevec != NULL)
1246 {
1247 free ((char *) work -> typevec);
5e5199e8 1248 work -> typevec = NULL;
c5a855ce 1249 work -> typevec_size = 0;
6599da04 1250 }
a3a5b5b7
MM
1251 if (work->tmpl_argvec)
1252 {
1253 int i;
1254
1255 for (i = 0; i < work->ntmpl_args; i++)
1256 if (work->tmpl_argvec[i])
1257 free ((char*) work->tmpl_argvec[i]);
2363489c 1258
a3a5b5b7 1259 free ((char*) work->tmpl_argvec);
5e5199e8 1260 work->tmpl_argvec = NULL;
a3a5b5b7 1261 }
9923cc56
MM
1262 if (work->previous_argument)
1263 {
1264 string_delete (work->previous_argument);
1265 free ((char*) work->previous_argument);
2363489c 1266 work->previous_argument = NULL;
9923cc56 1267 }
3388651c
DB
1268}
1269
1270
1271/* Delete all dynamic storage in work_stuff. */
1272static void
1273delete_work_stuff (work)
1274 struct work_stuff *work;
1275{
1276 delete_non_B_K_work_stuff (work);
1277 squangle_mop_up (work);
1278}
1279
1280
1281/* Clear out any mangled storage */
1282
1283static char *
1284mop_up (work, declp, success)
1285 struct work_stuff *work;
1286 string *declp;
1287 int success;
1288{
1289 char *demangled = NULL;
1290
1291 delete_non_B_K_work_stuff (work);
a3a5b5b7 1292
6599da04
JM
1293 /* If demangling was successful, ensure that the demangled string is null
1294 terminated and return it. Otherwise, free the demangling decl. */
2363489c 1295
6599da04
JM
1296 if (!success)
1297 {
1298 string_delete (declp);
1299 }
1300 else
1301 {
1302 string_appendn (declp, "", 1);
cf183ac2 1303 demangled = declp->b;
6599da04
JM
1304 }
1305 return (demangled);
1306}
1307
1308/*
1309
1310LOCAL FUNCTION
1311
1312 demangle_signature -- demangle the signature part of a mangled name
1313
1314SYNOPSIS
1315
1316 static int
1317 demangle_signature (struct work_stuff *work, const char **mangled,
1318 string *declp);
1319
1320DESCRIPTION
1321
1322 Consume and demangle the signature portion of the mangled name.
1323
1324 DECLP is the string where demangled output is being built. At
1325 entry it contains the demangled root name from the mangled name
1326 prefix. I.E. either a demangled operator name or the root function
1327 name. In some special cases, it may contain nothing.
1328
1329 *MANGLED points to the current unconsumed location in the mangled
1330 name. As tokens are consumed and demangling is performed, the
1331 pointer is updated to continuously point at the next token to
1332 be consumed.
1333
1334 Demangling GNU style mangled names is nasty because there is no
1335 explicit token that marks the start of the outermost function
1336 argument list. */
1337
1338static int
1339demangle_signature (work, mangled, declp)
1340 struct work_stuff *work;
1341 const char **mangled;
1342 string *declp;
1343{
1344 int success = 1;
1345 int func_done = 0;
1346 int expect_func = 0;
a3a5b5b7 1347 int expect_return_type = 0;
6599da04
JM
1348 const char *oldmangled = NULL;
1349 string trawname;
1350 string tname;
1351
1352 while (success && (**mangled != '\0'))
1353 {
1354 switch (**mangled)
1355 {
1356 case 'Q':
1357 oldmangled = *mangled;
1358 success = demangle_qualified (work, mangled, declp, 1, 0);
1359 if (success)
9923cc56 1360 remember_type (work, oldmangled, *mangled - oldmangled);
6599da04 1361 if (AUTO_DEMANGLING || GNU_DEMANGLING)
9923cc56 1362 expect_func = 1;
6599da04
JM
1363 oldmangled = NULL;
1364 break;
5e5199e8
AM
1365
1366 case 'K':
1367 oldmangled = *mangled;
1368 success = demangle_qualified (work, mangled, declp, 1, 0);
1369 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1370 {
1371 expect_func = 1;
1372 }
1373 oldmangled = NULL;
1374 break;
2363489c 1375
6599da04
JM
1376 case 'S':
1377 /* Static member function */
1378 if (oldmangled == NULL)
1379 {
1380 oldmangled = *mangled;
1381 }
1382 (*mangled)++;
1383 work -> static_type = 1;
1384 break;
1385
1386 case 'C':
9923cc56 1387 case 'V':
91063b51
MM
1388 case 'u':
1389 work->type_quals |= code_for_qualifier (**mangled);
9923cc56
MM
1390
1391 /* a qualified member function */
6599da04 1392 if (oldmangled == NULL)
9923cc56 1393 oldmangled = *mangled;
6599da04 1394 (*mangled)++;
6599da04 1395 break;
70d5ccef
DT
1396
1397 case 'L':
1398 /* Local class name follows after "Lnnn_" */
1399 if (HP_DEMANGLING)
1400 {
1401 while (**mangled && (**mangled != '_'))
1402 (*mangled)++;
1403 if (!**mangled)
1404 success = 0;
1405 else
1406 (*mangled)++;
1407 }
1408 else
1409 success = 0;
1410 break;
2363489c 1411
6599da04
JM
1412 case '0': case '1': case '2': case '3': case '4':
1413 case '5': case '6': case '7': case '8': case '9':
1414 if (oldmangled == NULL)
1415 {
1416 oldmangled = *mangled;
1417 }
2363489c 1418 work->temp_start = -1; /* uppermost call to demangle_class */
6599da04
JM
1419 success = demangle_class (work, mangled, declp);
1420 if (success)
1421 {
1422 remember_type (work, oldmangled, *mangled - oldmangled);
1423 }
70d5ccef 1424 if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING)
6599da04 1425 {
2363489c 1426 /* EDG and others will have the "F", so we let the loop cycle
70d5ccef
DT
1427 if we are looking at one. */
1428 if (**mangled != 'F')
1429 expect_func = 1;
6599da04
JM
1430 }
1431 oldmangled = NULL;
1432 break;
9923cc56
MM
1433
1434 case 'B':
1435 {
1436 string s;
1437 success = do_type (work, mangled, &s);
1438 if (success)
1439 {
1440 string_append (&s, SCOPE_STRING (work));
1441 string_prepends (declp, &s);
1442 }
1443 oldmangled = NULL;
1444 expect_func = 1;
1445 }
1446 break;
1447
6599da04
JM
1448 case 'F':
1449 /* Function */
70d5ccef 1450 /* ARM/HP style demangling includes a specific 'F' character after
6599da04
JM
1451 the class name. For GNU style, it is just implied. So we can
1452 safely just consume any 'F' at this point and be compatible
1453 with either style. */
1454
1455 oldmangled = NULL;
1456 func_done = 1;
1457 (*mangled)++;
1458
70d5ccef 1459 /* For lucid/ARM/HP style we have to forget any types we might
6599da04
JM
1460 have remembered up to this point, since they were not argument
1461 types. GNU style considers all types seen as available for
1462 back references. See comment in demangle_args() */
1463
70d5ccef 1464 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
6599da04
JM
1465 {
1466 forget_types (work);
1467 }
1468 success = demangle_args (work, mangled, declp);
70d5ccef
DT
1469 /* After picking off the function args, we expect to either
1470 find the function return type (preceded by an '_') or the
1471 end of the string. */
1472 if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_')
1473 {
1474 ++(*mangled);
1475 /* At this level, we do not care about the return type. */
1476 success = do_type (work, mangled, &tname);
1477 string_delete (&tname);
1478 }
1479
6599da04 1480 break;
2363489c 1481
6599da04
JM
1482 case 't':
1483 /* G++ Template */
2363489c 1484 string_init(&trawname);
6599da04
JM
1485 string_init(&tname);
1486 if (oldmangled == NULL)
1487 {
1488 oldmangled = *mangled;
1489 }
9923cc56
MM
1490 success = demangle_template (work, mangled, &tname,
1491 &trawname, 1, 1);
6599da04
JM
1492 if (success)
1493 {
1494 remember_type (work, oldmangled, *mangled - oldmangled);
1495 }
4d59ab3f
JM
1496 string_append (&tname, SCOPE_STRING (work));
1497
6599da04
JM
1498 string_prepends(declp, &tname);
1499 if (work -> destructor & 1)
1500 {
1501 string_prepend (&trawname, "~");
1502 string_appends (declp, &trawname);
1503 work->destructor -= 1;
1504 }
1505 if ((work->constructor & 1) || (work->destructor & 1))
1506 {
1507 string_appends (declp, &trawname);
1508 work->constructor -= 1;
1509 }
1510 string_delete(&trawname);
1511 string_delete(&tname);
1512 oldmangled = NULL;
1513 expect_func = 1;
1514 break;
1515
1516 case '_':
3388651c 1517 if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
a3a5b5b7
MM
1518 {
1519 /* Read the return type. */
1520 string return_type;
1521 string_init (&return_type);
1522
1523 (*mangled)++;
1524 success = do_type (work, mangled, &return_type);
1525 APPEND_BLANK (&return_type);
1526
1527 string_prepends (declp, &return_type);
1528 string_delete (&return_type);
1529 break;
1530 }
1531 else
1532 /* At the outermost level, we cannot have a return type specified,
1533 so if we run into another '_' at this point we are dealing with
1534 a mangled name that is either bogus, or has been mangled by
1535 some algorithm we don't know how to deal with. So just
1536 reject the entire demangling. */
70d5ccef
DT
1537 /* However, "_nnn" is an expected suffix for alternate entry point
1538 numbered nnn for a function, with HP aCC, so skip over that
1539 without reporting failure. pai/1997-09-04 */
1540 if (HP_DEMANGLING)
1541 {
1542 (*mangled)++;
f6bbde28 1543 while (**mangled && ISDIGIT ((unsigned char)**mangled))
70d5ccef
DT
1544 (*mangled)++;
1545 }
1546 else
1547 success = 0;
6599da04
JM
1548 break;
1549
a3a5b5b7 1550 case 'H':
3388651c 1551 if (AUTO_DEMANGLING || GNU_DEMANGLING)
a3a5b5b7
MM
1552 {
1553 /* A G++ template function. Read the template arguments. */
9923cc56
MM
1554 success = demangle_template (work, mangled, declp, 0, 0,
1555 0);
19ddc834
JM
1556 if (!(work->constructor & 1))
1557 expect_return_type = 1;
a3a5b5b7
MM
1558 (*mangled)++;
1559 break;
1560 }
1561 else
1562 /* fall through */
9ee02b5c 1563 {;}
a3a5b5b7 1564
6599da04
JM
1565 default:
1566 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1567 {
1568 /* Assume we have stumbled onto the first outermost function
1569 argument token, and start processing args. */
1570 func_done = 1;
1571 success = demangle_args (work, mangled, declp);
1572 }
1573 else
1574 {
1575 /* Non-GNU demanglers use a specific token to mark the start
1576 of the outermost function argument tokens. Typically 'F',
70d5ccef 1577 for ARM/HP-demangling, for example. So if we find something
6599da04
JM
1578 we are not prepared for, it must be an error. */
1579 success = 0;
1580 }
1581 break;
1582 }
1583 /*
1584 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1585 */
1586 {
1587 if (success && expect_func)
1588 {
1589 func_done = 1;
70d5ccef
DT
1590 if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING)
1591 {
1592 forget_types (work);
1593 }
6599da04 1594 success = demangle_args (work, mangled, declp);
a3a5b5b7
MM
1595 /* Since template include the mangling of their return types,
1596 we must set expect_func to 0 so that we don't try do
1597 demangle more arguments the next time we get here. */
1598 expect_func = 0;
6599da04
JM
1599 }
1600 }
1601 }
1602 if (success && !func_done)
1603 {
1604 if (AUTO_DEMANGLING || GNU_DEMANGLING)
1605 {
1606 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
1607 bar__3fooi is 'foo::bar(int)'. We get here when we find the
1608 first case, and need to ensure that the '(void)' gets added to
70d5ccef 1609 the current declp. Note that with ARM/HP, the first case
6599da04
JM
1610 represents the name of a static data member 'foo::bar',
1611 which is in the current declp, so we leave it alone. */
1612 success = demangle_args (work, mangled, declp);
1613 }
1614 }
91063b51
MM
1615 if (success && PRINT_ARG_TYPES)
1616 {
1617 if (work->static_type)
1618 string_append (declp, " static");
1619 if (work->type_quals != TYPE_UNQUALIFIED)
1620 {
1621 APPEND_BLANK (declp);
1622 string_append (declp, qualifier_string (work->type_quals));
1623 }
1624 }
9923cc56 1625
6599da04
JM
1626 return (success);
1627}
1628
1629#if 0
1630
1631static int
1632demangle_method_args (work, mangled, declp)
1633 struct work_stuff *work;
1634 const char **mangled;
1635 string *declp;
1636{
1637 int success = 0;
1638
1639 if (work -> static_type)
1640 {
1641 string_append (declp, *mangled + 1);
1642 *mangled += strlen (*mangled);
1643 success = 1;
1644 }
1645 else
1646 {
1647 success = demangle_args (work, mangled, declp);
1648 }
1649 return (success);
1650}
1651
1652#endif
1653
9ee02b5c
JL
1654static int
1655demangle_template_template_parm (work, mangled, tname)
1656 struct work_stuff *work;
1657 const char **mangled;
1658 string *tname;
1659{
1660 int i;
1661 int r;
1662 int need_comma = 0;
1663 int success = 1;
1664 string temp;
1665
1666 string_append (tname, "template <");
1667 /* get size of template parameter list */
1668 if (get_count (mangled, &r))
1669 {
1670 for (i = 0; i < r; i++)
1671 {
1672 if (need_comma)
1673 {
1674 string_append (tname, ", ");
1675 }
1676
1677 /* Z for type parameters */
1678 if (**mangled == 'Z')
1679 {
1680 (*mangled)++;
1681 string_append (tname, "class");
1682 }
1683 /* z for template parameters */
1684 else if (**mangled == 'z')
1685 {
1686 (*mangled)++;
2363489c 1687 success =
9ee02b5c
JL
1688 demangle_template_template_parm (work, mangled, tname);
1689 if (!success)
1690 {
1691 break;
1692 }
1693 }
1694 else
1695 {
1696 /* temp is initialized in do_type */
1697 success = do_type (work, mangled, &temp);
1698 if (success)
1699 {
1700 string_appends (tname, &temp);
1701 }
1702 string_delete(&temp);
1703 if (!success)
1704 {
1705 break;
1706 }
1707 }
1708 need_comma = 1;
1709 }
1710
1711 }
1712 if (tname->p[-1] == '>')
1713 string_append (tname, " ");
1714 string_append (tname, "> class");
1715 return (success);
1716}
1717
f9c85454 1718static int
b60fe4a7 1719demangle_expression (work, mangled, s, tk)
f9c85454
MM
1720 struct work_stuff *work;
1721 const char** mangled;
1722 string* s;
b60fe4a7 1723 type_kind_t tk;
f9c85454 1724{
b60fe4a7 1725 int need_operator = 0;
f9c85454
MM
1726 int success;
1727
b60fe4a7
MM
1728 success = 1;
1729 string_appendn (s, "(", 1);
1730 (*mangled)++;
1731 while (success && **mangled != 'W' && **mangled != '\0')
f9c85454 1732 {
b60fe4a7 1733 if (need_operator)
f9c85454 1734 {
b60fe4a7
MM
1735 size_t i;
1736 size_t len;
f9c85454 1737
b60fe4a7 1738 success = 0;
f9c85454 1739
b60fe4a7 1740 len = strlen (*mangled);
f9c85454 1741
2f26c11d 1742 for (i = 0; i < ARRAY_SIZE (optable); ++i)
b60fe4a7
MM
1743 {
1744 size_t l = strlen (optable[i].in);
f9c85454 1745
b60fe4a7
MM
1746 if (l <= len
1747 && memcmp (optable[i].in, *mangled, l) == 0)
1748 {
1749 string_appendn (s, " ", 1);
1750 string_append (s, optable[i].out);
1751 string_appendn (s, " ", 1);
1752 success = 1;
1753 (*mangled) += l;
1754 break;
f9c85454 1755 }
f9c85454 1756 }
f9c85454 1757
b60fe4a7
MM
1758 if (!success)
1759 break;
f9c85454 1760 }
2363489c 1761 else
b60fe4a7
MM
1762 need_operator = 1;
1763
1764 success = demangle_template_value_parm (work, mangled, s, tk);
1765 }
1766
1767 if (**mangled != 'W')
1768 success = 0;
1769 else
1770 {
1771 string_appendn (s, ")", 1);
1772 (*mangled)++;
f9c85454 1773 }
b60fe4a7
MM
1774
1775 return success;
1776}
1777
1778static int
1779demangle_integral_value (work, mangled, s)
1780 struct work_stuff *work;
1781 const char** mangled;
1782 string* s;
1783{
1784 int success;
1785
1786 if (**mangled == 'E')
1787 success = demangle_expression (work, mangled, s, tk_integral);
5e5199e8 1788 else if (**mangled == 'Q' || **mangled == 'K')
f9c85454
MM
1789 success = demangle_qualified (work, mangled, s, 0, 1);
1790 else
1791 {
b60fe4a7
MM
1792 int value;
1793
3388651c
DB
1794 /* By default, we let the number decide whether we shall consume an
1795 underscore. */
1796 int consume_following_underscore = 0;
1797 int leave_following_underscore = 0;
1798
f9c85454
MM
1799 success = 0;
1800
b60fe4a7 1801 /* Negative numbers are indicated with a leading `m'. */
f9c85454
MM
1802 if (**mangled == 'm')
1803 {
1804 string_appendn (s, "-", 1);
1805 (*mangled)++;
1806 }
3388651c
DB
1807 else if (mangled[0][0] == '_' && mangled[0][1] == 'm')
1808 {
1809 /* Since consume_count_with_underscores does not handle the
1810 `m'-prefix we must do it here, using consume_count and
1811 adjusting underscores: we have to consume the underscore
1812 matching the prepended one. */
1813 consume_following_underscore = 1;
1814 string_appendn (s, "-", 1);
1815 (*mangled) += 2;
1816 }
1817 else if (**mangled == '_')
1818 {
1819 /* Do not consume a following underscore;
1820 consume_following_underscore will consume what should be
1821 consumed. */
1822 leave_following_underscore = 1;
1823 }
1824
1825 /* We must call consume_count if we expect to remove a trailing
1826 underscore, since consume_count_with_underscores expects
1827 the leading underscore (that we consumed) if it is to handle
1828 multi-digit numbers. */
1829 if (consume_following_underscore)
1830 value = consume_count (mangled);
1831 else
1832 value = consume_count_with_underscores (mangled);
b60fe4a7 1833
b60fe4a7
MM
1834 if (value != -1)
1835 {
1836 char buf[INTBUF_SIZE];
1837 sprintf (buf, "%d", value);
1838 string_append (s, buf);
1839
3388651c
DB
1840 /* Numbers not otherwise delimited, might have an underscore
1841 appended as a delimeter, which we should skip.
1842
1843 ??? This used to always remove a following underscore, which
1844 is wrong. If other (arbitrary) cases are followed by an
1845 underscore, we need to do something more radical. */
1846
1847 if ((value > 9 || consume_following_underscore)
1848 && ! leave_following_underscore
1849 && **mangled == '_')
b60fe4a7
MM
1850 (*mangled)++;
1851
1852 /* All is well. */
1853 success = 1;
1854 }
1855 }
1856
1857 return success;
1858}
1859
1860/* Demangle the real value in MANGLED. */
1861
1862static int
1863demangle_real_value (work, mangled, s)
1864 struct work_stuff *work;
1865 const char **mangled;
1866 string* s;
1867{
1868 if (**mangled == 'E')
1869 return demangle_expression (work, mangled, s, tk_real);
1870
1871 if (**mangled == 'm')
1872 {
1873 string_appendn (s, "-", 1);
1874 (*mangled)++;
1875 }
f6bbde28 1876 while (ISDIGIT ((unsigned char)**mangled))
b60fe4a7
MM
1877 {
1878 string_appendn (s, *mangled, 1);
1879 (*mangled)++;
1880 }
1881 if (**mangled == '.') /* fraction */
1882 {
1883 string_appendn (s, ".", 1);
1884 (*mangled)++;
f6bbde28 1885 while (ISDIGIT ((unsigned char)**mangled))
b60fe4a7
MM
1886 {
1887 string_appendn (s, *mangled, 1);
1888 (*mangled)++;
1889 }
1890 }
1891 if (**mangled == 'e') /* exponent */
1892 {
1893 string_appendn (s, "e", 1);
1894 (*mangled)++;
f6bbde28 1895 while (ISDIGIT ((unsigned char)**mangled))
f9c85454
MM
1896 {
1897 string_appendn (s, *mangled, 1);
1898 (*mangled)++;
f9c85454
MM
1899 }
1900 }
2363489c 1901
b60fe4a7 1902 return 1;
f9c85454
MM
1903}
1904
2363489c 1905static int
4d17a06f 1906demangle_template_value_parm (work, mangled, s, tk)
f9c85454
MM
1907 struct work_stuff *work;
1908 const char **mangled;
1909 string* s;
4d17a06f 1910 type_kind_t tk;
f9c85454 1911{
f9c85454
MM
1912 int success = 1;
1913
f9c85454
MM
1914 if (**mangled == 'Y')
1915 {
1916 /* The next argument is a template parameter. */
1917 int idx;
1918
1919 (*mangled)++;
1920 idx = consume_count_with_underscores (mangled);
2363489c 1921 if (idx == -1
f9c85454
MM
1922 || (work->tmpl_argvec && idx >= work->ntmpl_args)
1923 || consume_count_with_underscores (mangled) == -1)
1924 return -1;
1925 if (work->tmpl_argvec)
1926 string_append (s, work->tmpl_argvec[idx]);
1927 else
b60fe4a7 1928 string_append_template_idx (s, idx);
f9c85454 1929 }
4d17a06f 1930 else if (tk == tk_integral)
f9c85454 1931 success = demangle_integral_value (work, mangled, s);
4d17a06f 1932 else if (tk == tk_char)
f9c85454
MM
1933 {
1934 char tmp[2];
1935 int val;
1936 if (**mangled == 'm')
1937 {
1938 string_appendn (s, "-", 1);
1939 (*mangled)++;
1940 }
1941 string_appendn (s, "'", 1);
1942 val = consume_count(mangled);
9d229989
JB
1943 if (val <= 0)
1944 success = 0;
1945 else
1946 {
1947 tmp[0] = (char)val;
1948 tmp[1] = '\0';
1949 string_appendn (s, &tmp[0], 1);
1950 string_appendn (s, "'", 1);
1951 }
f9c85454 1952 }
4d17a06f 1953 else if (tk == tk_bool)
f9c85454
MM
1954 {
1955 int val = consume_count (mangled);
1956 if (val == 0)
1957 string_appendn (s, "false", 5);
1958 else if (val == 1)
1959 string_appendn (s, "true", 4);
1960 else
1961 success = 0;
1962 }
4d17a06f 1963 else if (tk == tk_real)
b60fe4a7 1964 success = demangle_real_value (work, mangled, s);
ec2288ff 1965 else if (tk == tk_pointer || tk == tk_reference)
f9c85454 1966 {
391cdef0
MM
1967 if (**mangled == 'Q')
1968 success = demangle_qualified (work, mangled, s,
1969 /*isfuncname=*/0,
1970 /*append=*/1);
f9c85454
MM
1971 else
1972 {
391cdef0
MM
1973 int symbol_len = consume_count (mangled);
1974 if (symbol_len == -1)
1975 return -1;
1976 if (symbol_len == 0)
1977 string_appendn (s, "0", 1);
1978 else
f9c85454 1979 {
391cdef0
MM
1980 char *p = xmalloc (symbol_len + 1), *q;
1981 strncpy (p, *mangled, symbol_len);
1982 p [symbol_len] = '\0';
1983 /* We use cplus_demangle here, rather than
1984 internal_cplus_demangle, because the name of the entity
1985 mangled here does not make use of any of the squangling
1986 or type-code information we have built up thus far; it is
1987 mangled independently. */
1988 q = cplus_demangle (p, work->options);
1989 if (tk == tk_pointer)
1990 string_appendn (s, "&", 1);
1991 /* FIXME: Pointer-to-member constants should get a
1992 qualifying class name here. */
1993 if (q)
1994 {
1995 string_append (s, q);
1996 free (q);
1997 }
1998 else
1999 string_append (s, p);
2000 free (p);
f9c85454 2001 }
391cdef0 2002 *mangled += symbol_len;
f9c85454 2003 }
f9c85454
MM
2004 }
2005
2006 return success;
2007}
2008
9923cc56
MM
2009/* Demangle the template name in MANGLED. The full name of the
2010 template (e.g., S<int>) is placed in TNAME. The name without the
2011 template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
2012 non-NULL. If IS_TYPE is nonzero, this template is a type template,
2013 not a function template. If both IS_TYPE and REMEMBER are nonzero,
3388651c 2014 the template is remembered in the list of back-referenceable
9923cc56
MM
2015 types. */
2016
6599da04 2017static int
9923cc56 2018demangle_template (work, mangled, tname, trawname, is_type, remember)
6599da04
JM
2019 struct work_stuff *work;
2020 const char **mangled;
2021 string *tname;
2022 string *trawname;
a3a5b5b7 2023 int is_type;
9923cc56 2024 int remember;
6599da04
JM
2025{
2026 int i;
6599da04
JM
2027 int r;
2028 int need_comma = 0;
2029 int success = 0;
6599da04 2030 const char *start;
3510075c 2031 int is_java_array = 0;
6599da04 2032 string temp;
91e0f659 2033 int bindex = 0;
6599da04
JM
2034
2035 (*mangled)++;
a3a5b5b7 2036 if (is_type)
6599da04 2037 {
9923cc56
MM
2038 if (remember)
2039 bindex = register_Btype (work);
a3a5b5b7
MM
2040 start = *mangled;
2041 /* get template name */
9ee02b5c 2042 if (**mangled == 'z')
a3a5b5b7 2043 {
9ee02b5c
JL
2044 int idx;
2045 (*mangled)++;
2046 (*mangled)++;
2047
2048 idx = consume_count_with_underscores (mangled);
2363489c 2049 if (idx == -1
9ee02b5c
JL
2050 || (work->tmpl_argvec && idx >= work->ntmpl_args)
2051 || consume_count_with_underscores (mangled) == -1)
9923cc56
MM
2052 return (0);
2053
9ee02b5c
JL
2054 if (work->tmpl_argvec)
2055 {
2056 string_append (tname, work->tmpl_argvec[idx]);
2057 if (trawname)
2058 string_append (trawname, work->tmpl_argvec[idx]);
2059 }
2060 else
2061 {
b60fe4a7 2062 string_append_template_idx (tname, idx);
9ee02b5c 2063 if (trawname)
b60fe4a7 2064 string_append_template_idx (trawname, idx);
9ee02b5c 2065 }
a3a5b5b7 2066 }
9ee02b5c 2067 else
a3a5b5b7 2068 {
9d229989 2069 if ((r = consume_count (mangled)) <= 0
91e0f659 2070 || (int) strlen (*mangled) < r)
9ee02b5c
JL
2071 {
2072 return (0);
2073 }
3510075c
JL
2074 is_java_array = (work -> options & DMGL_JAVA)
2075 && strncmp (*mangled, "JArray1Z", 8) == 0;
2076 if (! is_java_array)
2077 {
2078 string_appendn (tname, *mangled, r);
2079 }
9ee02b5c
JL
2080 if (trawname)
2081 string_appendn (trawname, *mangled, r);
9ee02b5c 2082 *mangled += r;
a3a5b5b7 2083 }
6599da04 2084 }
3510075c
JL
2085 if (!is_java_array)
2086 string_append (tname, "<");
6599da04
JM
2087 /* get size of template parameter list */
2088 if (!get_count (mangled, &r))
2089 {
2090 return (0);
2091 }
a3a5b5b7
MM
2092 if (!is_type)
2093 {
2094 /* Create an array for saving the template argument values. */
2095 work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
2096 work->ntmpl_args = r;
2097 for (i = 0; i < r; i++)
2098 work->tmpl_argvec[i] = 0;
2099 }
6599da04
JM
2100 for (i = 0; i < r; i++)
2101 {
2102 if (need_comma)
2103 {
2104 string_append (tname, ", ");
2105 }
2106 /* Z for type parameters */
2107 if (**mangled == 'Z')
2108 {
2109 (*mangled)++;
2110 /* temp is initialized in do_type */
2111 success = do_type (work, mangled, &temp);
2112 if (success)
2113 {
2114 string_appends (tname, &temp);
a3a5b5b7
MM
2115
2116 if (!is_type)
2117 {
2118 /* Save the template argument. */
2119 int len = temp.p - temp.b;
2120 work->tmpl_argvec[i] = xmalloc (len + 1);
2121 memcpy (work->tmpl_argvec[i], temp.b, len);
2122 work->tmpl_argvec[i][len] = '\0';
2123 }
6599da04
JM
2124 }
2125 string_delete(&temp);
2126 if (!success)
2127 {
2128 break;
2129 }
2130 }
9ee02b5c
JL
2131 /* z for template parameters */
2132 else if (**mangled == 'z')
2133 {
2134 int r2;
2135 (*mangled)++;
2136 success = demangle_template_template_parm (work, mangled, tname);
2363489c 2137
9ee02b5c 2138 if (success
91e0f659
KG
2139 && (r2 = consume_count (mangled)) > 0
2140 && (int) strlen (*mangled) >= r2)
9ee02b5c
JL
2141 {
2142 string_append (tname, " ");
2143 string_appendn (tname, *mangled, r2);
2144 if (!is_type)
2145 {
2146 /* Save the template argument. */
2147 int len = r2;
2148 work->tmpl_argvec[i] = xmalloc (len + 1);
2149 memcpy (work->tmpl_argvec[i], *mangled, len);
2150 work->tmpl_argvec[i][len] = '\0';
2151 }
2152 *mangled += r2;
2153 }
2154 if (!success)
2155 {
2156 break;
2157 }
2158 }
6599da04
JM
2159 else
2160 {
a3a5b5b7
MM
2161 string param;
2162 string* s;
2163
6599da04 2164 /* otherwise, value parameter */
f9c85454 2165
6599da04
JM
2166 /* temp is initialized in do_type */
2167 success = do_type (work, mangled, &temp);
6599da04
JM
2168 string_delete(&temp);
2169 if (!success)
4d17a06f 2170 break;
a3a5b5b7
MM
2171
2172 if (!is_type)
2173 {
2174 s = &param;
2175 string_init (s);
2176 }
2177 else
2178 s = tname;
2179
4d17a06f
MM
2180 success = demangle_template_value_parm (work, mangled, s,
2181 (type_kind_t) success);
a3a5b5b7 2182
f9c85454 2183 if (!success)
6599da04 2184 {
f9c85454
MM
2185 if (!is_type)
2186 string_delete (s);
2187 success = 0;
2188 break;
6599da04 2189 }
f9c85454 2190
a3a5b5b7
MM
2191 if (!is_type)
2192 {
2193 int len = s->p - s->b;
2194 work->tmpl_argvec[i] = xmalloc (len + 1);
2195 memcpy (work->tmpl_argvec[i], s->b, len);
2196 work->tmpl_argvec[i][len] = '\0';
2363489c 2197
a3a5b5b7
MM
2198 string_appends (tname, s);
2199 string_delete (s);
2200 }
6599da04
JM
2201 }
2202 need_comma = 1;
2203 }
3510075c 2204 if (is_java_array)
4d59ab3f 2205 {
3510075c
JL
2206 string_append (tname, "[]");
2207 }
2208 else
2209 {
2210 if (tname->p[-1] == '>')
2211 string_append (tname, " ");
2212 string_append (tname, ">");
4d59ab3f 2213 }
2363489c 2214
9923cc56
MM
2215 if (is_type && remember)
2216 remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
2217
6599da04
JM
2218 /*
2219 if (work -> static_type)
2220 {
2221 string_append (declp, *mangled + 1);
2222 *mangled += strlen (*mangled);
2223 success = 1;
2224 }
2225 else
2226 {
2227 success = demangle_args (work, mangled, declp);
2228 }
2229 }
2230 */
2231 return (success);
2232}
2233
2234static int
2235arm_pt (work, mangled, n, anchor, args)
2236 struct work_stuff *work;
2237 const char *mangled;
2238 int n;
2239 const char **anchor, **args;
2240{
70d5ccef
DT
2241 /* Check if ARM template with "__pt__" in it ("parameterized type") */
2242 /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */
2243 if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__")))
6599da04
JM
2244 {
2245 int len;
2246 *args = *anchor + 6;
2247 len = consume_count (args);
9d229989
JB
2248 if (len == -1)
2249 return 0;
6599da04
JM
2250 if (*args + len == mangled + n && **args == '_')
2251 {
2252 ++*args;
2253 return 1;
2254 }
2255 }
70d5ccef
DT
2256 if (AUTO_DEMANGLING || EDG_DEMANGLING)
2257 {
2258 if ((*anchor = mystrstr (mangled, "__tm__"))
2259 || (*anchor = mystrstr (mangled, "__ps__"))
2260 || (*anchor = mystrstr (mangled, "__pt__")))
2261 {
2262 int len;
2263 *args = *anchor + 6;
2264 len = consume_count (args);
9d229989
JB
2265 if (len == -1)
2266 return 0;
70d5ccef
DT
2267 if (*args + len == mangled + n && **args == '_')
2268 {
2269 ++*args;
2270 return 1;
2271 }
2272 }
087aa398 2273 else if ((*anchor = mystrstr (mangled, "__S")))
70d5ccef
DT
2274 {
2275 int len;
2276 *args = *anchor + 3;
2277 len = consume_count (args);
9d229989
JB
2278 if (len == -1)
2279 return 0;
70d5ccef
DT
2280 if (*args + len == mangled + n && **args == '_')
2281 {
2282 ++*args;
2283 return 1;
2284 }
2285 }
2286 }
2287
6599da04
JM
2288 return 0;
2289}
2290
2291static void
70d5ccef 2292demangle_arm_hp_template (work, mangled, n, declp)
6599da04
JM
2293 struct work_stuff *work;
2294 const char **mangled;
2295 int n;
2296 string *declp;
2297{
2298 const char *p;
087aa398 2299 const char *args;
6599da04 2300 const char *e = *mangled + n;
70d5ccef 2301 string arg;
6599da04 2302
70d5ccef
DT
2303 /* Check for HP aCC template spec: classXt1t2 where t1, t2 are
2304 template args */
2305 if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
6599da04 2306 {
70d5ccef
DT
2307 char *start_spec_args = NULL;
2308
2309 /* First check for and omit template specialization pseudo-arguments,
2310 such as in "Spec<#1,#1.*>" */
2311 start_spec_args = strchr (*mangled, '<');
2312 if (start_spec_args && (start_spec_args - *mangled < n))
2313 string_appendn (declp, *mangled, start_spec_args - *mangled);
2314 else
2315 string_appendn (declp, *mangled, n);
2316 (*mangled) += n + 1;
2317 string_init (&arg);
2363489c 2318 if (work->temp_start == -1) /* non-recursive call */
70d5ccef
DT
2319 work->temp_start = declp->p - declp->b;
2320 string_append (declp, "<");
2321 while (1)
2322 {
2323 string_clear (&arg);
2324 switch (**mangled)
2325 {
2326 case 'T':
2327 /* 'T' signals a type parameter */
2328 (*mangled)++;
2329 if (!do_type (work, mangled, &arg))
2330 goto hpacc_template_args_done;
2331 break;
2363489c 2332
70d5ccef
DT
2333 case 'U':
2334 case 'S':
2335 /* 'U' or 'S' signals an integral value */
2336 if (!do_hpacc_template_const_value (work, mangled, &arg))
2337 goto hpacc_template_args_done;
2338 break;
2363489c 2339
70d5ccef
DT
2340 case 'A':
2341 /* 'A' signals a named constant expression (literal) */
2342 if (!do_hpacc_template_literal (work, mangled, &arg))
2343 goto hpacc_template_args_done;
2344 break;
2363489c 2345
70d5ccef
DT
2346 default:
2347 /* Today, 1997-09-03, we have only the above types
2363489c
UD
2348 of template parameters */
2349 /* FIXME: maybe this should fail and return null */
70d5ccef
DT
2350 goto hpacc_template_args_done;
2351 }
2352 string_appends (declp, &arg);
2353 /* Check if we're at the end of template args.
2354 0 if at end of static member of template class,
2363489c
UD
2355 _ if done with template args for a function */
2356 if ((**mangled == '\000') || (**mangled == '_'))
2357 break;
70d5ccef
DT
2358 else
2359 string_append (declp, ",");
2360 }
2361 hpacc_template_args_done:
2362 string_append (declp, ">");
2363 string_delete (&arg);
2364 if (**mangled == '_')
2365 (*mangled)++;
2366 return;
2367 }
2368 /* ARM template? (Also handles HP cfront extensions) */
2369 else if (arm_pt (work, *mangled, n, &p, &args))
2370 {
2371 string type_str;
2372
6599da04
JM
2373 string_init (&arg);
2374 string_appendn (declp, *mangled, p - *mangled);
70d5ccef 2375 if (work->temp_start == -1) /* non-recursive call */
2363489c 2376 work->temp_start = declp->p - declp->b;
6599da04
JM
2377 string_append (declp, "<");
2378 /* should do error checking here */
2379 while (args < e) {
2380 string_clear (&arg);
70d5ccef
DT
2381
2382 /* Check for type or literal here */
2383 switch (*args)
2384 {
2385 /* HP cfront extensions to ARM for template args */
2386 /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */
2387 /* FIXME: We handle only numeric literals for HP cfront */
2388 case 'X':
2363489c 2389 /* A typed constant value follows */
70d5ccef
DT
2390 args++;
2391 if (!do_type (work, &args, &type_str))
2392 goto cfront_template_args_done;
2393 string_append (&arg, "(");
2394 string_appends (&arg, &type_str);
2395 string_append (&arg, ")");
2396 if (*args != 'L')
2397 goto cfront_template_args_done;
2398 args++;
2399 /* Now snarf a literal value following 'L' */
2400 if (!snarf_numeric_literal (&args, &arg))
2401 goto cfront_template_args_done;
2402 break;
2403
2404 case 'L':
2405 /* Snarf a literal following 'L' */
2406 args++;
2407 if (!snarf_numeric_literal (&args, &arg))
2408 goto cfront_template_args_done;
2409 break;
2410 default:
2363489c 2411 /* Not handling other HP cfront stuff */
70d5ccef
DT
2412 if (!do_type (work, &args, &arg))
2413 goto cfront_template_args_done;
2414 }
6599da04
JM
2415 string_appends (declp, &arg);
2416 string_append (declp, ",");
2417 }
70d5ccef 2418 cfront_template_args_done:
6599da04 2419 string_delete (&arg);
70d5ccef 2420 if (args >= e)
2363489c 2421 --declp->p; /* remove extra comma */
6599da04
JM
2422 string_append (declp, ">");
2423 }
ab4856b1
ML
2424 else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2425 && (*mangled)[9] == 'N'
2426 && (*mangled)[8] == (*mangled)[10]
2427 && strchr (cplus_markers, (*mangled)[8]))
2428 {
2429 /* A member of the anonymous namespace. */
2430 string_append (declp, "{anonymous}");
2431 }
6599da04
JM
2432 else
2433 {
2363489c
UD
2434 if (work->temp_start == -1) /* non-recursive call only */
2435 work->temp_start = 0; /* disable in recursive calls */
6599da04
JM
2436 string_appendn (declp, *mangled, n);
2437 }
2438 *mangled += n;
2439}
2440
70d5ccef
DT
2441/* Extract a class name, possibly a template with arguments, from the
2442 mangled string; qualifiers, local class indicators, etc. have
2443 already been dealt with */
2444
6599da04
JM
2445static int
2446demangle_class_name (work, mangled, declp)
2447 struct work_stuff *work;
2448 const char **mangled;
2449 string *declp;
2450{
2451 int n;
2452 int success = 0;
2453
2454 n = consume_count (mangled);
9d229989
JB
2455 if (n == -1)
2456 return 0;
2457 if ((int) strlen (*mangled) >= n)
6599da04 2458 {
70d5ccef 2459 demangle_arm_hp_template (work, mangled, n, declp);
6599da04
JM
2460 success = 1;
2461 }
2462
2463 return (success);
2464}
2465
2466/*
2467
2468LOCAL FUNCTION
2469
2470 demangle_class -- demangle a mangled class sequence
2471
2472SYNOPSIS
2473
2474 static int
2475 demangle_class (struct work_stuff *work, const char **mangled,
2476 strint *declp)
2477
2478DESCRIPTION
2479
2480 DECLP points to the buffer into which demangling is being done.
2481
2482 *MANGLED points to the current token to be demangled. On input,
2483 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
2484 On exit, it points to the next token after the mangled class on
2485 success, or the first unconsumed token on failure.
2486
2487 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
2488 we are demangling a constructor or destructor. In this case
2489 we prepend "class::class" or "class::~class" to DECLP.
2490
2491 Otherwise, we prepend "class::" to the current DECLP.
2492
2493 Reset the constructor/destructor flags once they have been
2494 "consumed". This allows demangle_class to be called later during
2495 the same demangling, to do normal class demangling.
2496
2497 Returns 1 if demangling is successful, 0 otherwise.
2498
2499*/
2500
2501static int
2502demangle_class (work, mangled, declp)
2503 struct work_stuff *work;
2504 const char **mangled;
2505 string *declp;
2506{
2507 int success = 0;
5e5199e8 2508 int btype;
6599da04 2509 string class_name;
2363489c 2510 char *save_class_name_end = 0;
6599da04
JM
2511
2512 string_init (&class_name);
5e5199e8 2513 btype = register_Btype (work);
6599da04
JM
2514 if (demangle_class_name (work, mangled, &class_name))
2515 {
70d5ccef 2516 save_class_name_end = class_name.p;
6599da04
JM
2517 if ((work->constructor & 1) || (work->destructor & 1))
2518 {
70d5ccef
DT
2519 /* adjust so we don't include template args */
2520 if (work->temp_start && (work->temp_start != -1))
2521 {
2522 class_name.p = class_name.b + work->temp_start;
2523 }
6599da04
JM
2524 string_prepends (declp, &class_name);
2525 if (work -> destructor & 1)
2526 {
2527 string_prepend (declp, "~");
2528 work -> destructor -= 1;
2529 }
2530 else
2531 {
2363489c 2532 work -> constructor -= 1;
6599da04
JM
2533 }
2534 }
70d5ccef 2535 class_name.p = save_class_name_end;
5e5199e8
AM
2536 remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
2537 remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
9923cc56 2538 string_prepend (declp, SCOPE_STRING (work));
6599da04
JM
2539 string_prepends (declp, &class_name);
2540 success = 1;
2541 }
2542 string_delete (&class_name);
2543 return (success);
2544}
2545
3388651c
DB
2546
2547/* Called when there's a "__" in the mangled name, with `scan' pointing to
2548 the rightmost guess.
2549
2550 Find the correct "__"-sequence where the function name ends and the
2551 signature starts, which is ambiguous with GNU mangling.
2552 Call demangle_signature here, so we can make sure we found the right
2553 one; *mangled will be consumed so caller will not make further calls to
2554 demangle_signature. */
2555
2556static int
2557iterate_demangle_function (work, mangled, declp, scan)
2558 struct work_stuff *work;
2559 const char **mangled;
2560 string *declp;
2561 const char *scan;
2562{
2563 const char *mangle_init = *mangled;
2564 int success = 0;
2565 string decl_init;
2566 struct work_stuff work_init;
2567
2568 if (*(scan + 2) == '\0')
2569 return 0;
2570
2571 /* Do not iterate for some demangling modes, or if there's only one
2572 "__"-sequence. This is the normal case. */
2573 if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING
2574 || mystrstr (scan + 2, "__") == NULL)
2575 {
2576 demangle_function_name (work, mangled, declp, scan);
2577 return 1;
2578 }
2579
2580 /* Save state so we can restart if the guess at the correct "__" was
2581 wrong. */
2582 string_init (&decl_init);
2583 string_appends (&decl_init, declp);
2584 memset (&work_init, 0, sizeof work_init);
2585 work_stuff_copy_to_from (&work_init, work);
2586
2587 /* Iterate over occurrences of __, allowing names and types to have a
2588 "__" sequence in them. We must start with the first (not the last)
2589 occurrence, since "__" most often occur between independent mangled
2590 parts, hence starting at the last occurence inside a signature
2591 might get us a "successful" demangling of the signature. */
2592
2593 while (scan[2])
2594 {
2595 demangle_function_name (work, mangled, declp, scan);
2596 success = demangle_signature (work, mangled, declp);
2597 if (success)
2598 break;
2599
2600 /* Reset demangle state for the next round. */
2601 *mangled = mangle_init;
2602 string_clear (declp);
2603 string_appends (declp, &decl_init);
2604 work_stuff_copy_to_from (work, &work_init);
2605
2606 /* Leave this underscore-sequence. */
2607 scan += 2;
2608
2609 /* Scan for the next "__" sequence. */
2610 while (*scan && (scan[0] != '_' || scan[1] != '_'))
2611 scan++;
2612
2613 /* Move to last "__" in this sequence. */
2614 while (*scan && *scan == '_')
2615 scan++;
2616 scan -= 2;
2617 }
2618
2619 /* Delete saved state. */
2620 delete_work_stuff (&work_init);
2621 string_delete (&decl_init);
2622
2623 return success;
2624}
2625
6599da04
JM
2626/*
2627
2628LOCAL FUNCTION
2629
2630 demangle_prefix -- consume the mangled name prefix and find signature
2631
2632SYNOPSIS
2633
2634 static int
2635 demangle_prefix (struct work_stuff *work, const char **mangled,
2636 string *declp);
2637
2638DESCRIPTION
2639
2640 Consume and demangle the prefix of the mangled name.
3388651c
DB
2641 While processing the function name root, arrange to call
2642 demangle_signature if the root is ambiguous.
6599da04
JM
2643
2644 DECLP points to the string buffer into which demangled output is
2645 placed. On entry, the buffer is empty. On exit it contains
2646 the root function name, the demangled operator name, or in some
2647 special cases either nothing or the completely demangled result.
2648
2649 MANGLED points to the current pointer into the mangled name. As each
2650 token of the mangled name is consumed, it is updated. Upon entry
2651 the current mangled name pointer points to the first character of
2652 the mangled name. Upon exit, it should point to the first character
2653 of the signature if demangling was successful, or to the first
2654 unconsumed character if demangling of the prefix was unsuccessful.
2363489c 2655
6599da04
JM
2656 Returns 1 on success, 0 otherwise.
2657 */
2658
2659static int
2660demangle_prefix (work, mangled, declp)
2661 struct work_stuff *work;
2662 const char **mangled;
2663 string *declp;
2664{
2665 int success = 1;
2666 const char *scan;
2667 int i;
2668
9b559a27 2669 if (strlen(*mangled) > 6
2363489c 2670 && (strncmp(*mangled, "_imp__", 6) == 0
9b559a27
MK
2671 || strncmp(*mangled, "__imp_", 6) == 0))
2672 {
2673 /* it's a symbol imported from a PE dynamic library. Check for both
2674 new style prefix _imp__ and legacy __imp_ used by older versions
2675 of dlltool. */
2676 (*mangled) += 6;
2677 work->dllimported = 1;
2678 }
2679 else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0)
6599da04
JM
2680 {
2681 char *marker = strchr (cplus_markers, (*mangled)[8]);
2682 if (marker != NULL && *marker == (*mangled)[10])
2683 {
2684 if ((*mangled)[9] == 'D')
2685 {
2686 /* it's a GNU global destructor to be executed at program exit */
2687 (*mangled) += 11;
2688 work->destructor = 2;
2689 if (gnu_special (work, mangled, declp))
2690 return success;
2691 }
2692 else if ((*mangled)[9] == 'I')
2693 {
2694 /* it's a GNU global constructor to be executed at program init */
2695 (*mangled) += 11;
2696 work->constructor = 2;
2697 if (gnu_special (work, mangled, declp))
2698 return success;
2699 }
2700 }
2701 }
70d5ccef 2702 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0)
6599da04
JM
2703 {
2704 /* it's a ARM global destructor to be executed at program exit */
2705 (*mangled) += 7;
2706 work->destructor = 2;
2707 }
70d5ccef 2708 else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0)
6599da04
JM
2709 {
2710 /* it's a ARM global constructor to be executed at program initial */
2711 (*mangled) += 7;
2712 work->constructor = 2;
2713 }
2714
2715 /* This block of code is a reduction in strength time optimization
2716 of:
2717 scan = mystrstr (*mangled, "__"); */
2718
2719 {
2720 scan = *mangled;
2721
2722 do {
2723 scan = strchr (scan, '_');
2724 } while (scan != NULL && *++scan != '_');
2725
2726 if (scan != NULL) --scan;
2727 }
2728
2729 if (scan != NULL)
2730 {
2731 /* We found a sequence of two or more '_', ensure that we start at
2732 the last pair in the sequence. */
2733 i = strspn (scan, "_");
2734 if (i > 2)
2735 {
2363489c 2736 scan += (i - 2);
6599da04
JM
2737 }
2738 }
2363489c 2739
6599da04
JM
2740 if (scan == NULL)
2741 {
2742 success = 0;
2743 }
2744 else if (work -> static_type)
2745 {
f6bbde28 2746 if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't'))
6599da04
JM
2747 {
2748 success = 0;
2749 }
2750 }
2751 else if ((scan == *mangled)
f6bbde28 2752 && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q')
91e0f659 2753 || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H')))
6599da04
JM
2754 {
2755 /* The ARM says nothing about the mangling of local variables.
2756 But cfront mangles local variables by prepending __<nesting_level>
2757 to them. As an extension to ARM demangling we handle this case. */
70d5ccef 2758 if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING)
f6bbde28 2759 && ISDIGIT ((unsigned char)scan[2]))
6599da04
JM
2760 {
2761 *mangled = scan + 2;
2762 consume_count (mangled);
2763 string_append (declp, *mangled);
2764 *mangled += strlen (*mangled);
2363489c 2765 success = 1;
6599da04
JM
2766 }
2767 else
2768 {
2769 /* A GNU style constructor starts with __[0-9Qt]. But cfront uses
2770 names like __Q2_3foo3bar for nested type names. So don't accept
19ddc834
JM
2771 this style of constructor for cfront demangling. A GNU
2772 style member-template constructor starts with 'H'. */
70d5ccef 2773 if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING))
6599da04
JM
2774 work -> constructor += 1;
2775 *mangled = scan + 2;
2776 }
2777 }
70d5ccef
DT
2778 else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't')
2779 {
2780 /* Cfront-style parameterized type. Handled later as a signature. */
2781 success = 1;
2363489c 2782
70d5ccef
DT
2783 /* ARM template? */
2784 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2785 }
2786 else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm')
2787 || (scan[2] == 'p' && scan[3] == 's')
2788 || (scan[2] == 'p' && scan[3] == 't')))
2789 {
2790 /* EDG-style parameterized type. Handled later as a signature. */
2791 success = 1;
2363489c 2792
70d5ccef
DT
2793 /* EDG template? */
2794 demangle_arm_hp_template (work, mangled, strlen (*mangled), declp);
2795 }
f6bbde28 2796 else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2])
91e0f659 2797 && (scan[2] != 't'))
6599da04
JM
2798 {
2799 /* Mangled name starts with "__". Skip over any leading '_' characters,
2800 then find the next "__" that separates the prefix from the signature.
2801 */
70d5ccef 2802 if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
9ee02b5c 2803 || (arm_special (mangled, declp) == 0))
6599da04
JM
2804 {
2805 while (*scan == '_')
2806 {
2807 scan++;
2808 }
2809 if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
2810 {
2811 /* No separator (I.E. "__not_mangled"), or empty signature
2812 (I.E. "__not_mangled_either__") */
2813 success = 0;
2814 }
2815 else
3388651c 2816 return iterate_demangle_function (work, mangled, declp, scan);
6599da04
JM
2817 }
2818 }
6599da04
JM
2819 else if (*(scan + 2) != '\0')
2820 {
2821 /* Mangled name does not start with "__" but does have one somewhere
2822 in there with non empty stuff after it. Looks like a global
3388651c
DB
2823 function name. Iterate over all "__":s until the right
2824 one is found. */
2825 return iterate_demangle_function (work, mangled, declp, scan);
6599da04
JM
2826 }
2827 else
2828 {
2829 /* Doesn't look like a mangled name */
2830 success = 0;
2831 }
2832
2833 if (!success && (work->constructor == 2 || work->destructor == 2))
2834 {
2835 string_append (declp, *mangled);
2836 *mangled += strlen (*mangled);
2837 success = 1;
2363489c 2838 }
6599da04
JM
2839 return (success);
2840}
2841
2842/*
2843
2844LOCAL FUNCTION
2845
2846 gnu_special -- special handling of gnu mangled strings
2847
2848SYNOPSIS
2849
2850 static int
2851 gnu_special (struct work_stuff *work, const char **mangled,
2852 string *declp);
2853
2854
2855DESCRIPTION
2856
2857 Process some special GNU style mangling forms that don't fit
2858 the normal pattern. For example:
2859
2860 _$_3foo (destructor for class foo)
2861 _vt$foo (foo virtual table)
2862 _vt$foo$bar (foo::bar virtual table)
2863 __vt_foo (foo virtual table, new style with thunks)
2864 _3foo$varname (static data member)
2865 _Q22rs2tu$vw (static data member)
2866 __t6vector1Zii (constructor with template)
2867 __thunk_4__$_7ostream (virtual function thunk)
2868 */
2869
2870static int
2871gnu_special (work, mangled, declp)
2872 struct work_stuff *work;
2873 const char **mangled;
2874 string *declp;
2875{
2876 int n;
2877 int success = 1;
2878 const char *p;
2879
2880 if ((*mangled)[0] == '_'
2881 && strchr (cplus_markers, (*mangled)[1]) != NULL
2882 && (*mangled)[2] == '_')
2883 {
2884 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
2885 (*mangled) += 3;
2886 work -> destructor += 1;
2887 }
2888 else if ((*mangled)[0] == '_'
2889 && (((*mangled)[1] == '_'
2890 && (*mangled)[2] == 'v'
2891 && (*mangled)[3] == 't'
2892 && (*mangled)[4] == '_')
2893 || ((*mangled)[1] == 'v'
2894 && (*mangled)[2] == 't'
2895 && strchr (cplus_markers, (*mangled)[3]) != NULL)))
2896 {
2897 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
2898 and create the decl. Note that we consume the entire mangled
2899 input string, which means that demangle_signature has no work
2900 to do. */
2901 if ((*mangled)[2] == 'v')
2902 (*mangled) += 5; /* New style, with thunks: "__vt_" */
2903 else
2904 (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */
2905 while (**mangled != '\0')
2906 {
6599da04
JM
2907 switch (**mangled)
2908 {
2909 case 'Q':
5e5199e8 2910 case 'K':
6599da04
JM
2911 success = demangle_qualified (work, mangled, declp, 0, 1);
2912 break;
2913 case 't':
9923cc56
MM
2914 success = demangle_template (work, mangled, declp, 0, 1,
2915 1);
6599da04
JM
2916 break;
2917 default:
f6bbde28 2918 if (ISDIGIT((unsigned char)*mangled[0]))
6599da04
JM
2919 {
2920 n = consume_count(mangled);
5890bc92
JL
2921 /* We may be seeing a too-large size, or else a
2922 ".<digits>" indicating a static local symbol. In
2923 any case, declare victory and move on; *don't* try
2924 to use n to allocate. */
91e0f659 2925 if (n > (int) strlen (*mangled))
5890bc92
JL
2926 {
2927 success = 1;
2928 break;
2929 }
6599da04
JM
2930 }
2931 else
2932 {
2933 n = strcspn (*mangled, cplus_markers);
2934 }
2935 string_appendn (declp, *mangled, n);
2936 (*mangled) += n;
2937 }
2938
224301c1 2939 p = strpbrk (*mangled, cplus_markers);
6599da04
JM
2940 if (success && ((p == NULL) || (p == *mangled)))
2941 {
2942 if (p != NULL)
2943 {
9923cc56 2944 string_append (declp, SCOPE_STRING (work));
6599da04
JM
2945 (*mangled)++;
2946 }
2947 }
2948 else
2949 {
2950 success = 0;
2951 break;
2952 }
2953 }
2954 if (success)
2955 string_append (declp, " virtual table");
2956 }
2957 else if ((*mangled)[0] == '_'
2958 && (strchr("0123456789Qt", (*mangled)[1]) != NULL)
2959 && (p = strpbrk (*mangled, cplus_markers)) != NULL)
2960 {
2961 /* static data member, "_3foo$varname" for example */
2962 (*mangled)++;
2963 switch (**mangled)
2964 {
2965 case 'Q':
5e5199e8 2966 case 'K':
6599da04
JM
2967 success = demangle_qualified (work, mangled, declp, 0, 1);
2968 break;
2969 case 't':
9923cc56 2970 success = demangle_template (work, mangled, declp, 0, 1, 1);
6599da04
JM
2971 break;
2972 default:
2973 n = consume_count (mangled);
e797ff70 2974 if (n < 0 || n > (long) strlen (*mangled))
9d229989
JB
2975 {
2976 success = 0;
2977 break;
2978 }
29791078
HPN
2979
2980 if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
2981 && (*mangled)[9] == 'N'
2982 && (*mangled)[8] == (*mangled)[10]
2983 && strchr (cplus_markers, (*mangled)[8]))
2984 {
2985 /* A member of the anonymous namespace. There's information
2986 about what identifier or filename it was keyed to, but
2987 it's just there to make the mangled name unique; we just
2988 step over it. */
2989 string_append (declp, "{anonymous}");
2990 (*mangled) += n;
2991
2992 /* Now p points to the marker before the N, so we need to
2993 update it to the first marker after what we consumed. */
2994 p = strpbrk (*mangled, cplus_markers);
2995 break;
2996 }
2997
6599da04
JM
2998 string_appendn (declp, *mangled, n);
2999 (*mangled) += n;
3000 }
3001 if (success && (p == *mangled))
3002 {
3003 /* Consumed everything up to the cplus_marker, append the
3004 variable name. */
3005 (*mangled)++;
9923cc56 3006 string_append (declp, SCOPE_STRING (work));
6599da04
JM
3007 n = strlen (*mangled);
3008 string_appendn (declp, *mangled, n);
3009 (*mangled) += n;
3010 }
3011 else
3012 {
3013 success = 0;
3014 }
3015 }
3016 else if (strncmp (*mangled, "__thunk_", 8) == 0)
3017 {
9d229989
JB
3018 int delta;
3019
3020 (*mangled) += 8;
3021 delta = consume_count (mangled);
3022 if (delta == -1)
3023 success = 0;
6599da04
JM
3024 else
3025 {
9d229989
JB
3026 char *method = internal_cplus_demangle (work, ++*mangled);
3027
3028 if (method)
3029 {
3030 char buf[50];
3031 sprintf (buf, "virtual function thunk (delta:%d) for ", -delta);
3032 string_append (declp, buf);
3033 string_append (declp, method);
3034 free (method);
3035 n = strlen (*mangled);
3036 (*mangled) += n;
3037 }
3038 else
3039 {
3040 success = 0;
3041 }
6599da04
JM
3042 }
3043 }
3044 else if (strncmp (*mangled, "__t", 3) == 0
3045 && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f'))
3046 {
3047 p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function";
3048 (*mangled) += 4;
3049 switch (**mangled)
3050 {
3051 case 'Q':
5e5199e8 3052 case 'K':
6599da04
JM
3053 success = demangle_qualified (work, mangled, declp, 0, 1);
3054 break;
3055 case 't':
9923cc56 3056 success = demangle_template (work, mangled, declp, 0, 1, 1);
6599da04
JM
3057 break;
3058 default:
bb22da4b 3059 success = do_type (work, mangled, declp);
6599da04
JM
3060 break;
3061 }
3062 if (success && **mangled != '\0')
3063 success = 0;
3064 if (success)
3065 string_append (declp, p);
3066 }
3067 else
3068 {
3069 success = 0;
3070 }
3071 return (success);
3072}
3073
70d5ccef
DT
3074static void
3075recursively_demangle(work, mangled, result, namelength)
3076 struct work_stuff *work;
3077 const char **mangled;
3078 string *result;
3079 int namelength;
3080{
3081 char * recurse = (char *)NULL;
3082 char * recurse_dem = (char *)NULL;
2363489c 3083
70d5ccef
DT
3084 recurse = (char *) xmalloc (namelength + 1);
3085 memcpy (recurse, *mangled, namelength);
3086 recurse[namelength] = '\000';
2363489c 3087
70d5ccef 3088 recurse_dem = cplus_demangle (recurse, work->options);
2363489c 3089
70d5ccef
DT
3090 if (recurse_dem)
3091 {
3092 string_append (result, recurse_dem);
3093 free (recurse_dem);
3094 }
3095 else
3096 {
3097 string_appendn (result, *mangled, namelength);
3098 }
3099 free (recurse);
3100 *mangled += namelength;
3101}
3102
6599da04
JM
3103/*
3104
3105LOCAL FUNCTION
3106
3107 arm_special -- special handling of ARM/lucid mangled strings
3108
3109SYNOPSIS
3110
3111 static int
9ee02b5c
JL
3112 arm_special (const char **mangled,
3113 string *declp);
6599da04
JM
3114
3115
3116DESCRIPTION
3117
3118 Process some special ARM style mangling forms that don't fit
3119 the normal pattern. For example:
3120
3121 __vtbl__3foo (foo virtual table)
3122 __vtbl__3foo__3bar (bar::foo virtual table)
3123
3124 */
3125
3126static int
9ee02b5c 3127arm_special (mangled, declp)
6599da04
JM
3128 const char **mangled;
3129 string *declp;
3130{
3131 int n;
3132 int success = 1;
3133 const char *scan;
3134
3135 if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)
3136 {
3137 /* Found a ARM style virtual table, get past ARM_VTABLE_STRING
3138 and create the decl. Note that we consume the entire mangled
3139 input string, which means that demangle_signature has no work
3140 to do. */
3141 scan = *mangled + ARM_VTABLE_STRLEN;
3142 while (*scan != '\0') /* first check it can be demangled */
3143 {
3144 n = consume_count (&scan);
9d229989 3145 if (n == -1)
6599da04
JM
3146 {
3147 return (0); /* no good */
3148 }
3149 scan += n;
3150 if (scan[0] == '_' && scan[1] == '_')
3151 {
3152 scan += 2;
3153 }
3154 }
3155 (*mangled) += ARM_VTABLE_STRLEN;
3156 while (**mangled != '\0')
3157 {
3158 n = consume_count (mangled);
9d229989 3159 if (n == -1
e797ff70 3160 || n > (long) strlen (*mangled))
9d229989 3161 return 0;
6599da04
JM
3162 string_prependn (declp, *mangled, n);
3163 (*mangled) += n;
3164 if ((*mangled)[0] == '_' && (*mangled)[1] == '_')
3165 {
3166 string_prepend (declp, "::");
3167 (*mangled) += 2;
3168 }
3169 }
3170 string_append (declp, " virtual table");
3171 }
3172 else
3173 {
3174 success = 0;
3175 }
3176 return (success);
3177}
3178
3179/*
3180
3181LOCAL FUNCTION
3182
3183 demangle_qualified -- demangle 'Q' qualified name strings
3184
3185SYNOPSIS
3186
3187 static int
3188 demangle_qualified (struct work_stuff *, const char *mangled,
3189 string *result, int isfuncname, int append);
3190
3191DESCRIPTION
3192
3193 Demangle a qualified name, such as "Q25Outer5Inner" which is
3194 the mangled form of "Outer::Inner". The demangled output is
3195 prepended or appended to the result string according to the
3196 state of the append flag.
3197
3198 If isfuncname is nonzero, then the qualified name we are building
3199 is going to be used as a member function name, so if it is a
3200 constructor or destructor function, append an appropriate
3201 constructor or destructor name. I.E. for the above example,
3202 the result for use as a constructor is "Outer::Inner::Inner"
3203 and the result for use as a destructor is "Outer::Inner::~Inner".
3204
3205BUGS
3206
3207 Numeric conversion is ASCII dependent (FIXME).
3208
3209 */
3210
3211static int
3212demangle_qualified (work, mangled, result, isfuncname, append)
3213 struct work_stuff *work;
3214 const char **mangled;
3215 string *result;
3216 int isfuncname;
3217 int append;
3218{
5e5199e8 3219 int qualifiers = 0;
6599da04 3220 int success = 1;
6599da04
JM
3221 char num[2];
3222 string temp;
9923cc56
MM
3223 string last_name;
3224 int bindex = register_Btype (work);
3225
3226 /* We only make use of ISFUNCNAME if the entity is a constructor or
3227 destructor. */
2363489c 3228 isfuncname = (isfuncname
9923cc56 3229 && ((work->constructor & 1) || (work->destructor & 1)));
6599da04
JM
3230
3231 string_init (&temp);
9923cc56 3232 string_init (&last_name);
5e5199e8
AM
3233
3234 if ((*mangled)[0] == 'K')
3235 {
3236 /* Squangling qualified name reuse */
3237 int idx;
3238 (*mangled)++;
3239 idx = consume_count_with_underscores (mangled);
e0c13971 3240 if (idx == -1 || idx >= work -> numk)
5e5199e8
AM
3241 success = 0;
3242 else
3243 string_append (&temp, work -> ktypevec[idx]);
3244 }
3245 else
3246 switch ((*mangled)[1])
6599da04
JM
3247 {
3248 case '_':
3249 /* GNU mangled name with more than 9 classes. The count is preceded
3250 by an underscore (to distinguish it from the <= 9 case) and followed
3251 by an underscore. */
b60fe4a7
MM
3252 (*mangled)++;
3253 qualifiers = consume_count_with_underscores (mangled);
3254 if (qualifiers == -1)
6599da04 3255 success = 0;
6599da04
JM
3256 break;
3257
3258 case '1':
3259 case '2':
3260 case '3':
3261 case '4':
3262 case '5':
3263 case '6':
3264 case '7':
3265 case '8':
3266 case '9':
3267 /* The count is in a single digit. */
3268 num[0] = (*mangled)[1];
3269 num[1] = '\0';
3270 qualifiers = atoi (num);
3271
3272 /* If there is an underscore after the digit, skip it. This is
3273 said to be for ARM-qualified names, but the ARM makes no
3274 mention of such an underscore. Perhaps cfront uses one. */
3275 if ((*mangled)[2] == '_')
3276 {
3277 (*mangled)++;
3278 }
3279 (*mangled) += 2;
3280 break;
3281
3282 case '0':
3283 default:
3284 success = 0;
3285 }
3286
3287 if (!success)
3288 return success;
3289
3290 /* Pick off the names and collect them in the temp buffer in the order
3291 in which they are found, separated by '::'. */
3292
3293 while (qualifiers-- > 0)
3294 {
5e5199e8 3295 int remember_K = 1;
9923cc56
MM
3296 string_clear (&last_name);
3297
2363489c 3298 if (*mangled[0] == '_')
9923cc56
MM
3299 (*mangled)++;
3300
6599da04
JM
3301 if (*mangled[0] == 't')
3302 {
9923cc56
MM
3303 /* Here we always append to TEMP since we will want to use
3304 the template name without the template parameters as a
3305 constructor or destructor name. The appropriate
3306 (parameter-less) value is returned by demangle_template
3307 in LAST_NAME. We do not remember the template type here,
3308 in order to match the G++ mangling algorithm. */
2363489c 3309 success = demangle_template(work, mangled, &temp,
9923cc56 3310 &last_name, 1, 0);
2363489c 3311 if (!success)
9923cc56 3312 break;
2363489c 3313 }
07623417 3314 else if (*mangled[0] == 'K')
5e5199e8
AM
3315 {
3316 int idx;
3317 (*mangled)++;
3318 idx = consume_count_with_underscores (mangled);
e0c13971 3319 if (idx == -1 || idx >= work->numk)
5e5199e8
AM
3320 success = 0;
3321 else
3322 string_append (&temp, work->ktypevec[idx]);
3323 remember_K = 0;
3324
6599da04
JM
3325 if (!success) break;
3326 }
3327 else
9923cc56 3328 {
70d5ccef
DT
3329 if (EDG_DEMANGLING)
3330 {
3331 int namelength;
3332 /* Now recursively demangle the qualifier
2363489c
UD
3333 * This is necessary to deal with templates in
3334 * mangling styles like EDG */
70d5ccef 3335 namelength = consume_count (mangled);
9d229989
JB
3336 if (namelength == -1)
3337 {
3338 success = 0;
3339 break;
3340 }
70d5ccef
DT
3341 recursively_demangle(work, mangled, &temp, namelength);
3342 }
3343 else
3344 {
3345 success = do_type (work, mangled, &last_name);
3346 if (!success)
3347 break;
3348 string_appends (&temp, &last_name);
3349 }
6599da04 3350 }
5e5199e8
AM
3351
3352 if (remember_K)
9923cc56 3353 remember_Ktype (work, temp.b, LEN_STRING (&temp));
5e5199e8 3354
6599da04 3355 if (qualifiers > 0)
9923cc56 3356 string_append (&temp, SCOPE_STRING (work));
6599da04
JM
3357 }
3358
9923cc56
MM
3359 remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
3360
6599da04
JM
3361 /* If we are using the result as a function name, we need to append
3362 the appropriate '::' separated constructor or destructor name.
3363 We do this here because this is the most convenient place, where
3364 we already have a pointer to the name and the length of the name. */
3365
2363489c 3366 if (isfuncname)
6599da04 3367 {
9923cc56 3368 string_append (&temp, SCOPE_STRING (work));
6599da04 3369 if (work -> destructor & 1)
9923cc56
MM
3370 string_append (&temp, "~");
3371 string_appends (&temp, &last_name);
6599da04
JM
3372 }
3373
2363489c 3374 /* Now either prepend the temp buffer to the result, or append it,
6599da04
JM
3375 depending upon the state of the append flag. */
3376
3377 if (append)
9923cc56 3378 string_appends (result, &temp);
6599da04
JM
3379 else
3380 {
3381 if (!STRING_EMPTY (result))
9923cc56 3382 string_append (&temp, SCOPE_STRING (work));
6599da04
JM
3383 string_prepends (result, &temp);
3384 }
3385
9923cc56 3386 string_delete (&last_name);
6599da04
JM
3387 string_delete (&temp);
3388 return (success);
3389}
3390
3391/*
3392
3393LOCAL FUNCTION
3394
3395 get_count -- convert an ascii count to integer, consuming tokens
3396
3397SYNOPSIS
3398
3399 static int
3400 get_count (const char **type, int *count)
3401
3402DESCRIPTION
3403
9d229989
JB
3404 Assume that *type points at a count in a mangled name; set
3405 *count to its value, and set *type to the next character after
3406 the count. There are some weird rules in effect here.
3407
3408 If *type does not point at a string of digits, return zero.
3409
3410 If *type points at a string of digits followed by an
3411 underscore, set *count to their value as an integer, advance
3412 *type to point *after the underscore, and return 1.
3413
3414 If *type points at a string of digits not followed by an
3415 underscore, consume only the first digit. Set *count to its
3416 value as an integer, leave *type pointing after that digit,
3417 and return 1.
3418
3419 The excuse for this odd behavior: in the ARM and HP demangling
3420 styles, a type can be followed by a repeat count of the form
3421 `Nxy', where:
3422
3423 `x' is a single digit specifying how many additional copies
3424 of the type to append to the argument list, and
3425
3426 `y' is one or more digits, specifying the zero-based index of
3427 the first repeated argument in the list. Yes, as you're
3428 unmangling the name you can figure this out yourself, but
3429 it's there anyway.
3430
3431 So, for example, in `bar__3fooFPiN51', the first argument is a
3432 pointer to an integer (`Pi'), and then the next five arguments
3433 are the same (`N5'), and the first repeat is the function's
3434 second argument (`1').
6599da04
JM
3435*/
3436
3437static int
3438get_count (type, count)
3439 const char **type;
3440 int *count;
3441{
3442 const char *p;
3443 int n;
3444
f6bbde28 3445 if (!ISDIGIT ((unsigned char)**type))
b60fe4a7 3446 return (0);
6599da04
JM
3447 else
3448 {
3449 *count = **type - '0';
3450 (*type)++;
f6bbde28 3451 if (ISDIGIT ((unsigned char)**type))
6599da04
JM
3452 {
3453 p = *type;
3454 n = *count;
2363489c 3455 do
6599da04
JM
3456 {
3457 n *= 10;
3458 n += *p - '0';
3459 p++;
2363489c 3460 }
f6bbde28 3461 while (ISDIGIT ((unsigned char)*p));
6599da04
JM
3462 if (*p == '_')
3463 {
3464 *type = p + 1;
3465 *count = n;
3466 }
3467 }
3468 }
3469 return (1);
3470}
3471
4d17a06f
MM
3472/* RESULT will be initialised here; it will be freed on failure. The
3473 value returned is really a type_kind_t. */
6599da04
JM
3474
3475static int
3476do_type (work, mangled, result)
3477 struct work_stuff *work;
3478 const char **mangled;
3479 string *result;
3480{
3481 int n;
3482 int done;
3483 int success;
3484 string decl;
3485 const char *remembered_type;
91063b51 3486 int type_quals;
5e5199e8 3487 string btype;
4d17a06f 3488 type_kind_t tk = tk_none;
6599da04 3489
5e5199e8 3490 string_init (&btype);
6599da04
JM
3491 string_init (&decl);
3492 string_init (result);
3493
3494 done = 0;
3495 success = 1;
3496 while (success && !done)
3497 {
3498 int member;
3499 switch (**mangled)
3500 {
3501
3502 /* A pointer type */
3503 case 'P':
3504 case 'p':
3505 (*mangled)++;
3510075c
JL
3506 if (! (work -> options & DMGL_JAVA))
3507 string_prepend (&decl, "*");
4d17a06f
MM
3508 if (tk == tk_none)
3509 tk = tk_pointer;
6599da04
JM
3510 break;
3511
3512 /* A reference type */
3513 case 'R':
3514 (*mangled)++;
3515 string_prepend (&decl, "&");
4d17a06f 3516 if (tk == tk_none)
ec2288ff 3517 tk = tk_reference;
6599da04
JM
3518 break;
3519
3520 /* An array */
3521 case 'A':
3522 {
4d17a06f 3523 ++(*mangled);
09007174
JM
3524 if (!STRING_EMPTY (&decl)
3525 && (decl.b[0] == '*' || decl.b[0] == '&'))
5210f3d0
JM
3526 {
3527 string_prepend (&decl, "(");
3528 string_append (&decl, ")");
3529 }
3530 string_append (&decl, "[");
3531 if (**mangled != '_')
3532 success = demangle_template_value_parm (work, mangled, &decl,
3533 tk_integral);
6599da04 3534 if (**mangled == '_')
4d17a06f
MM
3535 ++(*mangled);
3536 string_append (&decl, "]");
6599da04
JM
3537 break;
3538 }
3539
3540 /* A back reference to a previously seen type */
3541 case 'T':
3542 (*mangled)++;
3543 if (!get_count (mangled, &n) || n >= work -> ntypes)
3544 {
3545 success = 0;
3546 }
3547 else
3548 {
3549 remembered_type = work -> typevec[n];
3550 mangled = &remembered_type;
3551 }
3552 break;
3553
3554 /* A function */
3555 case 'F':
3556 (*mangled)++;
09007174
JM
3557 if (!STRING_EMPTY (&decl)
3558 && (decl.b[0] == '*' || decl.b[0] == '&'))
6599da04
JM
3559 {
3560 string_prepend (&decl, "(");
3561 string_append (&decl, ")");
3562 }
3563 /* After picking off the function args, we expect to either find the
3564 function return type (preceded by an '_') or the end of the
3565 string. */
9923cc56 3566 if (!demangle_nested_args (work, mangled, &decl)
6599da04
JM
3567 || (**mangled != '_' && **mangled != '\0'))
3568 {
3569 success = 0;
9923cc56 3570 break;
6599da04
JM
3571 }
3572 if (success && (**mangled == '_'))
9923cc56 3573 (*mangled)++;
6599da04
JM
3574 break;
3575
3576 case 'M':
3577 case 'O':
3578 {
91063b51 3579 type_quals = TYPE_UNQUALIFIED;
6599da04
JM
3580
3581 member = **mangled == 'M';
3582 (*mangled)++;
6599da04
JM
3583
3584 string_append (&decl, ")");
7c56a6ce
MM
3585
3586 /* We don't need to prepend `::' for a qualified name;
3587 demangle_qualified will do that for us. */
3588 if (**mangled != 'Q')
3589 string_prepend (&decl, SCOPE_STRING (work));
3590
f6bbde28 3591 if (ISDIGIT ((unsigned char)**mangled))
6599da04
JM
3592 {
3593 n = consume_count (mangled);
9d229989
JB
3594 if (n == -1
3595 || (int) strlen (*mangled) < n)
6599da04
JM
3596 {
3597 success = 0;
3598 break;
3599 }
3600 string_prependn (&decl, *mangled, n);
3601 *mangled += n;
3602 }
391cdef0
MM
3603 else if (**mangled == 'X' || **mangled == 'Y')
3604 {
3605 string temp;
3606 do_type (work, mangled, &temp);
3607 string_prepends (&decl, &temp);
3608 }
3609 else if (**mangled == 't')
6599da04
JM
3610 {
3611 string temp;
3612 string_init (&temp);
9923cc56
MM
3613 success = demangle_template (work, mangled, &temp,
3614 NULL, 1, 1);
6599da04
JM
3615 if (success)
3616 {
3617 string_prependn (&decl, temp.b, temp.p - temp.b);
3618 string_clear (&temp);
3619 }
3620 else
3621 break;
3622 }
7c56a6ce
MM
3623 else if (**mangled == 'Q')
3624 {
3625 success = demangle_qualified (work, mangled, &decl,
3626 /*isfuncnam=*/0,
3627 /*append=*/0);
3628 if (!success)
3629 break;
3630 }
391cdef0
MM
3631 else
3632 {
3633 success = 0;
3634 break;
3635 }
3636
6599da04
JM
3637 string_prepend (&decl, "(");
3638 if (member)
3639 {
91063b51 3640 switch (**mangled)
6599da04 3641 {
91063b51
MM
3642 case 'C':
3643 case 'V':
3644 case 'u':
3645 type_quals |= code_for_qualifier (**mangled);
6599da04 3646 (*mangled)++;
91063b51
MM
3647 break;
3648
3649 default:
3650 break;
6599da04 3651 }
91063b51 3652
6599da04
JM
3653 if (*(*mangled)++ != 'F')
3654 {
3655 success = 0;
3656 break;
3657 }
3658 }
9923cc56 3659 if ((member && !demangle_nested_args (work, mangled, &decl))
6599da04
JM
3660 || **mangled != '_')
3661 {
3662 success = 0;
3663 break;
3664 }
3665 (*mangled)++;
3666 if (! PRINT_ANSI_QUALIFIERS)
3667 {
3668 break;
3669 }
91063b51 3670 if (type_quals != TYPE_UNQUALIFIED)
6599da04
JM
3671 {
3672 APPEND_BLANK (&decl);
91063b51 3673 string_append (&decl, qualifier_string (type_quals));
6599da04
JM
3674 }
3675 break;
3676 }
3677 case 'G':
3678 (*mangled)++;
3679 break;
3680
3681 case 'C':
1cc75298 3682 case 'V':
91063b51 3683 case 'u':
6599da04
JM
3684 if (PRINT_ANSI_QUALIFIERS)
3685 {
3686 if (!STRING_EMPTY (&decl))
91063b51
MM
3687 string_prepend (&decl, " ");
3688
3689 string_prepend (&decl, demangle_qualifier (**mangled));
6599da04 3690 }
1cc75298 3691 (*mangled)++;
6599da04
JM
3692 break;
3693 /*
3694 }
3695 */
3696
3697 /* fall through */
3698 default:
3699 done = 1;
3700 break;
3701 }
3702 }
3703
5210f3d0 3704 if (success) switch (**mangled)
6599da04
JM
3705 {
3706 /* A qualified name, such as "Outer::Inner". */
3707 case 'Q':
5e5199e8
AM
3708 case 'K':
3709 {
5e5199e8 3710 success = demangle_qualified (work, mangled, result, 0, 1);
5e5199e8
AM
3711 break;
3712 }
3713
3714 /* A back reference to a previously seen squangled type */
3715 case 'B':
3716 (*mangled)++;
3717 if (!get_count (mangled, &n) || n >= work -> numb)
5210f3d0 3718 success = 0;
5e5199e8 3719 else
4d17a06f 3720 string_append (result, work->btypevec[n]);
6599da04
JM
3721 break;
3722
19ddc834
JM
3723 case 'X':
3724 case 'Y':
3725 /* A template parm. We substitute the corresponding argument. */
3726 {
3727 int idx;
19ddc834
JM
3728
3729 (*mangled)++;
3730 idx = consume_count_with_underscores (mangled);
3731
2363489c 3732 if (idx == -1
19ddc834
JM
3733 || (work->tmpl_argvec && idx >= work->ntmpl_args)
3734 || consume_count_with_underscores (mangled) == -1)
3735 {
3736 success = 0;
3737 break;
3738 }
3739
3740 if (work->tmpl_argvec)
3741 string_append (result, work->tmpl_argvec[idx]);
3742 else
b60fe4a7 3743 string_append_template_idx (result, idx);
19ddc834
JM
3744
3745 success = 1;
3746 }
3747 break;
3748
6599da04
JM
3749 default:
3750 success = demangle_fund_type (work, mangled, result);
4d17a06f
MM
3751 if (tk == tk_none)
3752 tk = (type_kind_t) success;
6599da04
JM
3753 break;
3754 }
3755
3756 if (success)
3757 {
3758 if (!STRING_EMPTY (&decl))
3759 {
3760 string_append (result, " ");
3761 string_appends (result, &decl);
3762 }
3763 }
3764 else
4d17a06f 3765 string_delete (result);
6599da04 3766 string_delete (&decl);
4d17a06f
MM
3767
3768 if (success)
3769 /* Assume an integral type, if we're not sure. */
3770 return (int) ((tk == tk_none) ? tk_integral : tk);
3771 else
3772 return 0;
6599da04
JM
3773}
3774
3775/* Given a pointer to a type string that represents a fundamental type
3776 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
3777 string in which the demangled output is being built in RESULT, and
3778 the WORK structure, decode the types and add them to the result.
3779
3780 For example:
3781
3782 "Ci" => "const int"
3783 "Sl" => "signed long"
3784 "CUs" => "const unsigned short"
3785
4d17a06f 3786 The value returned is really a type_kind_t. */
6599da04
JM
3787
3788static int
3789demangle_fund_type (work, mangled, result)
3790 struct work_stuff *work;
3791 const char **mangled;
3792 string *result;
3793{
3794 int done = 0;
3795 int success = 1;
6e6e34b7 3796 char buf[10];
e9958132 3797 unsigned int dec = 0;
5e5199e8 3798 string btype;
4d17a06f
MM
3799 type_kind_t tk = tk_integral;
3800
5e5199e8 3801 string_init (&btype);
6599da04
JM
3802
3803 /* First pick off any type qualifiers. There can be more than one. */
3804
3805 while (!done)
3806 {
3807 switch (**mangled)
3808 {
3809 case 'C':
91063b51
MM
3810 case 'V':
3811 case 'u':
6599da04
JM
3812 if (PRINT_ANSI_QUALIFIERS)
3813 {
e8fc8222
AM
3814 if (!STRING_EMPTY (result))
3815 string_prepend (result, " ");
3816 string_prepend (result, demangle_qualifier (**mangled));
6599da04 3817 }
e8fc8222 3818 (*mangled)++;
6599da04
JM
3819 break;
3820 case 'U':
3821 (*mangled)++;
3822 APPEND_BLANK (result);
3823 string_append (result, "unsigned");
3824 break;
3825 case 'S': /* signed char only */
3826 (*mangled)++;
3827 APPEND_BLANK (result);
3828 string_append (result, "signed");
3829 break;
6599da04
JM
3830 case 'J':
3831 (*mangled)++;
3832 APPEND_BLANK (result);
19ddc834 3833 string_append (result, "__complex");
6599da04
JM
3834 break;
3835 default:
3836 done = 1;
3837 break;
3838 }
3839 }
3840
3841 /* Now pick off the fundamental type. There can be only one. */
3842
3843 switch (**mangled)
3844 {
3845 case '\0':
3846 case '_':
3847 break;
3848 case 'v':
3849 (*mangled)++;
3850 APPEND_BLANK (result);
3851 string_append (result, "void");
3852 break;
3853 case 'x':
3854 (*mangled)++;
3855 APPEND_BLANK (result);
3856 string_append (result, "long long");
3857 break;
3858 case 'l':
3859 (*mangled)++;
3860 APPEND_BLANK (result);
3861 string_append (result, "long");
3862 break;
3863 case 'i':
3864 (*mangled)++;
3865 APPEND_BLANK (result);
3866 string_append (result, "int");
3867 break;
3868 case 's':
3869 (*mangled)++;
3870 APPEND_BLANK (result);
3871 string_append (result, "short");
3872 break;
3873 case 'b':
3874 (*mangled)++;
3875 APPEND_BLANK (result);
3876 string_append (result, "bool");
4d17a06f 3877 tk = tk_bool;
6599da04
JM
3878 break;
3879 case 'c':
3880 (*mangled)++;
3881 APPEND_BLANK (result);
3882 string_append (result, "char");
4d17a06f 3883 tk = tk_char;
6599da04
JM
3884 break;
3885 case 'w':
3886 (*mangled)++;
3887 APPEND_BLANK (result);
3888 string_append (result, "wchar_t");
4d17a06f 3889 tk = tk_char;
6599da04
JM
3890 break;
3891 case 'r':
3892 (*mangled)++;
3893 APPEND_BLANK (result);
3894 string_append (result, "long double");
4d17a06f 3895 tk = tk_real;
6599da04
JM
3896 break;
3897 case 'd':
3898 (*mangled)++;
3899 APPEND_BLANK (result);
3900 string_append (result, "double");
4d17a06f 3901 tk = tk_real;
6599da04
JM
3902 break;
3903 case 'f':
3904 (*mangled)++;
3905 APPEND_BLANK (result);
3906 string_append (result, "float");
4d17a06f 3907 tk = tk_real;
6599da04
JM
3908 break;
3909 case 'G':
3910 (*mangled)++;
f6bbde28 3911 if (!ISDIGIT ((unsigned char)**mangled))
6599da04
JM
3912 {
3913 success = 0;
3914 break;
3915 }
6e6e34b7 3916 case 'I':
53504016 3917 (*mangled)++;
6e6e34b7
BK
3918 if (**mangled == '_')
3919 {
3920 int i;
53504016 3921 (*mangled)++;
c5a855ce 3922 for (i = 0;
e797ff70 3923 i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_';
53504016 3924 (*mangled)++, i++)
6e6e34b7 3925 buf[i] = **mangled;
c5a855ce
JB
3926 if (**mangled != '_')
3927 {
3928 success = 0;
3929 break;
3930 }
6e6e34b7 3931 buf[i] = '\0';
53504016 3932 (*mangled)++;
6e6e34b7
BK
3933 }
3934 else
3935 {
3936 strncpy (buf, *mangled, 2);
c5a855ce 3937 buf[2] = '\0';
53504016 3938 *mangled += min (strlen (*mangled), 2);
6e6e34b7 3939 }
2363489c 3940 sscanf (buf, "%x", &dec);
e9958132 3941 sprintf (buf, "int%u_t", dec);
6e6e34b7
BK
3942 APPEND_BLANK (result);
3943 string_append (result, buf);
3944 break;
3945
6599da04
JM
3946 /* fall through */
3947 /* An explicit type, such as "6mytype" or "7integer" */
3948 case '0':
3949 case '1':
3950 case '2':
3951 case '3':
3952 case '4':
3953 case '5':
3954 case '6':
3955 case '7':
3956 case '8':
3957 case '9':
5e5199e8
AM
3958 {
3959 int bindex = register_Btype (work);
3960 string btype;
3961 string_init (&btype);
3962 if (demangle_class_name (work, mangled, &btype)) {
3963 remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
3964 APPEND_BLANK (result);
3965 string_appends (result, &btype);
3966 }
2363489c 3967 else
5e5199e8
AM
3968 success = 0;
3969 string_delete (&btype);
3970 break;
6599da04 3971 }
6599da04 3972 case 't':
5e5199e8 3973 {
9923cc56 3974 success = demangle_template (work, mangled, &btype, 0, 1, 1);
5e5199e8
AM
3975 string_appends (result, &btype);
3976 break;
3977 }
6599da04
JM
3978 default:
3979 success = 0;
3980 break;
3981 }
3982
4d17a06f 3983 return success ? ((int) tk) : 0;
6599da04
JM
3984}
3985
70d5ccef
DT
3986
3987/* Handle a template's value parameter for HP aCC (extension from ARM)
3988 **mangled points to 'S' or 'U' */
3989
3990static int
3991do_hpacc_template_const_value (work, mangled, result)
e797ff70 3992 struct work_stuff *work ATTRIBUTE_UNUSED;
70d5ccef
DT
3993 const char **mangled;
3994 string *result;
3995{
3996 int unsigned_const;
3997
3998 if (**mangled != 'U' && **mangled != 'S')
3999 return 0;
2363489c 4000
70d5ccef
DT
4001 unsigned_const = (**mangled == 'U');
4002
4003 (*mangled)++;
4004
4005 switch (**mangled)
4006 {
4007 case 'N':
4008 string_append (result, "-");
2363489c 4009 /* fall through */
70d5ccef
DT
4010 case 'P':
4011 (*mangled)++;
4012 break;
4013 case 'M':
2363489c 4014 /* special case for -2^31 */
70d5ccef
DT
4015 string_append (result, "-2147483648");
4016 (*mangled)++;
4017 return 1;
4018 default:
4019 return 0;
4020 }
4021
4022 /* We have to be looking at an integer now */
f6bbde28 4023 if (!(ISDIGIT ((unsigned char)**mangled)))
70d5ccef
DT
4024 return 0;
4025
4026 /* We only deal with integral values for template
4027 parameters -- so it's OK to look only for digits */
f6bbde28 4028 while (ISDIGIT ((unsigned char)**mangled))
70d5ccef
DT
4029 {
4030 char_str[0] = **mangled;
4031 string_append (result, char_str);
4032 (*mangled)++;
4033 }
4034
4035 if (unsigned_const)
4036 string_append (result, "U");
4037
4038 /* FIXME? Some day we may have 64-bit (or larger :-) ) constants
4039 with L or LL suffixes. pai/1997-09-03 */
2363489c
UD
4040
4041 return 1; /* success */
70d5ccef
DT
4042}
4043
4044/* Handle a template's literal parameter for HP aCC (extension from ARM)
4045 **mangled is pointing to the 'A' */
4046
4047static int
4048do_hpacc_template_literal (work, mangled, result)
4049 struct work_stuff *work;
4050 const char **mangled;
4051 string *result;
4052{
4053 int literal_len = 0;
70d5ccef
DT
4054 char * recurse;
4055 char * recurse_dem;
2363489c 4056
70d5ccef
DT
4057 if (**mangled != 'A')
4058 return 0;
4059
4060 (*mangled)++;
4061
4062 literal_len = consume_count (mangled);
4063
9d229989 4064 if (literal_len <= 0)
70d5ccef
DT
4065 return 0;
4066
4067 /* Literal parameters are names of arrays, functions, etc. and the
4068 canonical representation uses the address operator */
4069 string_append (result, "&");
4070
2363489c 4071 /* Now recursively demangle the literal name */
70d5ccef
DT
4072 recurse = (char *) xmalloc (literal_len + 1);
4073 memcpy (recurse, *mangled, literal_len);
4074 recurse[literal_len] = '\000';
4075
4076 recurse_dem = cplus_demangle (recurse, work->options);
2363489c 4077
70d5ccef
DT
4078 if (recurse_dem)
4079 {
4080 string_append (result, recurse_dem);
4081 free (recurse_dem);
4082 }
4083 else
4084 {
4085 string_appendn (result, *mangled, literal_len);
4086 }
4087 (*mangled) += literal_len;
4088 free (recurse);
4089
4090 return 1;
4091}
4092
4093static int
4094snarf_numeric_literal (args, arg)
087aa398 4095 const char ** args;
70d5ccef
DT
4096 string * arg;
4097{
4098 if (**args == '-')
4099 {
4100 char_str[0] = '-';
4101 string_append (arg, char_str);
4102 (*args)++;
4103 }
4104 else if (**args == '+')
4105 (*args)++;
2363489c 4106
f6bbde28 4107 if (!ISDIGIT ((unsigned char)**args))
70d5ccef
DT
4108 return 0;
4109
f6bbde28 4110 while (ISDIGIT ((unsigned char)**args))
70d5ccef
DT
4111 {
4112 char_str[0] = **args;
4113 string_append (arg, char_str);
4114 (*args)++;
4115 }
4116
4117 return 1;
4118}
4119
9923cc56
MM
4120/* Demangle the next argument, given by MANGLED into RESULT, which
4121 *should be an uninitialized* string. It will be initialized here,
4122 and free'd should anything go wrong. */
6599da04
JM
4123
4124static int
4125do_arg (work, mangled, result)
4126 struct work_stuff *work;
4127 const char **mangled;
4128 string *result;
4129{
9923cc56
MM
4130 /* Remember where we started so that we can record the type, for
4131 non-squangling type remembering. */
6599da04
JM
4132 const char *start = *mangled;
4133
9923cc56
MM
4134 string_init (result);
4135
4136 if (work->nrepeats > 0)
6599da04 4137 {
9923cc56
MM
4138 --work->nrepeats;
4139
4140 if (work->previous_argument == 0)
4141 return 0;
4142
2363489c 4143 /* We want to reissue the previous type in this argument list. */
9923cc56
MM
4144 string_appends (result, work->previous_argument);
4145 return 1;
6599da04 4146 }
9923cc56
MM
4147
4148 if (**mangled == 'n')
4149 {
4150 /* A squangling-style repeat. */
4151 (*mangled)++;
4152 work->nrepeats = consume_count(mangled);
4153
9d229989 4154 if (work->nrepeats <= 0)
9923cc56
MM
4155 /* This was not a repeat count after all. */
4156 return 0;
4157
4158 if (work->nrepeats > 9)
4159 {
4160 if (**mangled != '_')
4161 /* The repeat count should be followed by an '_' in this
4162 case. */
4163 return 0;
4164 else
4165 (*mangled)++;
4166 }
2363489c 4167
9923cc56
MM
4168 /* Now, the repeat is all set up. */
4169 return do_arg (work, mangled, result);
4170 }
4171
4172 /* Save the result in WORK->previous_argument so that we can find it
4173 if it's repeated. Note that saving START is not good enough: we
4174 do not want to add additional types to the back-referenceable
4175 type vector when processing a repeated type. */
4176 if (work->previous_argument)
4177 string_clear (work->previous_argument);
6599da04
JM
4178 else
4179 {
9923cc56
MM
4180 work->previous_argument = (string*) xmalloc (sizeof (string));
4181 string_init (work->previous_argument);
6599da04 4182 }
9923cc56
MM
4183
4184 if (!do_type (work, mangled, work->previous_argument))
4185 return 0;
4186
4187 string_appends (result, work->previous_argument);
4188
4189 remember_type (work, start, *mangled - start);
4190 return 1;
6599da04
JM
4191}
4192
4193static void
4194remember_type (work, start, len)
4195 struct work_stuff *work;
4196 const char *start;
4197 int len;
4198{
4199 char *tem;
4200
9923cc56
MM
4201 if (work->forgetting_types)
4202 return;
4203
6599da04
JM
4204 if (work -> ntypes >= work -> typevec_size)
4205 {
4206 if (work -> typevec_size == 0)
4207 {
4208 work -> typevec_size = 3;
4209 work -> typevec
4210 = (char **) xmalloc (sizeof (char *) * work -> typevec_size);
4211 }
4212 else
4213 {
4214 work -> typevec_size *= 2;
4215 work -> typevec
4216 = (char **) xrealloc ((char *)work -> typevec,
4217 sizeof (char *) * work -> typevec_size);
4218 }
4219 }
4220 tem = xmalloc (len + 1);
4221 memcpy (tem, start, len);
4222 tem[len] = '\0';
4223 work -> typevec[work -> ntypes++] = tem;
4224}
4225
5e5199e8
AM
4226
4227/* Remember a K type class qualifier. */
4228static void
4229remember_Ktype (work, start, len)
4230 struct work_stuff *work;
4231 const char *start;
4232 int len;
4233{
4234 char *tem;
4235
4236 if (work -> numk >= work -> ksize)
4237 {
4238 if (work -> ksize == 0)
4239 {
4240 work -> ksize = 5;
4241 work -> ktypevec
4242 = (char **) xmalloc (sizeof (char *) * work -> ksize);
4243 }
4244 else
4245 {
4246 work -> ksize *= 2;
4247 work -> ktypevec
4248 = (char **) xrealloc ((char *)work -> ktypevec,
4249 sizeof (char *) * work -> ksize);
4250 }
4251 }
4252 tem = xmalloc (len + 1);
4253 memcpy (tem, start, len);
4254 tem[len] = '\0';
4255 work -> ktypevec[work -> numk++] = tem;
4256}
4257
4258/* Register a B code, and get an index for it. B codes are registered
2363489c 4259 as they are seen, rather than as they are completed, so map<temp<char> >
5e5199e8
AM
4260 registers map<temp<char> > as B0, and temp<char> as B1 */
4261
4262static int
4263register_Btype (work)
4264 struct work_stuff *work;
4265{
4266 int ret;
2363489c 4267
5e5199e8
AM
4268 if (work -> numb >= work -> bsize)
4269 {
4270 if (work -> bsize == 0)
4271 {
4272 work -> bsize = 5;
4273 work -> btypevec
4274 = (char **) xmalloc (sizeof (char *) * work -> bsize);
4275 }
4276 else
4277 {
4278 work -> bsize *= 2;
4279 work -> btypevec
4280 = (char **) xrealloc ((char *)work -> btypevec,
4281 sizeof (char *) * work -> bsize);
4282 }
4283 }
4284 ret = work -> numb++;
4285 work -> btypevec[ret] = NULL;
4286 return(ret);
4287}
4288
4289/* Store a value into a previously registered B code type. */
4290
4291static void
4292remember_Btype (work, start, len, index)
4293 struct work_stuff *work;
4294 const char *start;
4295 int len, index;
4296{
4297 char *tem;
4298
4299 tem = xmalloc (len + 1);
4300 memcpy (tem, start, len);
4301 tem[len] = '\0';
4302 work -> btypevec[index] = tem;
4303}
4304
4305/* Lose all the info related to B and K type codes. */
4306static void
4307forget_B_and_K_types (work)
4308 struct work_stuff *work;
4309{
4310 int i;
4311
4312 while (work -> numk > 0)
4313 {
4314 i = --(work -> numk);
4315 if (work -> ktypevec[i] != NULL)
4316 {
4317 free (work -> ktypevec[i]);
4318 work -> ktypevec[i] = NULL;
4319 }
4320 }
4321
4322 while (work -> numb > 0)
4323 {
4324 i = --(work -> numb);
4325 if (work -> btypevec[i] != NULL)
4326 {
4327 free (work -> btypevec[i]);
4328 work -> btypevec[i] = NULL;
4329 }
4330 }
4331}
6599da04
JM
4332/* Forget the remembered types, but not the type vector itself. */
4333
4334static void
4335forget_types (work)
4336 struct work_stuff *work;
4337{
4338 int i;
4339
4340 while (work -> ntypes > 0)
4341 {
4342 i = --(work -> ntypes);
4343 if (work -> typevec[i] != NULL)
4344 {
4345 free (work -> typevec[i]);
4346 work -> typevec[i] = NULL;
4347 }
4348 }
4349}
4350
4351/* Process the argument list part of the signature, after any class spec
4352 has been consumed, as well as the first 'F' character (if any). For
4353 example:
4354
4355 "__als__3fooRT0" => process "RT0"
4356 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
4357
4358 DECLP must be already initialised, usually non-empty. It won't be freed
4359 on failure.
4360
4361 Note that g++ differs significantly from ARM and lucid style mangling
4362 with regards to references to previously seen types. For example, given
4363 the source fragment:
4364
4365 class foo {
4366 public:
4367 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic);
4368 };
4369
4370 foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4371 void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; }
4372
4373 g++ produces the names:
4374
4375 __3fooiRT0iT2iT2
4376 foo__FiR3fooiT1iT1
4377
4378 while lcc (and presumably other ARM style compilers as well) produces:
4379
4380 foo__FiR3fooT1T2T1T2
4381 __ct__3fooFiR3fooT1T2T1T2
4382
9923cc56
MM
4383 Note that g++ bases its type numbers starting at zero and counts all
4384 previously seen types, while lucid/ARM bases its type numbers starting
6599da04
JM
4385 at one and only considers types after it has seen the 'F' character
4386 indicating the start of the function args. For lucid/ARM style, we
4387 account for this difference by discarding any previously seen types when
4388 we see the 'F' character, and subtracting one from the type number
4389 reference.
4390
4391 */
4392
4393static int
4394demangle_args (work, mangled, declp)
4395 struct work_stuff *work;
4396 const char **mangled;
4397 string *declp;
4398{
4399 string arg;
4400 int need_comma = 0;
4401 int r;
4402 int t;
4403 const char *tem;
4404 char temptype;
4405
4406 if (PRINT_ARG_TYPES)
4407 {
4408 string_append (declp, "(");
4409 if (**mangled == '\0')
4410 {
4411 string_append (declp, "void");
4412 }
4413 }
4414
9923cc56
MM
4415 while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
4416 || work->nrepeats > 0)
6599da04
JM
4417 {
4418 if ((**mangled == 'N') || (**mangled == 'T'))
4419 {
4420 temptype = *(*mangled)++;
2363489c 4421
6599da04
JM
4422 if (temptype == 'N')
4423 {
4424 if (!get_count (mangled, &r))
4425 {
4426 return (0);
4427 }
4428 }
4429 else
4430 {
4431 r = 1;
4432 }
70d5ccef 4433 if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10)
6599da04
JM
4434 {
4435 /* If we have 10 or more types we might have more than a 1 digit
4436 index so we'll have to consume the whole count here. This
4437 will lose if the next thing is a type name preceded by a
4438 count but it's impossible to demangle that case properly
4439 anyway. Eg if we already have 12 types is T12Pc "(..., type1,
4440 Pc, ...)" or "(..., type12, char *, ...)" */
9d229989 4441 if ((t = consume_count(mangled)) <= 0)
6599da04
JM
4442 {
4443 return (0);
4444 }
4445 }
4446 else
4447 {
4448 if (!get_count (mangled, &t))
4449 {
4450 return (0);
4451 }
4452 }
70d5ccef 4453 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
6599da04
JM
4454 {
4455 t--;
4456 }
4457 /* Validate the type index. Protect against illegal indices from
4458 malformed type strings. */
4459 if ((t < 0) || (t >= work -> ntypes))
4460 {
4461 return (0);
4462 }
9923cc56 4463 while (work->nrepeats > 0 || --r >= 0)
6599da04
JM
4464 {
4465 tem = work -> typevec[t];
4466 if (need_comma && PRINT_ARG_TYPES)
4467 {
4468 string_append (declp, ", ");
4469 }
4470 if (!do_arg (work, &tem, &arg))
4471 {
4472 return (0);
4473 }
4474 if (PRINT_ARG_TYPES)
4475 {
4476 string_appends (declp, &arg);
4477 }
4478 string_delete (&arg);
4479 need_comma = 1;
4480 }
4481 }
4482 else
4483 {
9923cc56
MM
4484 if (need_comma && PRINT_ARG_TYPES)
4485 string_append (declp, ", ");
6599da04 4486 if (!do_arg (work, mangled, &arg))
9923cc56 4487 return (0);
6599da04 4488 if (PRINT_ARG_TYPES)
9923cc56 4489 string_appends (declp, &arg);
6599da04
JM
4490 string_delete (&arg);
4491 need_comma = 1;
4492 }
4493 }
4494
4495 if (**mangled == 'e')
4496 {
4497 (*mangled)++;
4498 if (PRINT_ARG_TYPES)
4499 {
4500 if (need_comma)
4501 {
4502 string_append (declp, ",");
4503 }
4504 string_append (declp, "...");
4505 }
4506 }
4507
4508 if (PRINT_ARG_TYPES)
4509 {
4510 string_append (declp, ")");
4511 }
4512 return (1);
4513}
4514
9923cc56
MM
4515/* Like demangle_args, but for demangling the argument lists of function
4516 and method pointers or references, not top-level declarations. */
4517
d94f5c58 4518static int
9923cc56
MM
4519demangle_nested_args (work, mangled, declp)
4520 struct work_stuff *work;
4521 const char **mangled;
4522 string *declp;
4523{
4524 string* saved_previous_argument;
4525 int result;
4526 int saved_nrepeats;
4527
4528 /* The G++ name-mangling algorithm does not remember types on nested
4529 argument lists, unless -fsquangling is used, and in that case the
4530 type vector updated by remember_type is not used. So, we turn
4531 off remembering of types here. */
4532 ++work->forgetting_types;
4533
4534 /* For the repeat codes used with -fsquangling, we must keep track of
4535 the last argument. */
4536 saved_previous_argument = work->previous_argument;
4537 saved_nrepeats = work->nrepeats;
4538 work->previous_argument = 0;
4539 work->nrepeats = 0;
4540
4541 /* Actually demangle the arguments. */
4542 result = demangle_args (work, mangled, declp);
2363489c 4543
9923cc56
MM
4544 /* Restore the previous_argument field. */
4545 if (work->previous_argument)
4546 string_delete (work->previous_argument);
4547 work->previous_argument = saved_previous_argument;
3510075c 4548 --work->forgetting_types;
9923cc56
MM
4549 work->nrepeats = saved_nrepeats;
4550
4551 return result;
4552}
4553
6599da04
JM
4554static void
4555demangle_function_name (work, mangled, declp, scan)
4556 struct work_stuff *work;
4557 const char **mangled;
4558 string *declp;
4559 const char *scan;
4560{
9ee02b5c 4561 size_t i;
6599da04
JM
4562 string type;
4563 const char *tem;
4564
4565 string_appendn (declp, (*mangled), scan - (*mangled));
4566 string_need (declp, 1);
4567 *(declp -> p) = '\0';
4568
4569 /* Consume the function name, including the "__" separating the name
4570 from the signature. We are guaranteed that SCAN points to the
4571 separator. */
4572
4573 (*mangled) = scan + 2;
70d5ccef
DT
4574 /* We may be looking at an instantiation of a template function:
4575 foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a
4576 following _F marks the start of the function arguments. Handle
4577 the template arguments first. */
2363489c 4578
70d5ccef
DT
4579 if (HP_DEMANGLING && (**mangled == 'X'))
4580 {
4581 demangle_arm_hp_template (work, mangled, 0, declp);
4582 /* This leaves MANGLED pointing to the 'F' marking func args */
4583 }
6599da04 4584
70d5ccef 4585 if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)
6599da04
JM
4586 {
4587
4588 /* See if we have an ARM style constructor or destructor operator.
4589 If so, then just record it, clear the decl, and return.
4590 We can't build the actual constructor/destructor decl until later,
4591 when we recover the class name from the signature. */
4592
4593 if (strcmp (declp -> b, "__ct") == 0)
4594 {
4595 work -> constructor += 1;
4596 string_clear (declp);
4597 return;
4598 }
4599 else if (strcmp (declp -> b, "__dt") == 0)
4600 {
4601 work -> destructor += 1;
4602 string_clear (declp);
4603 return;
4604 }
4605 }
4606
2363489c 4607 if (declp->p - declp->b >= 3
6599da04
JM
4608 && declp->b[0] == 'o'
4609 && declp->b[1] == 'p'
4610 && strchr (cplus_markers, declp->b[2]) != NULL)
4611 {
4612 /* see if it's an assignment expression */
4613 if (declp->p - declp->b >= 10 /* op$assign_ */
4614 && memcmp (declp->b + 3, "assign_", 7) == 0)
4615 {
2f26c11d 4616 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04 4617 {
9ee02b5c 4618 int len = declp->p - declp->b - 10;
91e0f659 4619 if ((int) strlen (optable[i].in) == len
6599da04
JM
4620 && memcmp (optable[i].in, declp->b + 10, len) == 0)
4621 {
4622 string_clear (declp);
4623 string_append (declp, "operator");
4624 string_append (declp, optable[i].out);
4625 string_append (declp, "=");
4626 break;
4627 }
4628 }
4629 }
4630 else
4631 {
2f26c11d 4632 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
4633 {
4634 int len = declp->p - declp->b - 3;
2363489c 4635 if ((int) strlen (optable[i].in) == len
6599da04
JM
4636 && memcmp (optable[i].in, declp->b + 3, len) == 0)
4637 {
4638 string_clear (declp);
4639 string_append (declp, "operator");
4640 string_append (declp, optable[i].out);
4641 break;
4642 }
4643 }
4644 }
4645 }
4646 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0
4647 && strchr (cplus_markers, declp->b[4]) != NULL)
4648 {
4649 /* type conversion operator */
4650 tem = declp->b + 5;
4651 if (do_type (work, &tem, &type))
4652 {
4653 string_clear (declp);
4654 string_append (declp, "operator ");
4655 string_appends (declp, &type);
4656 string_delete (&type);
4657 }
4658 }
4659 else if (declp->b[0] == '_' && declp->b[1] == '_'
4660 && declp->b[2] == 'o' && declp->b[3] == 'p')
4661 {
4662 /* ANSI. */
4663 /* type conversion operator. */
4664 tem = declp->b + 4;
4665 if (do_type (work, &tem, &type))
4666 {
4667 string_clear (declp);
4668 string_append (declp, "operator ");
4669 string_appends (declp, &type);
4670 string_delete (&type);
4671 }
4672 }
4673 else if (declp->b[0] == '_' && declp->b[1] == '_'
f6bbde28
ZW
4674 && ISLOWER((unsigned char)declp->b[2])
4675 && ISLOWER((unsigned char)declp->b[3]))
6599da04
JM
4676 {
4677 if (declp->b[4] == '\0')
4678 {
4679 /* Operator. */
2f26c11d 4680 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
4681 {
4682 if (strlen (optable[i].in) == 2
4683 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
4684 {
4685 string_clear (declp);
4686 string_append (declp, "operator");
4687 string_append (declp, optable[i].out);
4688 break;
4689 }
4690 }
4691 }
4692 else
4693 {
4694 if (declp->b[2] == 'a' && declp->b[5] == '\0')
4695 {
4696 /* Assignment. */
2f26c11d 4697 for (i = 0; i < ARRAY_SIZE (optable); i++)
6599da04
JM
4698 {
4699 if (strlen (optable[i].in) == 3
4700 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
4701 {
4702 string_clear (declp);
4703 string_append (declp, "operator");
4704 string_append (declp, optable[i].out);
4705 break;
2363489c 4706 }
6599da04
JM
4707 }
4708 }
4709 }
4710 }
4711}
4712
4713/* a mini string-handling package */
4714
4715static void
4716string_need (s, n)
4717 string *s;
4718 int n;
4719{
4720 int tem;
4721
4722 if (s->b == NULL)
4723 {
4724 if (n < 32)
4725 {
4726 n = 32;
4727 }
4728 s->p = s->b = xmalloc (n);
4729 s->e = s->b + n;
4730 }
4731 else if (s->e - s->p < n)
4732 {
4733 tem = s->p - s->b;
4734 n += tem;
4735 n *= 2;
4736 s->b = xrealloc (s->b, n);
4737 s->p = s->b + tem;
4738 s->e = s->b + n;
4739 }
4740}
4741
4742static void
4743string_delete (s)
4744 string *s;
4745{
4746 if (s->b != NULL)
4747 {
4748 free (s->b);
4749 s->b = s->e = s->p = NULL;
4750 }
4751}
4752
4753static void
4754string_init (s)
4755 string *s;
4756{
4757 s->b = s->p = s->e = NULL;
4758}
4759
2363489c 4760static void
6599da04
JM
4761string_clear (s)
4762 string *s;
4763{
4764 s->p = s->b;
4765}
4766
4767#if 0
4768
4769static int
4770string_empty (s)
4771 string *s;
4772{
4773 return (s->b == s->p);
4774}
4775
4776#endif
4777
4778static void
4779string_append (p, s)
4780 string *p;
4781 const char *s;
4782{
4783 int n;
4784 if (s == NULL || *s == '\0')
4785 return;
4786 n = strlen (s);
4787 string_need (p, n);
4788 memcpy (p->p, s, n);
4789 p->p += n;
4790}
4791
4792static void
4793string_appends (p, s)
4794 string *p, *s;
4795{
4796 int n;
4797
4798 if (s->b != s->p)
4799 {
4800 n = s->p - s->b;
4801 string_need (p, n);
4802 memcpy (p->p, s->b, n);
4803 p->p += n;
4804 }
4805}
4806
4807static void
4808string_appendn (p, s, n)
4809 string *p;
4810 const char *s;
4811 int n;
4812{
4813 if (n != 0)
4814 {
4815 string_need (p, n);
4816 memcpy (p->p, s, n);
4817 p->p += n;
4818 }
4819}
4820
4821static void
4822string_prepend (p, s)
4823 string *p;
4824 const char *s;
4825{
4826 if (s != NULL && *s != '\0')
4827 {
4828 string_prependn (p, s, strlen (s));
4829 }
4830}
4831
4832static void
4833string_prepends (p, s)
4834 string *p, *s;
4835{
4836 if (s->b != s->p)
4837 {
4838 string_prependn (p, s->b, s->p - s->b);
4839 }
4840}
4841
4842static void
4843string_prependn (p, s, n)
4844 string *p;
4845 const char *s;
4846 int n;
4847{
4848 char *q;
4849
4850 if (n != 0)
4851 {
4852 string_need (p, n);
4853 for (q = p->p - 1; q >= p->b; q--)
4854 {
4855 q[n] = q[0];
4856 }
4857 memcpy (p->b, s, n);
4858 p->p += n;
4859 }
4860}
4861
b60fe4a7
MM
4862static void
4863string_append_template_idx (s, idx)
4864 string *s;
4865 int idx;
4866{
4867 char buf[INTBUF_SIZE + 1 /* 'T' */];
4868 sprintf(buf, "T%d", idx);
4869 string_append (s, buf);
4870}
4871
6599da04
JM
4872/* To generate a standalone demangler program for testing purposes,
4873 just compile and link this file with -DMAIN and libiberty.a. When
4874 run, it demangles each command line arg, or each stdin string, and
4875 prints the result on stdout. */
4876
4877#ifdef MAIN
4878
4879#include "getopt.h"
4880
2a138827
KG
4881static const char *program_name;
4882static const char *program_version = VERSION;
6599da04
JM
4883static int flags = DMGL_PARAMS | DMGL_ANSI;
4884
4885static void demangle_it PARAMS ((char *));
2a138827
KG
4886static void usage PARAMS ((FILE *, int)) ATTRIBUTE_NORETURN;
4887static void fatal PARAMS ((const char *)) ATTRIBUTE_NORETURN;
a85a47fb 4888static void print_demangler_list PARAMS ((FILE *));
6599da04
JM
4889
4890static void
4891demangle_it (mangled_name)
4892 char *mangled_name;
4893{
4894 char *result;
4895
4896 result = cplus_demangle (mangled_name, flags);
4897 if (result == NULL)
4898 {
4899 printf ("%s\n", mangled_name);
4900 }
4901 else
4902 {
4903 printf ("%s\n", result);
4904 free (result);
4905 }
4906}
4907
24eaa47a
KB
4908static void
4909print_demangler_list (stream)
4910 FILE *stream;
4911{
4912 struct demangler_engine *demangler;
4913
4914 fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
4915
4916 for (demangler = libiberty_demanglers + 1;
4917 demangler->demangling_style != unknown_demangling;
4918 ++demangler)
4919 fprintf (stream, ",%s", demangler->demangling_style_name);
4920
4921 fprintf (stream, "}");
4922}
4923
6599da04
JM
4924static void
4925usage (stream, status)
4926 FILE *stream;
4927 int status;
2363489c 4928{
6599da04 4929 fprintf (stream, "\
24eaa47a 4930Usage: %s [-_] [-n] [--strip-underscores] [--no-strip-underscores] \n",
6599da04 4931 program_name);
24eaa47a
KB
4932
4933 fprintf (stream, "\
4934 [-s ");
4935 print_demangler_list (stream);
4936 fprintf (stream, "]\n");
4937
4938 fprintf (stream, "\
4939 [--format ");
4940 print_demangler_list (stream);
4941 fprintf (stream, "]\n");
4942
4943 fprintf (stream, "\
4944 [--help] [--version] [arg...]\n");
6599da04
JM
4945 exit (status);
4946}
4947
911c3b7d 4948#define MBUF_SIZE 32767
6599da04
JM
4949char mbuffer[MBUF_SIZE];
4950
4951/* Defined in the automatically-generated underscore.c. */
4952extern int prepends_underscore;
4953
4954int strip_underscore = 0;
4955
4956static struct option long_options[] = {
4957 {"strip-underscores", no_argument, 0, '_'},
4958 {"format", required_argument, 0, 's'},
4959 {"help", no_argument, 0, 'h'},
6599da04
JM
4960 {"no-strip-underscores", no_argument, 0, 'n'},
4961 {"version", no_argument, 0, 'v'},
4962 {0, no_argument, 0, 0}
4963};
4964
9ee02b5c
JL
4965/* More 'friendly' abort that prints the line and file.
4966 config.h can #define abort fancy_abort if you like that sort of thing. */
4967
4968void
4969fancy_abort ()
4970{
4971 fatal ("Internal gcc abort.");
4972}
4973
3eca405b 4974
a82cecda
JK
4975static const char *
4976standard_symbol_characters PARAMS ((void));
4977
4978static const char *
4979hp_symbol_characters PARAMS ((void));
4980
69afa80d 4981static const char *
c6e13630 4982gnu_v3_symbol_characters PARAMS ((void));
69afa80d 4983
3a08531d
ME
4984/* Return the string of non-alnum characters that may occur
4985 as a valid symbol component, in the standard assembler symbol
3eca405b 4986 syntax. */
3eca405b 4987
3a08531d
ME
4988static const char *
4989standard_symbol_characters ()
4990{
4991 return "_$.";
3eca405b
JB
4992}
4993
4994
3a08531d
ME
4995/* Return the string of non-alnum characters that may occur
4996 as a valid symbol name component in an HP object file.
3eca405b
JB
4997
4998 Note that, since HP's compiler generates object code straight from
4999 C++ source, without going through an assembler, its mangled
5000 identifiers can use all sorts of characters that no assembler would
5001 tolerate, so the alphabet this function creates is a little odd.
5002 Here are some sample mangled identifiers offered by HP:
5003
5004 typeid*__XT24AddressIndExpClassMember_
5005 [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv
5006 __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv
5007
5008 This still seems really weird to me, since nowhere else in this
5009 file is there anything to recognize curly brackets, parens, etc.
5010 I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me
5011 this is right, but I still strongly suspect that there's a
5012 misunderstanding here.
5013
5014 If we decide it's better for c++filt to use HP's assembler syntax
5015 to scrape identifiers out of its input, here's the definition of
5016 the symbol name syntax from the HP assembler manual:
5017
5018 Symbols are composed of uppercase and lowercase letters, decimal
5019 digits, dollar symbol, period (.), ampersand (&), pound sign(#) and
5020 underscore (_). A symbol can begin with a letter, digit underscore or
5021 dollar sign. If a symbol begins with a digit, it must contain a
5022 non-digit character.
5023
5024 So have fun. */
3a08531d
ME
5025static const char *
5026hp_symbol_characters ()
3eca405b 5027{
3a08531d 5028 return "_$.<>#,*&[]:(){}";
3eca405b
JB
5029}
5030
5031
69afa80d 5032/* Return the string of non-alnum characters that may occur
c6e13630 5033 as a valid symbol component in the GNU C++ V3 ABI mangling
69afa80d
AS
5034 scheme. */
5035
5036static const char *
c6e13630 5037gnu_v3_symbol_characters ()
69afa80d 5038{
31e0ab1f 5039 return "_$.";
69afa80d
AS
5040}
5041
5042
2a138827
KG
5043extern int main PARAMS ((int, char **));
5044
6599da04
JM
5045int
5046main (argc, argv)
5047 int argc;
5048 char **argv;
5049{
5050 char *result;
5051 int c;
e797ff70 5052 const char *valid_symbols;
4031ed65 5053 enum demangling_styles style = auto_demangling;
6599da04
JM
5054
5055 program_name = argv[0];
5056
5057 strip_underscore = prepends_underscore;
5058
3b60dd8e 5059 while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
6599da04
JM
5060 {
5061 switch (c)
5062 {
5063 case '?':
5064 usage (stderr, 1);
5065 break;
5066 case 'h':
5067 usage (stdout, 0);
5068 case 'n':
5069 strip_underscore = 0;
5070 break;
5071 case 'v':
70d5ccef 5072 printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version);
2a138827 5073 return (0);
6599da04
JM
5074 case '_':
5075 strip_underscore = 1;
5076 break;
6599da04 5077 case 's':
24eaa47a 5078 {
24eaa47a
KB
5079 style = cplus_demangle_name_to_style (optarg);
5080 if (style == unknown_demangling)
5081 {
5082 fprintf (stderr, "%s: unknown demangling style `%s'\n",
5083 program_name, optarg);
5084 return (1);
5085 }
5086 else
5087 cplus_demangle_set_style (style);
5088 }
6599da04
JM
5089 break;
5090 }
5091 }
5092
5093 if (optind < argc)
5094 {
5095 for ( ; optind < argc; optind++)
5096 {
5097 demangle_it (argv[optind]);
5098 }
5099 }
5100 else
5101 {
3eca405b
JB
5102 switch (current_demangling_style)
5103 {
5104 case gnu_demangling:
5105 case lucid_demangling:
5106 case arm_demangling:
cf183ac2 5107 case java_demangling:
3eca405b 5108 case edg_demangling:
3b3bd9a7 5109 case gnat_demangling:
c6e13630 5110 case auto_demangling:
3a08531d 5111 valid_symbols = standard_symbol_characters ();
3eca405b
JB
5112 break;
5113 case hp_demangling:
3a08531d 5114 valid_symbols = hp_symbol_characters ();
3eca405b 5115 break;
c6e13630
JM
5116 case gnu_v3_demangling:
5117 valid_symbols = gnu_v3_symbol_characters ();
69afa80d 5118 break;
3eca405b
JB
5119 default:
5120 /* Folks should explicitly indicate the appropriate alphabet for
5121 each demangling. Providing a default would allow the
5122 question to go unconsidered. */
5123 abort ();
5124 }
5125
6599da04
JM
5126 for (;;)
5127 {
5128 int i = 0;
5129 c = getchar ();
5130 /* Try to read a label. */
f6bbde28 5131 while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
6599da04
JM
5132 {
5133 if (i >= MBUF_SIZE-1)
5134 break;
5135 mbuffer[i++] = c;
5136 c = getchar ();
5137 }
5138 if (i > 0)
5139 {
5140 int skip_first = 0;
5141
e03a61f1 5142 if (mbuffer[0] == '.' || mbuffer[0] == '$')
6599da04
JM
5143 ++skip_first;
5144 if (strip_underscore && mbuffer[skip_first] == '_')
5145 ++skip_first;
5146
5147 if (skip_first > i)
5148 skip_first = i;
5149
5150 mbuffer[i] = 0;
d9fd5aae 5151 flags |= (int) style;
6599da04
JM
5152 result = cplus_demangle (mbuffer + skip_first, flags);
5153 if (result)
5154 {
5155 if (mbuffer[0] == '.')
5156 putc ('.', stdout);
5157 fputs (result, stdout);
5158 free (result);
5159 }
5160 else
5161 fputs (mbuffer, stdout);
5162
5163 fflush (stdout);
5164 }
5165 if (c == EOF)
5166 break;
5167 putchar (c);
6d0be369 5168 fflush (stdout);
6599da04
JM
5169 }
5170 }
5171
2a138827 5172 return (0);
6599da04
JM
5173}
5174
5175static void
5176fatal (str)
2a138827 5177 const char *str;
6599da04
JM
5178{
5179 fprintf (stderr, "%s: %s\n", program_name, str);
5180 exit (1);
5181}
5182
9b1a92d8 5183PTR
6599da04 5184xmalloc (size)
9b1a92d8 5185 size_t size;
6599da04 5186{
9b1a92d8 5187 register PTR value = (PTR) malloc (size);
6599da04
JM
5188 if (value == 0)
5189 fatal ("virtual memory exhausted");
5190 return value;
5191}
5192
9b1a92d8 5193PTR
6599da04 5194xrealloc (ptr, size)
9b1a92d8
KG
5195 PTR ptr;
5196 size_t size;
6599da04 5197{
9b1a92d8 5198 register PTR value = (PTR) realloc (ptr, size);
6599da04
JM
5199 if (value == 0)
5200 fatal ("virtual memory exhausted");
5201 return value;
5202}
5203#endif /* main */