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