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