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