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