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