HPPA merge.
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
CommitLineData
dd3b648e 1/* Demangler for GNU C++
7d9884b9 2 Copyright 1989, 1991 Free Software Foundation, Inc.
f9b5584c
FF
3 Written by James Clark (jjc@jclark.uucp)
4 Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
dd3b648e 5
572acbbe
MT
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
99a7de40 10
572acbbe
MT
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
99a7de40 15
572acbbe
MT
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e 19
f9b5584c 20/* This is for g++ 1.95.03 (November 13 version). */
dd3b648e 21
8f793aa5 22/* This file exports two functions; cplus_mangle_opname and cplus_demangle.
dd3b648e
RP
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
e1ce8aa5
JK
28/* GDB-specific, FIXME. */
29#include "defs.h"
8f793aa5 30#include "demangle.h"
e1ce8aa5 31
d747e0af 32#include <ctype.h>
dd3b648e 33#include <string.h>
dd3b648e 34
f9b5584c
FF
35#if !defined (GNU_DEMANGLING) && !defined (ARM_DEMANGLING)
36# define GNU_DEMANGLING 1
37#endif
38
8ffd75c8
JG
39/* This is '$' on systems where the assembler can deal with that.
40 Where the assembler can't, it's '.' (but on many systems '.' is
41 used for other things). */
f9b5584c 42
8ffd75c8
JG
43#if !defined (CPLUS_MARKER)
44#define CPLUS_MARKER '$'
45#endif
46
dd3b648e
RP
47#ifndef __STDC__
48#define const
49#endif
50
f9b5584c
FF
51/* Stuff that is shared between sub-routines.
52 * Using a shared structure allows cplus_demangle to be reentrant. */
f536aa39 53
f9b5584c
FF
54struct work_stuff
55{
8f793aa5 56 int options;
f536aa39
PB
57 char **typevec;
58 int ntypes;
59 int typevec_size;
f9b5584c
FF
60 int constructor;
61 int destructor;
62 int static_type; /* A static member function */
63 int const_type; /* A const member function */
f536aa39 64};
dd3b648e 65
f9b5584c
FF
66#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
67#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS)
68
69static const struct optable
70{
dd3b648e
RP
71 const char *in;
72 const char *out;
8f793aa5 73 int flags;
dd3b648e 74} optable[] = {
8f793aa5
FF
75 "nw", " new", DMGL_ANSI, /* new (1.92, ansi) */
76 "dl", " delete", DMGL_ANSI, /* new (1.92, ansi) */
77 "new", " new", 0, /* old (1.91, and 1.x) */
78 "delete", " delete", 0, /* old (1.91, and 1.x) */
79 "as", "=", DMGL_ANSI, /* ansi */
80 "ne", "!=", DMGL_ANSI, /* old, ansi */
81 "eq", "==", DMGL_ANSI, /* old, ansi */
82 "ge", ">=", DMGL_ANSI, /* old, ansi */
83 "gt", ">", DMGL_ANSI, /* old, ansi */
84 "le", "<=", DMGL_ANSI, /* old, ansi */
85 "lt", "<", DMGL_ANSI, /* old, ansi */
86 "plus", "+", 0, /* old */
87 "pl", "+", DMGL_ANSI, /* ansi */
88 "apl", "+=", DMGL_ANSI, /* ansi */
89 "minus", "-", 0, /* old */
90 "mi", "-", DMGL_ANSI, /* ansi */
91 "ami", "-=", DMGL_ANSI, /* ansi */
92 "mult", "*", 0, /* old */
93 "ml", "*", DMGL_ANSI, /* ansi */
f9b5584c
FF
94#ifdef ARM_DEMANGLING
95 "amu", "*=", DMGL_ANSI, /* ansi */
96#else
8f793aa5 97 "aml", "*=", DMGL_ANSI, /* ansi */
f9b5584c 98#endif
8f793aa5
FF
99 "convert", "+", 0, /* old (unary +) */
100 "negate", "-", 0, /* old (unary -) */
101 "trunc_mod", "%", 0, /* old */
102 "md", "%", DMGL_ANSI, /* ansi */
103 "amd", "%=", DMGL_ANSI, /* ansi */
104 "trunc_div", "/", 0, /* old */
105 "dv", "/", DMGL_ANSI, /* ansi */
106 "adv", "/=", DMGL_ANSI, /* ansi */
107 "truth_andif", "&&", 0, /* old */
108 "aa", "&&", DMGL_ANSI, /* ansi */
109 "truth_orif", "||", 0, /* old */
110 "oo", "||", DMGL_ANSI, /* ansi */
111 "truth_not", "!", 0, /* old */
112 "nt", "!", DMGL_ANSI, /* ansi */
113 "postincrement","++", 0, /* old */
114 "pp", "++", DMGL_ANSI, /* ansi */
115 "postdecrement","--", 0, /* old */
116 "mm", "--", DMGL_ANSI, /* ansi */
117 "bit_ior", "|", 0, /* old */
118 "or", "|", DMGL_ANSI, /* ansi */
119 "aor", "|=", DMGL_ANSI, /* ansi */
120 "bit_xor", "^", 0, /* old */
121 "er", "^", DMGL_ANSI, /* ansi */
122 "aer", "^=", DMGL_ANSI, /* ansi */
123 "bit_and", "&", 0, /* old */
124 "ad", "&", DMGL_ANSI, /* ansi */
125 "aad", "&=", DMGL_ANSI, /* ansi */
126 "bit_not", "~", 0, /* old */
127 "co", "~", DMGL_ANSI, /* ansi */
128 "call", "()", 0, /* old */
129 "cl", "()", DMGL_ANSI, /* ansi */
130 "alshift", "<<", 0, /* old */
131 "ls", "<<", DMGL_ANSI, /* ansi */
132 "als", "<<=", DMGL_ANSI, /* ansi */
133 "arshift", ">>", 0, /* old */
134 "rs", ">>", DMGL_ANSI, /* ansi */
135 "ars", ">>=", DMGL_ANSI, /* ansi */
136 "component", "->", 0, /* old */
f9b5584c
FF
137#ifdef LUCID_DEMANGLING
138 "pt", "->", DMGL_ANSI, /* ansi; Lucid C++ form */
139#else
8f793aa5 140 "rf", "->", DMGL_ANSI, /* ansi */
f9b5584c 141#endif
8f793aa5
FF
142 "indirect", "*", 0, /* old */
143 "method_call", "->()", 0, /* old */
144 "addr", "&", 0, /* old (unary &) */
145 "array", "[]", 0, /* old */
146 "vc", "[]", DMGL_ANSI, /* ansi */
147 "compound", ", ", 0, /* old */
148 "cm", ", ", DMGL_ANSI, /* ansi */
149 "cond", "?:", 0, /* old */
150 "cn", "?:", DMGL_ANSI, /* psuedo-ansi */
151 "max", ">?", 0, /* old */
152 "mx", ">?", DMGL_ANSI, /* psuedo-ansi */
153 "min", "<?", 0, /* old */
154 "mn", "<?", DMGL_ANSI, /* psuedo-ansi */
155 "nop", "", 0, /* old (for operator=) */
156 "rm", "->*", DMGL_ANSI, /* ansi */
dd3b648e
RP
157};
158
dd3b648e 159
f9b5584c
FF
160typedef struct string /* Beware: these aren't required to be */
161{ /* '\0' terminated. */
dd3b648e
RP
162 char *b; /* pointer to start of string */
163 char *p; /* pointer after last character */
164 char *e; /* pointer after end of allocated space */
165} string;
166
f9b5584c
FF
167#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
168#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
169 string_prepend(str, " ");}
170#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
171 string_append(str, " ");}
172
173/* Prototypes for local functions */
174
175static char *
176mop_up PARAMS ((string *, struct work_stuff *, int));
177
178static int
179demangle_method_args PARAMS ((string *, const char **, struct work_stuff *));
180
181static int
182demangle_template PARAMS ((string *declp, const char **, struct work_stuff *));
183
184static int
185demangle_qualified PARAMS ((string *, const char **, struct work_stuff *));
186
187static int
188demangle_class PARAMS ((string *, const char **, struct work_stuff *));
189
190static int
191demangle_fund_type PARAMS ((const char **, string *, struct work_stuff *));
192
193static int
194demangle_signature PARAMS ((string *, const char **, struct work_stuff *));
195
196static int
197demangle_prefix PARAMS ((string *, const char **, struct work_stuff *));
198
199static int
200gnu_special PARAMS ((string *, const char **, struct work_stuff *));
201
1ab3bf1b
JG
202static void
203string_need PARAMS ((string *, int));
204
205static void
206string_delete PARAMS ((string *));
207
208static void
209string_init PARAMS ((string *));
210
211static void
212string_clear PARAMS ((string *));
213
214static int
215string_empty PARAMS ((string *));
216
217static void
218string_append PARAMS ((string *, const char *));
219
220static void
221string_appends PARAMS ((string *, string *));
222
223static void
224string_appendn PARAMS ((string *, const char *, int));
225
226static void
227string_prepend PARAMS ((string *, const char *));
228
229static void
230string_prependn PARAMS ((string *, const char *, int));
231
232static int
233get_count PARAMS ((const char **, int *));
234
1c92ca6f
FF
235static int
236consume_count PARAMS ((const char **));
237
1ab3bf1b 238static int
f9b5584c 239demangle_args PARAMS ((string *, const char **, struct work_stuff *));
1ab3bf1b
JG
240
241static int
f536aa39 242do_type PARAMS ((const char **, string *, struct work_stuff *));
1ab3bf1b
JG
243
244static int
f536aa39 245do_arg PARAMS ((const char **, string *, struct work_stuff*));
1ab3bf1b
JG
246
247static void
f9b5584c
FF
248demangle_function_name PARAMS ((string *, const char **, struct work_stuff*,
249 const char *));
1ab3bf1b
JG
250
251static void
f536aa39 252remember_type PARAMS ((const char *, int, struct work_stuff *));
1ab3bf1b 253
dd3b648e 254#if 0
1ab3bf1b
JG
255static void
256string_prepends PARAMS ((string *, string *));
dd3b648e
RP
257#endif
258
1c92ca6f
FF
259/* Translate count to integer, consuming tokens in the process.
260 Conversion terminates on the first non-digit character. */
261
262static int
263consume_count (type)
264 const char **type;
265{
266 int count = 0;
267
268 do
269 {
270 count *= 10;
271 count += **type - '0';
272 (*type)++;
273 } while (isdigit (**type));
274 return (count);
275}
1ab3bf1b 276
55838914 277/* Takes operator name as e.g. "++" and returns mangled
572acbbe
MT
278 operator name (e.g. "postincrement_expr"), or NULL if not found.
279
8f793aa5
FF
280 If OPTIONS & DMGL_ANSI == 1, return the ANSI name;
281 if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */
282
55838914 283char *
8f793aa5 284cplus_mangle_opname (opname, options)
55838914 285 char *opname;
8f793aa5 286 int options;
55838914 287{
f9b5584c
FF
288 int i;
289 int len;
55838914 290
f9b5584c 291 len = strlen (opname);
8f793aa5 292 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
55838914
JK
293 {
294 if (strlen (optable[i].out) == len
8f793aa5 295 && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI)
55838914 296 && memcmp (optable[i].out, opname, len) == 0)
f9b5584c 297 return ((char *)optable[i].in);
55838914 298 }
f9b5584c 299 return (0);
55838914
JK
300}
301
8f793aa5
FF
302/* char *cplus_demangle (const char *name, int options)
303
304 If NAME is a mangled function name produced by GNU C++, then
305 a pointer to a malloced string giving a C++ representation
306 of the name will be returned; otherwise NULL will be returned.
307 It is the caller's responsibility to free the string which
308 is returned.
309
310 The OPTIONS arg may contain one or more of the following bits:
311
312 DMGL_ANSI ANSI qualifiers such as `const' and `void' are
313 included.
314 DMGL_PARAMS Function parameters are included.
315
316 For example,
317
318 cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)"
319 cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)"
320 cplus_demangle ("foo__1Ai", 0) => "A::foo"
321
322 cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)"
323 cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)"
324 cplus_demangle ("foo__1Afe", 0) => "A::foo"
f9b5584c
FF
325
326 Note that any leading underscores, or other such characters prepended by
327 the compilation system, are presumed to have already been stripped from
328 TYPE. */
8f793aa5 329
dd3b648e 330char *
f9b5584c
FF
331cplus_demangle (mangled, options)
332 const char *mangled;
8f793aa5 333 int options;
dd3b648e
RP
334{
335 string decl;
dd3b648e 336 int success = 0;
f536aa39 337 struct work_stuff work[1];
dd3b648e 338 const char *p;
f9b5584c
FF
339 char *demangled = NULL;
340
341 if ((mangled != NULL) && (*mangled != '\0'))
342 {
343 (void) memset ((char *) work, 0, sizeof (work));
344 work -> options = options;
345
346 string_init (&decl);
347 success = demangle_prefix (&decl, &mangled, work);
348 if (success && (*mangled != '\0'))
349 {
350 success = demangle_signature (&decl, &mangled, work);
351 }
352 demangled = mop_up (&decl, work, success);
353 }
354 return (demangled);
355}
356
357static char *
358mop_up (declp, work, success)
359 string *declp;
360 struct work_stuff *work;
361 int success;
362{
363 int i;
364 char *demangled = NULL;
365
366 /* Discard the remembered types, if any. */
367
368 for (i = 0; i < work -> ntypes; i++)
369 {
370 if (work -> typevec[i] != NULL)
371 {
372 free (work -> typevec[i]);
373 }
374 }
375 if (work -> typevec != NULL)
376 {
377 free ((char *) work -> typevec);
378 }
379
380 /* If demangling was successful, ensure that the demangled string is null
381 terminated and return it. Otherwise, free the demangling decl. */
382
383 if (!success)
384 {
385 string_delete (declp);
386 }
387 else
388 {
389 string_appendn (declp, "", 1);
390 demangled = declp -> b;
391 }
392 return (demangled);
393}
394
395/*
396
397LOCAL FUNCTION
398
399 demangle_signature -- demangle the signature part of a mangled name
400
401SYNOPSIS
402
403 static int
404 demangle_signature (string *declp, const char **mangled,
405 struct work_stuff *work);
406
407DESCRIPTION
408
409 Consume and demangle the signature portion of the mangled name.
410
411 DECLP is the string where demangled output is being built. At
412 entry it contains the demangled root name from the mangled name
413 prefix. I.E. either a demangled operator name or the root function
414 name. In some special cases, it may contain nothing.
415
416 *MANGLED points to the current unconsumed location in the mangled
417 name. As tokens are consumed and demangling is performed, the
418 pointer is updated to continuously point at the next token to
419 be consumed.
420
421 Demangling GNU style mangled names is nasty because there is no
422 explicit token that marks the start of the outermost function
423 argument list.
424*/
425
426static int
427demangle_signature (declp, mangled, work)
428 string *declp;
429 const char **mangled;
430 struct work_stuff *work;
431{
432 int success = 1;
433 int func_done = 0;
434#ifdef GNU_DEMANGLING
435 int expect_func = 0;
436#endif
dd3b648e
RP
437#ifndef LONGERNAMES
438 const char *premangle;
439#endif
440
f9b5584c
FF
441#ifndef LONGERNAMES
442 premangle = *mangled;
dd3b648e 443#endif
f536aa39 444
f9b5584c 445 while (success && (**mangled != '\0'))
dd3b648e 446 {
f9b5584c 447 switch (**mangled)
dd3b648e 448 {
f9b5584c
FF
449 case 'Q':
450 success = demangle_qualified (declp, mangled, work);
451#ifdef GNU_DEMANGLING
452 expect_func = 1;
453#endif
454 break;
455
456 case 'S':
457 /* Static member function */
458 (*mangled)++;
459 work -> static_type = 1;
460 break;
461
462 case 'C':
463 /* a const member function */
464 (*mangled)++;
465 work -> const_type = 1;
466 break;
467
468 case '0': case '1': case '2': case '3': case '4':
469 case '5': case '6': case '7': case '8': case '9':
470 success = demangle_class (declp, mangled, work);
471#ifndef LONGERNAMES
472 if (success)
473 {
474 remember_type (premangle, *mangled - premangle, work);
475 }
476#endif
477#ifdef GNU_DEMANGLING
478 expect_func = 1;
479#endif
480 break;
481
482 case 'F':
483 /* Function */
484 /* ARM style demangling includes a specific 'F' character after
485 the class name. For GNU style, it is just implied. So we can
486 safely just consume any 'F' at this point and be compatible
487 with either style. */
488 func_done = 1;
489 (*mangled)++;
490 success = demangle_args (declp, mangled, work);
491 break;
492
493 case 't':
494 /* Template */
495 success = demangle_template (declp, mangled, work);
496 break;
497
7fd31a84
FF
498 case '_':
499 /* At the outermost level, we cannot have a return type specified,
500 so if we run into another '_' at this point we are dealing with
501 a mangled name that is either bogus, or has been mangled by
502 some algorithm we don't know how to deal with. So just
503 reject the entire demangling. */
504 success = 0;
505 break;
506
f9b5584c
FF
507 default:
508#ifdef GNU_DEMANGLING
509 /* Assume we have stumbled onto the first outermost function
510 argument token, and start processing args. */
511 func_done = 1;
512 success = demangle_args (declp, mangled, work);
513#else
514 /* Non-GNU demanglers use a specific token to mark the start
515 of the outermost function argument tokens. Typically 'F',
516 for ARM-demangling, for example. So if we find something
517 we are not prepared for, it must be an error. */
518 success = 0;
519#endif
520 break;
dd3b648e 521 }
f9b5584c 522#ifdef GNU_DEMANGLING
7fd31a84 523 if (success && expect_func)
dd3b648e 524 {
f9b5584c
FF
525 func_done = 1;
526 success = demangle_args (declp, mangled, work);
dd3b648e 527 }
f9b5584c
FF
528#endif
529 }
530 if (success && !func_done)
531 {
4c07f28d
FF
532#ifdef GNU_DEMANGLING
533 /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and
534 bar__3fooi is 'foo::bar(int)'. We get here when we find the
535 first case, and need to ensure that the '(void)' gets added to
536 the current declp. Note that with ARM_DEMANGLING, the first
537 case represents the name of a static data member 'foo::bar',
538 which is in the current declp, so we leave it alone. */
f9b5584c 539 success = demangle_args (declp, mangled, work);
4c07f28d 540#endif
dd3b648e 541 }
f9b5584c
FF
542 if (success && work -> static_type && PRINT_ARG_TYPES)
543 {
544 string_append (declp, " static");
545 }
546 if (success && work -> const_type && PRINT_ARG_TYPES)
547 {
548 string_append (declp, " const");
549 }
550 return (success);
551}
dd3b648e 552
f9b5584c 553#if 0
dd3b648e 554
f9b5584c
FF
555static int
556demangle_method_args (declp, mangled, work)
557 string *declp;
558 const char **mangled;
559 struct work_stuff *work;
560{
561 int success = 0;
562
563 if (work -> static_type)
4c53d9ca 564 {
f9b5584c
FF
565 string_append (declp, *mangled + 1);
566 *mangled += strlen (*mangled);
567 success = 1;
4c53d9ca 568 }
f9b5584c 569 else
dd3b648e 570 {
f9b5584c
FF
571 success = demangle_args (declp, mangled, work);
572 }
573 return (success);
574}
575
576#endif
577
578static int
579demangle_template (declp, mangled, work)
580 string *declp;
581 const char **mangled;
582 struct work_stuff *work;
583{
584 int i;
585 int n;
586 string tname;
587 string trawname;
588 int is_pointer;
589 int is_real;
590 int is_integral;
591 int r;
592 int need_comma = 0;
593 int success = 0;
594 int done;
595 const char *old_p;
596 int symbol_len;
597 string temp;
598
599 (*mangled)++;
600 string_init (&tname);
601 string_init (&trawname);
602 /* get template name */
603 if (!get_count (mangled, &r))
604 {
605 return (0);
606 }
607 string_appendn (&tname, *mangled, r);
608 string_appendn (&trawname, *mangled, r);
609 string_appendn (&trawname, "", 1);
610 *mangled += r;
611 string_append (&tname, "<");
612 /* get size of template parameter list */
613 if (!get_count (mangled, &r))
614 {
615 return (0);
616 }
617 for (i = 0; i < r; i++)
618 {
619 if (need_comma)
dd3b648e 620 {
f9b5584c
FF
621 string_append (&tname, ", ");
622 }
623 /* Z for type parameters */
624 if (**mangled == 'Z')
625 {
626 (*mangled)++;
627 success = do_type (mangled, &temp, work);
628 string_appendn (&temp, "", 1);
629 if (success)
572acbbe 630 {
f9b5584c
FF
631 string_append (&tname, temp.b);
632 }
633 string_delete(&temp);
634 if (!success)
635 {
636 break;
572acbbe 637 }
572acbbe
MT
638 }
639 else
640 {
f9b5584c
FF
641 /* otherwise, value parameter */
642 old_p = *mangled;
643 is_pointer = 0;
644 is_real = 0;
645 is_integral = 0;
646 done = 0;
647 success = do_type (mangled, &temp, work);
648 string_appendn (&temp, "", 1);
649 if (success)
650 {
651 string_append (&tname, temp.b);
652 }
653 string_delete(&temp);
654 if (!success)
655 {
656 break;
657 }
658 string_append (&tname, "=");
659 while (*old_p && !done)
660 {
661 switch (*old_p)
662 {
663 case 'P':
664 case 'R':
665 done = is_pointer = 1;
666 break;
667 case 'C': /* const */
668 case 'S': /* explicitly signed [char] */
669 case 'U': /* unsigned */
670 case 'V': /* volatile */
671 case 'F': /* function */
672 case 'M': /* member function */
673 case 'O': /* ??? */
674 old_p++;
675 continue;
676 case 'Q': /* repetition of following */
677 case 'T': /* remembered type */
678 abort ();
679 break;
680 case 'v': /* void */
681 abort ();
682 break;
683 case 'x': /* long long */
684 case 'l': /* long */
685 case 'i': /* int */
686 case 's': /* short */
687 case 'c': /* char */
688 done = is_integral = 1;
689 break;
690 case 'r': /* long double */
691 case 'd': /* double */
692 case 'f': /* float */
693 done = is_real = 1;
694 break;
695 default:
696 abort ();
697 }
698 }
699 if (is_integral)
700 {
701 if (**mangled == 'm')
702 {
703 string_appendn (&tname, "-", 1);
704 (*mangled)++;
705 }
706 while (isdigit (**mangled))
707 {
708 string_appendn (&tname, *mangled, 1);
709 (*mangled)++;
710 }
711 }
712 else if (is_real)
713 {
714 if (**mangled == 'm')
715 {
716 string_appendn (&tname, "-", 1);
717 (*mangled)++;
718 }
719 while (isdigit (**mangled))
720 {
721 string_appendn (&tname, *mangled, 1);
722 (*mangled)++;
723 }
724 if (**mangled == '.') /* fraction */
725 {
726 string_appendn (&tname, ".", 1);
727 (*mangled)++;
728 while (isdigit (**mangled))
729 {
730 string_appendn (&tname, *mangled, 1);
731 (*mangled)++;
732 }
733 }
734 if (**mangled == 'e') /* exponent */
735 {
736 string_appendn (&tname, "e", 1);
737 (*mangled)++;
738 while (isdigit (**mangled))
739 {
740 string_appendn (&tname, *mangled, 1);
741 (*mangled)++;
742 }
743 }
744 }
745 else if (is_pointer)
746 {
747 if (!get_count (mangled, &symbol_len))
748 {
749 success = 0;
750 break;
751 }
752 string_appendn (&tname, *mangled, symbol_len);
753 *mangled += symbol_len;
754 }
dd3b648e 755 }
f9b5584c
FF
756 need_comma = 1;
757 }
758 string_append (&tname, ">::");
759 if (work -> destructor)
760 {
761 string_append (&tname, "~");
762 }
763 if (work -> constructor || work -> destructor)
764 {
765 string_append (&tname, trawname.b);
766 }
767 string_delete(&trawname);
768
769 if (!success)
770 {
771 string_delete(&tname);
dd3b648e
RP
772 }
773 else
774 {
f9b5584c
FF
775 string_prepend (declp, tname.b);
776 string_delete (&tname);
777
778 if (work -> static_type)
779 {
780 string_append (declp, *mangled + 1);
781 *mangled += strlen (*mangled);
782 success = 1;
783 }
784 else
785 {
786 success = demangle_args (declp, mangled, work);
787 }
dd3b648e 788 }
f9b5584c 789}
dd3b648e 790
f9b5584c
FF
791/*
792
793LOCAL FUNCTION
794
795 demangle_class -- demangle a mangled class sequence
796
797SYNOPSIS
798
799 static int
800 demangle_class (string *declp, const char **mangled,
801 struct work_stuff *work)
802
803DESCRIPTION
804
805 DECLP points to the buffer into which demangling is being done.
806
807 *MANGLED points to the current token to be demangled. On input,
808 it points to a mangled class (I.E. "3foo", "13verylongclass", etc.)
809 On exit, it points to the next token after the mangled class on
810 success, or the first unconsumed token on failure.
811
812 If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then
813 we are demangling a constructor or destructor. In this case
814 we prepend "class::class" or "class::~class" to DECLP.
815
816 Otherwise, we prepend "class::" to the current DECLP.
817
818 Reset the constructor/destructor flags once they have been
819 "consumed". This allows demangle_class to be called later during
820 the same demangling, to do normal class demangling.
821
822 Returns 1 if demangling is successful, 0 otherwise.
823
824*/
825
826static int
827demangle_class (declp, mangled, work)
828 string *declp;
829 const char **mangled;
830 struct work_stuff *work;
831{
832 int n;
833 int success = 0;
834
1c92ca6f 835 n = consume_count (mangled);
f9b5584c
FF
836 if (strlen (*mangled) >= n)
837 {
838 if (work -> constructor || work -> destructor)
f536aa39 839 {
f9b5584c
FF
840 string_prependn (declp, *mangled, n);
841 if (work -> destructor)
f536aa39 842 {
f9b5584c 843 string_prepend (declp, "~");
f536aa39 844 }
f9b5584c 845 work -> constructor = work -> destructor = 0;
dd3b648e 846 }
f9b5584c
FF
847 string_prepend (declp, "::");
848 string_prependn (declp, *mangled, n);
849 *mangled += n;
850 success = 1;
851 }
852 return (success);
853}
854
855/*
856
857LOCAL FUNCTION
858
859 demangle_prefix -- consume the mangled name prefix and find signature
860
861SYNOPSIS
862
863 static int
864 demangle_prefix (string *declp, const char **mangled,
865 struct work_stuff *work)
866
867DESCRIPTION
868
869 Consume and demangle the prefix of the mangled name.
870
871 DECLP points to the string buffer into which demangled output is
872 placed. On entry, the buffer is empty. On exit it contains
873 the root function name, the demangled operator name, or in some
874 special cases either nothing or the completely demangled result.
875
876 MANGLED points to the current pointer into the mangled name. As each
877 token of the mangled name is consumed, it is updated. Upon entry
878 the current mangled name pointer points to the first character of
879 the mangled name. Upon exit, it should point to the first character
880 of the signature if demangling was successful, or to the first
881 unconsumed character if demangling of the prefix was unsuccessful.
882
883 Returns 1 on success, 0 otherwise.
884 */
885
886static int
887demangle_prefix (declp, mangled, work)
888 string *declp;
889 const char **mangled;
890 struct work_stuff *work;
891{
892 int success = 1;
893 const char *scan;
894
895 if ((scan = strstr (*mangled, "__")) == NULL)
896 {
897 success = gnu_special (declp, mangled, work);
898 }
899 else if (work -> static_type)
900 {
901 if (!isdigit (scan[0]) && (scan[0] != 't'))
dd3b648e 902 {
f9b5584c 903 success = 0;
dd3b648e 904 }
f9b5584c
FF
905 }
906 else if ((scan == *mangled) && (isdigit (scan[2]) || (scan[2] == 'Q')))
907 {
908 /* A GNU style constructor starts with "__<digit>" or "__Q". */
909 work -> constructor = 1;
910 *mangled = scan + 2;
911 }
912 else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't'))
913 {
914 /* Mangled name starts with "__". Skip over any leading '_' characters,
915 then find the next "__" that separates the prefix from the signature.
916 */
917 while (*scan == '_')
dd3b648e 918 {
f9b5584c 919 scan++;
dd3b648e 920 }
f9b5584c 921 if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0'))
dd3b648e 922 {
f9b5584c
FF
923 /* No separator (I.E. "__not_mangled"), or empty signature
924 (I.E. "__not_mangled_either__") */
925 success = 0;
dd3b648e
RP
926 }
927 else
928 {
f9b5584c 929 demangle_function_name (declp, mangled, work, scan);
4c53d9ca 930 }
f9b5584c
FF
931 }
932 else if (*(scan + 2) != '\0')
933 {
934 /* Mangled name does not start with "__" but does have one somewhere
935 in there with non empty stuff after it. Looks like a global
936 function name. */
937 demangle_function_name (declp, mangled, work, scan);
938 }
939 else
940 {
941 /* Doesn't look like a mangled name */
942 success = 0;
943 }
944 return (success);
945}
4c53d9ca 946
1c92ca6f
FF
947/*
948
949LOCAL FUNCTION
950
951 gnu_special -- special handling of gnu mangled strings
952
953SYNOPSIS
954
955 static int
956 gnu_special (string *declp, const char **mangled,
957 struct work_stuff *work)
958
959
960DESCRIPTION
961
962 Process some special GNU style mangling forms that don't fit
963 the normal pattern. For example:
964
965 _$_3foo (destructor for class foo)
966 _vt$foo (virtual table)
967 _3foo$varname (static data member)
968 */
969
f9b5584c
FF
970static int
971gnu_special (declp, mangled, work)
972 string *declp;
973 const char **mangled;
974 struct work_stuff *work;
975{
976 int n;
977 int success = 1;
978 const char *p;
979
980 if ((*mangled)[0] == '_'
981 && (*mangled)[1] == CPLUS_MARKER
982 && (*mangled)[2] == '_')
983 {
984 /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */
985 (*mangled) += 3;
986 work -> destructor = 1;
987 }
f9b5584c
FF
988 else if ((*mangled)[0] == '_'
989 && (*mangled)[1] == 'v'
990 && (*mangled)[2] == 't'
991 && (*mangled)[3] == CPLUS_MARKER)
dd3b648e 992 {
f9b5584c
FF
993 /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
994 and create the decl. Note that we consume the entire mangled
995 input string, which means that demangle_signature has no work
996 to do. */
997 (*mangled) += 4;
998 n = strlen (*mangled);
999 string_appendn (declp, *mangled, n);
1000 string_append (declp, " virtual table");
1001 (*mangled) += n;
dd3b648e 1002 }
1c92ca6f
FF
1003 else if ((*mangled)[0] == '_'
1004 && isdigit ((*mangled)[1])
1005 && (p = strchr (*mangled, CPLUS_MARKER)) != NULL)
1006 {
1007 /* static data member, "_3foo$varname" for example */
1008 (*mangled)++;
1009 p++;
1010 n = consume_count (mangled);
1011 string_appendn (declp, *mangled, n);
1012 string_append (declp, "::");
1013 n = strlen (p);
1014 string_appendn (declp, p, n);
1015 (*mangled) = p + n;
1016 }
dd3b648e
RP
1017 else
1018 {
f9b5584c
FF
1019 success = 0;
1020 }
1021 return (success);
1022}
1023
1024/* Do a qualified name, such as "Q25Outer5Inner" for "Outer::Inner" */
1025
1026static int
1027demangle_qualified (declp, mangled, work)
1028 string *declp;
1029 const char **mangled;
1030 struct work_stuff *work;
1031{
1032 int n;
1033 string class;
1034 string tmp;
1035 int success = 0;
1036
1037 n = (*mangled)[1] - '0';
1038 if (n >= 0 && n <= 9)
1039 {
1040 if ((*mangled)[2] == '_')
1041 {
1042 /* cfront style */
1043 (*mangled)++;
1044 }
1045 (*mangled) += 2;
1046 string_init (&class);
1047 while (n-- > 0)
1048 {
1049 success = do_type (mangled, &tmp, work);
1050 string_appends (&class, &tmp);
1051 string_append (&class, "::");
1052 if (n == 0 && (work -> constructor || work -> destructor))
1053 {
1054 if (work -> destructor)
1055 {
1056 string_append (&class, "~");
1057 }
1058 string_appends (&class, &tmp);
1059 }
1060 string_delete (&tmp);
1061 }
1062 work -> constructor = work -> destructor = 0;
1063 string_prependn (declp, class.b, class.p - class.b);
1064 string_delete (&class);
dd3b648e 1065 }
f9b5584c 1066 return (success);
dd3b648e
RP
1067}
1068
1c92ca6f
FF
1069/*
1070
1071LOCAL FUNCTION
1072
1073 get_count -- convert an ascii count to integer, consuming tokens
1074
1075SYNOPSIS
1076
1077 static int
1078 get_count (const char **type, int *count)
1079
1080DESCRIPTION
1081
1082 Return 0 if no conversion is performed, 1 if a string is converted.
1083*/
1084
dd3b648e
RP
1085static int
1086get_count (type, count)
1087 const char **type;
1088 int *count;
1089{
f9b5584c
FF
1090 const char *p;
1091 int n;
1092
dd3b648e 1093 if (!isdigit (**type))
f9b5584c
FF
1094 {
1095 return (0);
1096 }
1c92ca6f 1097 else
dd3b648e 1098 {
1c92ca6f
FF
1099 *count = **type - '0';
1100 (*type)++;
1101 if (isdigit (**type))
dd3b648e 1102 {
1c92ca6f
FF
1103 p = *type;
1104 n = *count;
1105 do
1106 {
1107 n *= 10;
1108 n += *p - '0';
1109 p++;
1110 }
1111 while (isdigit (*p));
1112 if (*p == '_')
1113 {
1114 *type = p + 1;
1115 *count = n;
1116 }
dd3b648e
RP
1117 }
1118 }
f9b5584c 1119 return (1);
dd3b648e
RP
1120}
1121
1122/* result will be initialised here; it will be freed on failure */
1123
1124static int
f536aa39 1125do_type (type, result, work)
dd3b648e
RP
1126 const char **type;
1127 string *result;
f536aa39 1128 struct work_stuff *work;
dd3b648e
RP
1129{
1130 int n;
1131 int done;
dd3b648e
RP
1132 int success;
1133 string decl;
1134 const char *remembered_type;
f9b5584c
FF
1135 int constp;
1136 int volatilep;
dd3b648e
RP
1137
1138 string_init (&decl);
1139 string_init (result);
1140
1141 done = 0;
1142 success = 1;
1143 while (success && !done)
1144 {
1145 int member;
1146 switch (**type)
1147 {
f9b5584c
FF
1148 /* A qualified name, such as "Outer::Inner". Note qualifier count
1149 is limited to a single digit (0-9 qualifiers). */
55838914
JK
1150 case 'Q':
1151 n = (*type)[1] - '0';
1152 if (n < 0 || n > 9)
f9b5584c
FF
1153 {
1154 success = 0;
1155 }
f536aa39 1156 if ((*type)[2] == '_') /* cfront style */
f9b5584c
FF
1157 {
1158 (*type)++;
1159 }
55838914
JK
1160 *type += 2;
1161 while (n-- > 0)
f9b5584c
FF
1162 {
1163 do_type (type, result, work);
1164 }
55838914
JK
1165 break;
1166
f9b5584c 1167 /* A pointer type */
dd3b648e 1168 case 'P':
f9b5584c 1169 (*type)++;
dd3b648e
RP
1170 string_prepend (&decl, "*");
1171 break;
1172
f9b5584c 1173 /* A reference type */
dd3b648e 1174 case 'R':
f9b5584c 1175 (*type)++;
dd3b648e
RP
1176 string_prepend (&decl, "&");
1177 break;
1178
f9b5584c 1179 /* A back reference to a previously seen type */
dd3b648e 1180 case 'T':
f9b5584c
FF
1181 (*type)++;
1182 if (!get_count (type, &n) || n >= work -> ntypes)
1183 {
1184 success = 0;
1185 }
dd3b648e
RP
1186 else
1187 {
f9b5584c 1188 remembered_type = work -> typevec[n];
dd3b648e
RP
1189 type = &remembered_type;
1190 }
1191 break;
1192
f9b5584c 1193 /* A function */
dd3b648e 1194 case 'F':
f9b5584c
FF
1195 (*type)++;
1196 if (!STRING_EMPTY (&decl) && decl.b[0] == '*')
dd3b648e
RP
1197 {
1198 string_prepend (&decl, "(");
1199 string_append (&decl, ")");
1200 }
8f793aa5 1201 /* After picking off the function args, we expect to either find the
f9b5584c
FF
1202 function return type (preceded by an '_') or the end of the
1203 string. */
1204 if (!demangle_args (&decl, type, work)
8f793aa5 1205 || (**type != '_' && **type != '\0'))
f9b5584c
FF
1206 {
1207 success = 0;
1208 }
8f793aa5 1209 if (success && (**type == '_'))
f9b5584c
FF
1210 {
1211 (*type)++;
1212 }
dd3b648e
RP
1213 break;
1214
1215 case 'M':
1216 case 'O':
1217 {
f9b5584c
FF
1218 constp = 0;
1219 volatilep = 0;
dd3b648e
RP
1220
1221 member = **type == 'M';
f9b5584c 1222 (*type)++;
dd3b648e
RP
1223 if (!isdigit (**type))
1224 {
1225 success = 0;
1226 break;
1227 }
1c92ca6f 1228 n = consume_count (type);
dd3b648e
RP
1229 if (strlen (*type) < n)
1230 {
1231 success = 0;
1232 break;
1233 }
1234 string_append (&decl, ")");
1235 string_prepend (&decl, "::");
1236 string_prependn (&decl, *type, n);
1237 string_prepend (&decl, "(");
1238 *type += n;
1239 if (member)
1240 {
1241 if (**type == 'C')
1242 {
f9b5584c 1243 (*type)++;
dd3b648e
RP
1244 constp = 1;
1245 }
1246 if (**type == 'V')
1247 {
f9b5584c 1248 (*type)++;
dd3b648e
RP
1249 volatilep = 1;
1250 }
1251 if (*(*type)++ != 'F')
1252 {
1253 success = 0;
1254 break;
1255 }
1256 }
f9b5584c
FF
1257 if ((member && !demangle_args (&decl, type, work))
1258 || **type != '_')
dd3b648e
RP
1259 {
1260 success = 0;
1261 break;
1262 }
f9b5584c 1263 (*type)++;
8f793aa5 1264 if (! PRINT_ANSI_QUALIFIERS)
f9b5584c
FF
1265 {
1266 break;
1267 }
dd3b648e
RP
1268 if (constp)
1269 {
f9b5584c 1270 APPEND_BLANK (&decl);
dd3b648e
RP
1271 string_append (&decl, "const");
1272 }
1273 if (volatilep)
1274 {
f9b5584c 1275 APPEND_BLANK (&decl);
dd3b648e
RP
1276 string_append (&decl, "volatile");
1277 }
1278 break;
1279 }
1280
1281 case 'C':
1282 if ((*type)[1] == 'P')
1283 {
f9b5584c 1284 (*type)++;
8f793aa5 1285 if (PRINT_ANSI_QUALIFIERS)
dd3b648e 1286 {
f9b5584c
FF
1287 if (!STRING_EMPTY (&decl))
1288 {
1289 string_prepend (&decl, " ");
1290 }
dd3b648e
RP
1291 string_prepend (&decl, "const");
1292 }
1293 break;
1294 }
1295
1296 /* fall through */
1297 default:
1298 done = 1;
1299 break;
1300 }
1301 }
1302
f9b5584c
FF
1303 success = demangle_fund_type (type, result, work);
1304
1305 if (success)
1306 {
1307 if (!STRING_EMPTY (&decl))
1308 {
1309 string_append (result, " ");
1310 string_appends (result, &decl);
1311 }
1312 }
1313 else
1314 {
1315 string_delete (result);
1316 }
1317 string_delete (&decl);
1318 return (success);
1319}
1320
1321/* Given a pointer to a type string that represents a fundamental type
1322 argument (int, long, unsigned int, etc) in TYPE, a pointer to the
1323 string in which the demangled output is being built in RESULT, and
1324 the WORK structure, decode the types and add them to the result.
1325
1326 For example:
1327
1328 "Ci" => "const int"
1329 "Sl" => "signed long"
1330 "CUs" => "const unsigned short"
1331
1332 */
1333
1334static int
1335demangle_fund_type (type, result, work)
1336 const char **type;
1337 string *result;
1338 struct work_stuff *work;
1339{
1340 int done = 0;
1341 int success = 1;
1342 int n;
1343
1344 /* First pick off any type qualifiers. There can be more than one. */
1345
1346 while (!done)
dd3b648e
RP
1347 {
1348 switch (**type)
1349 {
f9b5584c
FF
1350 case 'C':
1351 (*type)++;
1352 if (PRINT_ANSI_QUALIFIERS)
1353 {
1354 APPEND_BLANK (result);
1355 string_append (result, "const");
1356 }
1357 break;
1358 case 'U':
1359 (*type)++;
1360 APPEND_BLANK (result);
1361 string_append (result, "unsigned");
1362 break;
1363 case 'S': /* signed char only */
1364 (*type)++;
1365 APPEND_BLANK (result);
1366 string_append (result, "signed");
1367 break;
1368 case 'V':
1369 (*type)++;
1370 if (PRINT_ANSI_QUALIFIERS)
1371 {
1372 APPEND_BLANK (result);
1373 string_append (result, "volatile");
1374 }
1375 break;
1376 default:
1377 done = 1;
1378 break;
dd3b648e
RP
1379 }
1380 }
1381
f9b5584c
FF
1382 /* Now pick off the fundamental type. There can be only one. */
1383
1384 switch (**type)
1385 {
dd3b648e
RP
1386 case '\0':
1387 case '_':
1388 break;
1389 case 'v':
f9b5584c
FF
1390 (*type)++;
1391 APPEND_BLANK (result);
dd3b648e
RP
1392 string_append (result, "void");
1393 break;
1394 case 'x':
f9b5584c
FF
1395 (*type)++;
1396 APPEND_BLANK (result);
dd3b648e
RP
1397 string_append (result, "long long");
1398 break;
1399 case 'l':
f9b5584c
FF
1400 (*type)++;
1401 APPEND_BLANK (result);
dd3b648e
RP
1402 string_append (result, "long");
1403 break;
1404 case 'i':
f9b5584c
FF
1405 (*type)++;
1406 APPEND_BLANK (result);
dd3b648e
RP
1407 string_append (result, "int");
1408 break;
1409 case 's':
f9b5584c
FF
1410 (*type)++;
1411 APPEND_BLANK (result);
dd3b648e
RP
1412 string_append (result, "short");
1413 break;
1414 case 'c':
f9b5584c
FF
1415 (*type)++;
1416 APPEND_BLANK (result);
dd3b648e
RP
1417 string_append (result, "char");
1418 break;
1419 case 'r':
f9b5584c
FF
1420 (*type)++;
1421 APPEND_BLANK (result);
dd3b648e
RP
1422 string_append (result, "long double");
1423 break;
1424 case 'd':
f9b5584c
FF
1425 (*type)++;
1426 APPEND_BLANK (result);
dd3b648e
RP
1427 string_append (result, "double");
1428 break;
1429 case 'f':
f9b5584c
FF
1430 (*type)++;
1431 APPEND_BLANK (result);
dd3b648e
RP
1432 string_append (result, "float");
1433 break;
1434 case 'G':
f9b5584c 1435 (*type)++;
dd3b648e
RP
1436 if (!isdigit (**type))
1437 {
1438 success = 0;
1439 break;
1440 }
1441 /* fall through */
f9b5584c 1442 /* An explicit type, such as "6mytype" or "7integer" */
dd3b648e
RP
1443 case '0':
1444 case '1':
1445 case '2':
1446 case '3':
1447 case '4':
1448 case '5':
1449 case '6':
1450 case '7':
1451 case '8':
1452 case '9':
1c92ca6f 1453 n = consume_count (type);
dd3b648e
RP
1454 if (strlen (*type) < n)
1455 {
1456 success = 0;
1457 break;
1458 }
f9b5584c 1459 APPEND_BLANK (result);
dd3b648e
RP
1460 string_appendn (result, *type, n);
1461 *type += n;
1462 break;
1463 default:
1464 success = 0;
1465 break;
1466 }
1467
f9b5584c 1468 return (success);
dd3b648e
RP
1469}
1470
f9b5584c 1471/* `result' will be initialized in do_type; it will be freed on failure */
dd3b648e
RP
1472
1473static int
f536aa39 1474do_arg (type, result, work)
dd3b648e
RP
1475 const char **type;
1476 string *result;
f536aa39 1477 struct work_stuff *work;
dd3b648e
RP
1478{
1479 const char *start = *type;
1480
f536aa39 1481 if (!do_type (type, result, work))
f9b5584c
FF
1482 {
1483 return (0);
1484 }
1485 else
1486 {
1487 remember_type (start, *type - start, work);
1488 return (1);
1489 }
dd3b648e
RP
1490}
1491
1492static void
f536aa39 1493remember_type (start, len, work)
dd3b648e
RP
1494 const char *start;
1495 int len;
f536aa39 1496 struct work_stuff *work;
dd3b648e
RP
1497{
1498 char *tem;
1499
f9b5584c 1500 if (work -> ntypes >= work -> typevec_size)
dd3b648e 1501 {
f9b5584c 1502 if (work -> typevec_size == 0)
dd3b648e 1503 {
f9b5584c
FF
1504 work -> typevec_size = 3;
1505 work -> typevec =
1506 (char **) xmalloc (sizeof (char *) * work -> typevec_size);
dd3b648e
RP
1507 }
1508 else
1509 {
f9b5584c
FF
1510 work -> typevec_size *= 2;
1511 work -> typevec =
1512 (char **) xrealloc ((char *)work -> typevec,
1513 sizeof (char *) * work -> typevec_size);
dd3b648e
RP
1514 }
1515 }
1516 tem = (char *) xmalloc (len + 1);
1517 memcpy (tem, start, len);
1518 tem[len] = '\0';
f9b5584c 1519 work -> typevec[work -> ntypes++] = tem;
dd3b648e
RP
1520}
1521
f9b5584c
FF
1522/* Process the argument list part of the signature, after any class spec
1523 has been consumed, as well as the first 'F' character (if any). For
1524 example:
1525
1526 "__als__3fooRT0" => process "RT0"
1527 "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i"
1528
1529 DECLP must be already initialised, usually non-empty. It won't be freed
1530 on failure */
dd3b648e
RP
1531
1532static int
f9b5584c
FF
1533demangle_args (declp, type, work)
1534 string *declp;
dd3b648e 1535 const char **type;
f536aa39 1536 struct work_stuff *work;
dd3b648e
RP
1537{
1538 string arg;
1539 int need_comma = 0;
f9b5584c
FF
1540 int r;
1541 int t;
1542 const char *tem;
1543 char temptype;
dd3b648e 1544
8f793aa5 1545 if (PRINT_ARG_TYPES)
f9b5584c
FF
1546 {
1547 string_append (declp, "(");
1548 if (**type == '\0')
1549 {
1550 string_append (declp, "void");
1551 }
1552 }
dd3b648e 1553
55b3ef9a 1554 while (**type != '_' && **type != '\0' && **type != 'e')
dd3b648e 1555 {
f9b5584c 1556 if ((**type == 'N') || (**type == 'T'))
dd3b648e 1557 {
f9b5584c
FF
1558 temptype = *(*type)++;
1559
1560 if (temptype == 'N')
1561 {
1562 if (!get_count (type, &r))
1563 {
1564 return (0);
1565 }
1566 }
1567 else
1568 {
1569 r = 1;
1570 }
1571 if (!get_count (type, &t))
1572 {
1573 return (0);
1574 }
1575#ifdef ARM_DEMANGLING
1576 t--;
1577#endif
1578 if (t >= work -> ntypes)
1579 {
1580 return (0);
1581 }
dd3b648e
RP
1582 while (--r >= 0)
1583 {
f9b5584c 1584 tem = work -> typevec[t];
8f793aa5 1585 if (need_comma && PRINT_ARG_TYPES)
f9b5584c
FF
1586 {
1587 string_append (declp, ", ");
1588 }
f536aa39 1589 if (!do_arg (&tem, &arg, work))
f9b5584c
FF
1590 {
1591 return (0);
1592 }
8f793aa5 1593 if (PRINT_ARG_TYPES)
f9b5584c
FF
1594 {
1595 string_appends (declp, &arg);
1596 }
dd3b648e
RP
1597 string_delete (&arg);
1598 need_comma = 1;
1599 }
1600 }
1601 else
1602 {
8f793aa5 1603 if (need_comma & PRINT_ARG_TYPES)
f9b5584c
FF
1604 {
1605 string_append (declp, ", ");
1606 }
f536aa39 1607 if (!do_arg (type, &arg, work))
f9b5584c
FF
1608 {
1609 return (0);
1610 }
8f793aa5 1611 if (PRINT_ARG_TYPES)
f9b5584c
FF
1612 {
1613 string_appends (declp, &arg);
1614 }
dd3b648e
RP
1615 string_delete (&arg);
1616 need_comma = 1;
1617 }
1618 }
1619
55b3ef9a 1620 if (**type == 'e')
dd3b648e 1621 {
f9b5584c 1622 (*type)++;
8f793aa5 1623 if (PRINT_ARG_TYPES)
dd3b648e
RP
1624 {
1625 if (need_comma)
f9b5584c
FF
1626 {
1627 string_append (declp, ",");
1628 }
1629 string_append (declp, "...");
dd3b648e
RP
1630 }
1631 }
1632
8f793aa5 1633 if (PRINT_ARG_TYPES)
f9b5584c
FF
1634 {
1635 string_append (declp, ")");
1636 }
1637 return (1);
dd3b648e
RP
1638}
1639
1640static void
f9b5584c
FF
1641demangle_function_name (declp, mangled, work, scan)
1642 string *declp;
1643 const char **mangled;
f536aa39 1644 struct work_stuff *work;
f9b5584c 1645 const char *scan;
dd3b648e 1646{
f9b5584c
FF
1647 int i;
1648 int len;
1649 string type;
1650 const char *tem;
1651
1652 string_appendn (declp, (*mangled), scan - (*mangled));
1653 string_need (declp, 1);
1654 *(declp -> p) = '\0';
1655
1656 /* Consume the function name, including the "__" separating the name
1657 from the signature. We are guaranteed that SCAN points to the
1658 separator. */
1659
1660 (*mangled) = scan + 2;
1661
1662#ifdef ARM_DEMANGLING
1663
1664 /* See if we have an ARM style constructor or destructor operator.
1665 If so, then just record it, clear the decl, and return.
1666 We can't build the actual constructor/destructor decl until later,
1667 when we recover the class name from the signature. */
1668
1669 if (strcmp (declp -> b, "__ct") == 0)
1670 {
1671 work -> constructor = 1;
1672 string_clear (declp);
1673 return;
1674 }
1675 else if (strcmp (declp -> b, "__dt") == 0)
1676 {
1677 work -> destructor = 1;
1678 string_clear (declp);
1679 return;
1680 }
1681
1682#endif
572acbbe 1683
f9b5584c
FF
1684 if (declp->p - declp->b >= 3
1685 && declp->b[0] == 'o'
1686 && declp->b[1] == 'p'
1687 && declp->b[2] == CPLUS_MARKER)
dd3b648e 1688 {
dd3b648e 1689 /* see if it's an assignment expression */
f9b5584c
FF
1690 if (declp->p - declp->b >= 10 /* op$assign_ */
1691 && memcmp (declp->b + 3, "assign_", 7) == 0)
dd3b648e 1692 {
f9b5584c 1693 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
dd3b648e 1694 {
f9b5584c 1695 len = declp->p - declp->b - 10;
dd3b648e 1696 if (strlen (optable[i].in) == len
f9b5584c 1697 && memcmp (optable[i].in, declp->b + 10, len) == 0)
dd3b648e 1698 {
f9b5584c
FF
1699 string_clear (declp);
1700 string_append (declp, "operator");
1701 string_append (declp, optable[i].out);
1702 string_append (declp, "=");
1703 break;
dd3b648e
RP
1704 }
1705 }
1706 }
1707 else
1708 {
f9b5584c 1709 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
dd3b648e 1710 {
f9b5584c 1711 int len = declp->p - declp->b - 3;
dd3b648e 1712 if (strlen (optable[i].in) == len
f9b5584c 1713 && memcmp (optable[i].in, declp->b + 3, len) == 0)
dd3b648e 1714 {
f9b5584c
FF
1715 string_clear (declp);
1716 string_append (declp, "operator");
1717 string_append (declp, optable[i].out);
1718 break;
dd3b648e
RP
1719 }
1720 }
1721 }
dd3b648e 1722 }
f9b5584c 1723 else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type$", 5) == 0)
dd3b648e
RP
1724 {
1725 /* type conversion operator */
f9b5584c 1726 tem = declp->b + 5;
f536aa39 1727 if (do_type (&tem, &type, work))
dd3b648e 1728 {
f9b5584c
FF
1729 string_clear (declp);
1730 string_append (declp, "operator ");
1731 string_appends (declp, &type);
dd3b648e 1732 string_delete (&type);
dd3b648e
RP
1733 }
1734 }
f9b5584c 1735 else if (declp->b[2] == 'o' && declp->b[3] == 'p')
572acbbe 1736 {
f9b5584c 1737 /* ANSI. */
572acbbe 1738 /* type conversion operator. */
f9b5584c 1739 tem = declp->b + 4;
f536aa39 1740 if (do_type (&tem, &type, work))
572acbbe 1741 {
f9b5584c
FF
1742 string_clear (declp);
1743 string_append (declp, "operator ");
1744 string_appends (declp, &type);
572acbbe 1745 string_delete (&type);
572acbbe
MT
1746 }
1747 }
f9b5584c
FF
1748 else if (declp->b[0] == '_' && declp->b[1] == '_'
1749 && declp->b[2] >= 'a' && declp->b[2] <= 'z'
1750 && declp->b[3] >= 'a' && declp->b[3] <= 'z')
572acbbe 1751 {
f9b5584c 1752 if (declp->b[4] == '\0')
572acbbe
MT
1753 {
1754 /* Operator. */
f9b5584c 1755 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
572acbbe
MT
1756 {
1757 if (strlen (optable[i].in) == 2
f9b5584c 1758 && memcmp (optable[i].in, declp->b + 2, 2) == 0)
572acbbe 1759 {
f9b5584c
FF
1760 string_clear (declp);
1761 string_append (declp, "operator");
1762 string_append (declp, optable[i].out);
1763 break;
572acbbe
MT
1764 }
1765 }
1766 }
1767 else
1768 {
f9b5584c 1769 if (declp->b[2] == 'a' && declp->b[5] == '\0')
572acbbe 1770 {
f9b5584c
FF
1771 /* Assignment. */
1772 for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++)
572acbbe 1773 {
f9b5584c
FF
1774 if (strlen (optable[i].in) == 3
1775 && memcmp (optable[i].in, declp->b + 2, 3) == 0)
1776 {
1777 string_clear (declp);
1778 string_append (declp, "operator");
1779 string_append (declp, optable[i].out);
1780 break;
1781 }
572acbbe
MT
1782 }
1783 }
1784 }
1785 }
dd3b648e
RP
1786}
1787
1788/* a mini string-handling package */
1789
1790static void
1791string_need (s, n)
1792 string *s;
1793 int n;
1794{
f9b5584c
FF
1795 int tem;
1796
dd3b648e
RP
1797 if (s->b == NULL)
1798 {
1799 if (n < 32)
f9b5584c
FF
1800 {
1801 n = 32;
1802 }
dd3b648e
RP
1803 s->p = s->b = (char *) xmalloc (n);
1804 s->e = s->b + n;
1805 }
1806 else if (s->e - s->p < n)
1807 {
f9b5584c 1808 tem = s->p - s->b;
dd3b648e
RP
1809 n += tem;
1810 n *= 2;
1811 s->b = (char *) xrealloc (s->b, n);
1812 s->p = s->b + tem;
1813 s->e = s->b + n;
1814 }
1815}
1816
1817static void
1818string_delete (s)
1819 string *s;
1820{
1821 if (s->b != NULL)
1822 {
1823 free (s->b);
1824 s->b = s->e = s->p = NULL;
1825 }
1826}
1827
1828static void
1829string_init (s)
1830 string *s;
1831{
1832 s->b = s->p = s->e = NULL;
1833}
1834
1835static void
1836string_clear (s)
1837 string *s;
1838{
1839 s->p = s->b;
1840}
1841
1842static int
1843string_empty (s)
1844 string *s;
1845{
f9b5584c 1846 return (s->b == s->p);
dd3b648e
RP
1847}
1848
1849static void
1850string_append (p, s)
1851 string *p;
1852 const char *s;
1853{
1854 int n;
1855 if (s == NULL || *s == '\0')
1856 return;
1857 n = strlen (s);
1858 string_need (p, n);
1859 memcpy (p->p, s, n);
1860 p->p += n;
1861}
1862
1863static void
1864string_appends (p, s)
1865 string *p, *s;
1866{
1867 int n;
f9b5584c
FF
1868
1869 if (s->b != s->p)
1870 {
1871 n = s->p - s->b;
1872 string_need (p, n);
1873 memcpy (p->p, s->b, n);
1874 p->p += n;
1875 }
dd3b648e
RP
1876}
1877
1878static void
1879string_appendn (p, s, n)
1880 string *p;
1881 const char *s;
1882 int n;
1883{
f9b5584c
FF
1884 if (n != 0)
1885 {
1886 string_need (p, n);
1887 memcpy (p->p, s, n);
1888 p->p += n;
1889 }
dd3b648e
RP
1890}
1891
1892static void
1893string_prepend (p, s)
1894 string *p;
1895 const char *s;
1896{
f9b5584c
FF
1897 if (s != NULL && *s != '\0')
1898 {
1899 string_prependn (p, s, strlen (s));
1900 }
dd3b648e
RP
1901}
1902
1903#if 0
1904static void
1905string_prepends (p, s)
1906 string *p, *s;
1907{
f9b5584c
FF
1908 if (s->b != s->p)
1909 {
1910 string_prependn (p, s->b, s->p - s->b);
1911 }
dd3b648e
RP
1912}
1913#endif
1914
1915static void
1916string_prependn (p, s, n)
1917 string *p;
1918 const char *s;
1919 int n;
1920{
1921 char *q;
1922
f9b5584c
FF
1923 if (n != 0)
1924 {
1925 string_need (p, n);
1926 for (q = p->p - 1; q >= p->b; q--)
1927 {
1928 q[n] = q[0];
1929 }
1930 memcpy (p->b, s, n);
1931 p->p += n;
1932 }
1933}
1934
1935/* To generate a standalone demangler program for testing purposes, just
1936 compile and link this file with -DMAIN. When run, it demangles each
1937 command line arg, or each stdin string, and prints the result on stdout. */
1938
1939#ifdef MAIN
1940
1941static void
1942demangle_it (mangled_name)
1943 char *mangled_name;
1944{
1945 char *result;
1946
1947 result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI);
1948 if (result == NULL)
1949 {
1950 printf ("%s\n", mangled_name);
1951 }
1952 else
1953 {
1954 printf ("%s\n", result);
1955 free (result);
1956 }
1957}
1958
1959PTR
1960xmalloc (size)
1961 long size;
1962{
1963 PTR newmem;
1964
1965 if ((newmem = malloc ((int) size)) == NULL)
1966 {
1967 fprintf (stderr, "\nCan't allocate %u bytes\n", size);
1968 exit (1);
1969 }
1970 return (newmem);
1971}
1972
1973PTR
1974xrealloc (oldmem, size)
1975 PTR oldmem;
1976 long size;
1977{
1978 PTR newmem;
1979
1980 if ((newmem = realloc ((char *) oldmem, (int) size)) == NULL)
1981 {
1982 fprintf (stderr, "\nCan't reallocate %u bytes\n", size);
1983 exit (1);
1984 }
1985 return (newmem);
1986}
1987
1988main (argc, argv)
1989 int argc;
1990 char **argv;
1991{
1992 char mangled_name[128];
1993 char *result;
1994
1995 if (argc > 1)
1996 {
1997 argc--;
1998 argv++;
1999 while (argc-- > 0)
2000 {
2001 demangle_it (*argv);
2002 }
2003 }
2004 else
2005 {
2006 while (gets (mangled_name))
2007 {
2008 demangle_it (mangled_name);
2009 }
2010 }
dd3b648e 2011}
f9b5584c
FF
2012
2013#endif
This page took 0.148316 seconds and 4 git commands to generate.