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