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