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