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