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