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