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