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