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