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