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