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