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