Johns release
[deliverable/binutils-gdb.git] / gdb / cplus-dem.c
1 /* Demangler for GNU C++
2 Copyright (C) 1989 Free Software Foundation, Inc.
3 written by James Clark (jjc@jclark.uucp)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 /* This is for g++ 1.36.1 (November 6 version). It will probably
20 require changes for any other version.
21
22 Modified for g++ 1.36.2 (November 18 version). */
23
24 /* This file exports one function
25
26 char *cplus_demangle (const char *name, int mode)
27
28 If NAME is a mangled function name produced by GNU C++, then
29 a pointer to a malloced string giving a C++ representation
30 of the name will be returned; otherwise NULL will be returned.
31 It is the caller's responsibility to free the string which
32 is returned.
33
34 If MODE > 0, then ANSI qualifiers such as `const' and `void' are output.
35 Otherwise they are not.
36 If MODE >= 0, parameters are emitted; otherwise not.
37
38 For example,
39
40 cplus_demangle ("foo__1Ai", 0) => "A::foo(int)"
41 cplus_demangle ("foo__1Ai", 1) => "A::foo(int)"
42 cplus_demangle ("foo__1Ai", -1) => "A::foo"
43
44 cplus_demangle ("foo__1Afe", 0) => "A::foo(float,...)"
45 cplus_demangle ("foo__1Afe", 1) => "A::foo(float,...)"
46 cplus_demangle ("foo__1Afe", -1) => "A::foo"
47
48 This file imports xmalloc and xrealloc, which are like malloc and
49 realloc except that they generate a fatal error if there is no
50 available memory. */
51
52 /* define this if names don't start with _ */
53 /* #define nounderscore 1 */
54
55 #include <stdio.h>
56 #include <ctype.h>
57
58 #ifdef USG
59 #include <memory.h>
60 #include <string.h>
61 #else
62 #include <strings.h>
63 #define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))
64 #define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))
65 #define strchr index
66 #define strrchr rindex
67 #endif
68
69 #ifndef __STDC__
70 #define const
71 #endif
72
73 #ifdef __STDC__
74 extern char *cplus_demangle (const char *type, int mode);
75 #else
76 extern char *cplus_demangle ();
77 #endif
78
79 #ifdef __STDC__
80 extern char *xmalloc (int);
81 extern char *xrealloc (char *, int);
82 extern void free (char *);
83 #else
84 extern char *xmalloc ();
85 extern char *xrealloc ();
86 extern void free ();
87 #endif
88
89 static char **typevec = 0;
90 static int ntypes = 0;
91 static int typevec_size = 0;
92
93 static struct {
94 const char *in;
95 const char *out;
96 } optable[] = {
97 "new", " new",
98 "delete", " delete",
99 "ne", "!=",
100 "eq", "==",
101 "ge", ">=",
102 "gt", ">",
103 "le", "<=",
104 "lt", "<",
105 "plus", "+",
106 "minus", "-",
107 "mult", "*",
108 "convert", "+", /* unary + */
109 "negate", "-", /* unary - */
110 "trunc_mod", "%",
111 "trunc_div", "/",
112 "truth_andif", "&&",
113 "truth_orif", "||",
114 "truth_not", "!",
115 "postincrement", "++",
116 "postdecrement", "--",
117 "bit_ior", "|",
118 "bit_xor", "^",
119 "bit_and", "&",
120 "bit_not", "~",
121 "call", "()",
122 "cond", "?:",
123 "alshift", "<<",
124 "arshift", ">>",
125 "component", "->",
126 "indirect", "*",
127 "method_call", "->()",
128 "addr", "&", /* unary & */
129 "array", "[]",
130 "nop", "", /* for operator= */
131 };
132
133 /* Beware: these aren't '\0' terminated. */
134
135 typedef struct {
136 char *b; /* pointer to start of string */
137 char *p; /* pointer after last character */
138 char *e; /* pointer after end of allocated space */
139 } string;
140
141 #ifdef __STDC__
142 static void string_need (string *s, int n);
143 static void string_delete (string *s);
144 static void string_init (string *s);
145 static void string_clear (string *s);
146 static int string_empty (string *s);
147 static void string_append (string *p, const char *s);
148 static void string_appends (string *p, string *s);
149 static void string_appendn (string *p, const char *s, int n);
150 static void string_prepend (string *p, const char *s);
151 #if 0
152 static void string_prepends (string *p, string *s);
153 #endif
154 static void string_prependn (string *p, const char *s, int n);
155 static int get_count (const char **type, int *count);
156 static int do_args (const char **type, string *decl, int arg_mode);
157 static int do_type (const char **type, string *result, int arg_mode);
158 static int do_arg (const char **type, string *result, int arg_mode);
159 static void munge_function_name (string *name, int arg_mode);
160 static void remember_type (const char *type, int len);
161 #else
162 static void string_need ();
163 static void string_delete ();
164 static void string_init ();
165 static void string_clear ();
166 static int string_empty ();
167 static void string_append ();
168 static void string_appends ();
169 static void string_appendn ();
170 static void string_prepend ();
171 #if 0
172 static void string_prepends ();
173 #endif
174 static void string_prependn ();
175 static int get_count ();
176 static int do_args ();
177 static int do_type ();
178 static int do_arg ();
179 static int do_args ();
180 static void munge_function_name ();
181 static void remember_type ();
182 #endif
183
184 char *
185 cplus_demangle (type, arg_mode)
186 const char *type;
187 int arg_mode;
188 {
189 string decl;
190 int n;
191 int success = 0;
192 int constructor = 0;
193 int const_flag = 0;
194 int i;
195 const char *p;
196 #ifndef LONGERNAMES
197 const char *premangle;
198 #endif
199
200 # define print_ansi_qualifiers (arg_mode > 0)
201 # define print_arg_types (arg_mode >= 0)
202
203 if (type == NULL || *type == '\0')
204 return NULL;
205 #ifndef nounderscore
206 if (*type++ != '_')
207 return NULL;
208 #endif
209 p = type;
210 while (*p != '\0' && !(*p == '_' && p[1] == '_'))
211 p++;
212 if (*p == '\0')
213 {
214 /* destructor */
215 if (type[0] == '_' && type[1] == '$' && type[2] == '_')
216 {
217 int n = (strlen (type) - 3)*2 + 3 + 2 + 1;
218 char *tem = (char *) xmalloc (n);
219 strcpy (tem, type + 3);
220 strcat (tem, "::~");
221 strcat (tem, type + 3);
222 strcat (tem, "()");
223 return tem;
224 }
225 /* static data member */
226 if (*type != '_' && (p = strchr (type, '$')) != NULL)
227 {
228 int n = strlen (type) + 2;
229 char *tem = (char *) xmalloc (n);
230 memcpy (tem, type, p - type);
231 strcpy (tem + (p - type), "::");
232 strcpy (tem + (p - type) + 2, p + 1);
233 return tem;
234 }
235 /* virtual table "_vt$" */
236 if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == '$')
237 {
238 int n = strlen (type + 4) + 14 + 1;
239 char *tem = (char *) xmalloc (n);
240 strcpy (tem, type + 4);
241 strcat (tem, " virtual table");
242 return tem;
243 }
244 return NULL;
245 }
246
247 string_init (&decl);
248
249 if (p == type)
250 {
251 if (!isdigit (p[2]))
252 {
253 string_delete (&decl);
254 return NULL;
255 }
256 constructor = 1;
257 }
258 else
259 {
260 string_appendn (&decl, type, p - type);
261 munge_function_name (&decl, arg_mode);
262 }
263 p += 2;
264
265 #ifndef LONGERNAMES
266 premangle = p;
267 #endif
268 switch (*p)
269 {
270 case 'C':
271 /* a const member function */
272 if (!isdigit (p[1]))
273 {
274 string_delete (&decl);
275 return NULL;
276 }
277 p += 1;
278 const_flag = 1;
279 /* fall through */
280 case '0':
281 case '1':
282 case '2':
283 case '3':
284 case '4':
285 case '5':
286 case '6':
287 case '7':
288 case '8':
289 case '9':
290 n = 0;
291 do
292 {
293 n *= 10;
294 n += *p - '0';
295 p += 1;
296 }
297 while (isdigit (*p));
298 if (strlen (p) < n)
299 {
300 string_delete (&decl);
301 return NULL;
302 }
303 if (constructor)
304 {
305 string_appendn (&decl, p, n);
306 string_append (&decl, "::");
307 string_appendn (&decl, p, n);
308 }
309 else
310 {
311 string_prepend (&decl, "::");
312 string_prependn (&decl, p, n);
313 }
314 p += n;
315 #ifndef LONGERNAMES
316 remember_type (premangle, p - premangle);
317 #endif
318 success = do_args (&p, &decl, arg_mode);
319 if (const_flag && print_arg_types)
320 string_append (&decl, " const");
321 break;
322 case 'F':
323 p += 1;
324 success = do_args (&p, &decl, arg_mode);
325 break;
326 }
327
328 for (i = 0; i < ntypes; i++)
329 if (typevec[i] != NULL)
330 free (typevec[i]);
331 ntypes = 0;
332 if (typevec != NULL)
333 {
334 free ((char *)typevec);
335 typevec = NULL;
336 typevec_size = 0;
337 }
338
339 if (success)
340 {
341 string_appendn (&decl, "", 1);
342 return decl.b;
343 }
344 else
345 {
346 string_delete (&decl);
347 return NULL;
348 }
349 }
350
351 static int
352 get_count (type, count)
353 const char **type;
354 int *count;
355 {
356 if (!isdigit (**type))
357 return 0;
358 *count = **type - '0';
359 *type += 1;
360 /* see flush_repeats in cplus-method.c */
361 if (isdigit (**type))
362 {
363 const char *p = *type;
364 int n = *count;
365 do
366 {
367 n *= 10;
368 n += *p - '0';
369 p += 1;
370 }
371 while (isdigit (*p));
372 if (*p == '_')
373 {
374 *type = p + 1;
375 *count = n;
376 }
377 }
378 return 1;
379 }
380
381 /* result will be initialised here; it will be freed on failure */
382
383 static int
384 do_type (type, result, arg_mode)
385 const char **type;
386 string *result;
387 int arg_mode;
388 {
389 int n;
390 int done;
391 int non_empty = 0;
392 int success;
393 string decl;
394 const char *remembered_type;
395
396 string_init (&decl);
397 string_init (result);
398
399 done = 0;
400 success = 1;
401 while (success && !done)
402 {
403 int member;
404 switch (**type)
405 {
406 case 'P':
407 *type += 1;
408 string_prepend (&decl, "*");
409 break;
410
411 case 'R':
412 *type += 1;
413 string_prepend (&decl, "&");
414 break;
415
416 case 'T':
417 *type += 1;
418 if (!get_count (type, &n) || n >= ntypes)
419 success = 0;
420 else
421 {
422 remembered_type = typevec[n];
423 type = &remembered_type;
424 }
425 break;
426
427 case 'F':
428 *type += 1;
429 if (!string_empty (&decl) && decl.b[0] == '*')
430 {
431 string_prepend (&decl, "(");
432 string_append (&decl, ")");
433 }
434 if (!do_args (type, &decl, arg_mode) || **type != '_')
435 success = 0;
436 else
437 *type += 1;
438 break;
439
440 case 'M':
441 case 'O':
442 {
443 int constp = 0;
444 int volatilep = 0;
445
446 member = **type == 'M';
447 *type += 1;
448 if (!isdigit (**type))
449 {
450 success = 0;
451 break;
452 }
453 n = 0;
454 do
455 {
456 n *= 10;
457 n += **type - '0';
458 *type += 1;
459 }
460 while (isdigit (**type));
461 if (strlen (*type) < n)
462 {
463 success = 0;
464 break;
465 }
466 string_append (&decl, ")");
467 string_prepend (&decl, "::");
468 string_prependn (&decl, *type, n);
469 string_prepend (&decl, "(");
470 *type += n;
471 if (member)
472 {
473 if (**type == 'C')
474 {
475 *type += 1;
476 constp = 1;
477 }
478 if (**type == 'V')
479 {
480 *type += 1;
481 volatilep = 1;
482 }
483 if (*(*type)++ != 'F')
484 {
485 success = 0;
486 break;
487 }
488 }
489 if ((member && !do_args (type, &decl, arg_mode)) || **type != '_')
490 {
491 success = 0;
492 break;
493 }
494 *type += 1;
495 if (! print_ansi_qualifiers)
496 break;
497 if (constp)
498 {
499 if (non_empty)
500 string_append (&decl, " ");
501 else
502 non_empty = 1;
503 string_append (&decl, "const");
504 }
505 if (volatilep)
506 {
507 if (non_empty)
508 string_append (&decl, " ");
509 else
510 non_empty = 1;
511 string_append (&decl, "volatile");
512 }
513 break;
514 }
515
516 case 'C':
517 if ((*type)[1] == 'P')
518 {
519 *type += 1;
520 if (print_ansi_qualifiers)
521 {
522 if (!string_empty (&decl))
523 string_prepend (&decl, " ");
524 string_prepend (&decl, "const");
525 }
526 break;
527 }
528
529 /* fall through */
530 default:
531 done = 1;
532 break;
533 }
534 }
535
536 done = 0;
537 non_empty = 0;
538 while (success && !done)
539 {
540 switch (**type)
541 {
542 case 'C':
543 *type += 1;
544 if (print_ansi_qualifiers)
545 {
546 if (non_empty)
547 string_append (result, " ");
548 else
549 non_empty = 1;
550 string_append (result, "const");
551 }
552 break;
553 case 'U':
554 *type += 1;
555 if (non_empty)
556 string_append (result, " ");
557 else
558 non_empty = 1;
559 string_append (result, "unsigned");
560 break;
561 case 'V':
562 *type += 1;
563 if (print_ansi_qualifiers)
564 {
565 if (non_empty)
566 string_append (result, " ");
567 else
568 non_empty = 1;
569 string_append (result, "volatile");
570 }
571 break;
572 default:
573 done = 1;
574 break;
575 }
576 }
577
578 if (success)
579 switch (**type)
580 {
581 case '\0':
582 case '_':
583 break;
584 case 'v':
585 *type += 1;
586 if (non_empty)
587 string_append (result, " ");
588 string_append (result, "void");
589 break;
590 case 'x':
591 *type += 1;
592 if (non_empty)
593 string_append (result, " ");
594 string_append (result, "long long");
595 break;
596 case 'l':
597 *type += 1;
598 if (non_empty)
599 string_append (result, " ");
600 string_append (result, "long");
601 break;
602 case 'i':
603 *type += 1;
604 if (non_empty)
605 string_append (result, " ");
606 string_append (result, "int");
607 break;
608 case 's':
609 *type += 1;
610 if (non_empty)
611 string_append (result, " ");
612 string_append (result, "short");
613 break;
614 case 'c':
615 *type += 1;
616 if (non_empty)
617 string_append (result, " ");
618 string_append (result, "char");
619 break;
620 case 'r':
621 *type += 1;
622 if (non_empty)
623 string_append (result, " ");
624 string_append (result, "long double");
625 break;
626 case 'd':
627 *type += 1;
628 if (non_empty)
629 string_append (result, " ");
630 string_append (result, "double");
631 break;
632 case 'f':
633 *type += 1;
634 if (non_empty)
635 string_append (result, " ");
636 string_append (result, "float");
637 break;
638 case 'G':
639 *type += 1;
640 if (!isdigit (**type))
641 {
642 success = 0;
643 break;
644 }
645 /* fall through */
646 case '0':
647 case '1':
648 case '2':
649 case '3':
650 case '4':
651 case '5':
652 case '6':
653 case '7':
654 case '8':
655 case '9':
656 n = 0;
657 do
658 {
659 n *= 10;
660 n += **type - '0';
661 *type += 1;
662 }
663 while (isdigit (**type));
664 if (strlen (*type) < n)
665 {
666 success = 0;
667 break;
668 }
669 if (non_empty)
670 string_append (result, " ");
671 string_appendn (result, *type, n);
672 *type += n;
673 break;
674 default:
675 success = 0;
676 break;
677 }
678
679 if (success)
680 {
681 if (!string_empty (&decl))
682 {
683 string_append (result, " ");
684 string_appends (result, &decl);
685 }
686 string_delete (&decl);
687 return 1;
688 }
689 else
690 {
691 string_delete (&decl);
692 string_delete (result);
693 return 0;
694 }
695 }
696
697 /* `result' will be initialised in do_type; it will be freed on failure */
698
699 static int
700 do_arg (type, result, arg_mode)
701 const char **type;
702 string *result;
703 int arg_mode;
704 {
705 const char *start = *type;
706
707 if (!do_type (type, result, arg_mode))
708 return 0;
709 remember_type (start, *type - start);
710 return 1;
711 }
712
713 static void
714 remember_type (start, len)
715 const char *start;
716 int len;
717 {
718 char *tem;
719
720 if (ntypes >= typevec_size)
721 {
722 if (typevec_size == 0)
723 {
724 typevec_size = 3;
725 typevec = (char **) xmalloc (sizeof (char*)*typevec_size);
726 }
727 else
728 {
729 typevec_size *= 2;
730 typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size);
731 }
732 }
733 tem = (char *) xmalloc (len + 1);
734 memcpy (tem, start, len);
735 tem[len] = '\0';
736 typevec[ntypes++] = tem;
737 }
738
739 /* `decl' must be already initialised, usually non-empty;
740 it won't be freed on failure */
741
742 static int
743 do_args (type, decl, arg_mode)
744 const char **type;
745 string *decl;
746 int arg_mode;
747 {
748 string arg;
749 int need_comma = 0;
750
751 if (print_arg_types)
752 string_append (decl, "(");
753
754 while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
755 {
756 if (**type == 'N')
757 {
758 int r;
759 int t;
760 *type += 1;
761 if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes)
762 return 0;
763 while (--r >= 0)
764 {
765 const char *tem = typevec[t];
766 if (need_comma && print_arg_types)
767 string_append (decl, ", ");
768 if (!do_arg (&tem, &arg, arg_mode))
769 return 0;
770 if (print_arg_types)
771 string_appends (decl, &arg);
772 string_delete (&arg);
773 need_comma = 1;
774 }
775 }
776 else
777 {
778 if (need_comma & print_arg_types)
779 string_append (decl, ", ");
780 if (!do_arg (type, &arg, arg_mode))
781 return 0;
782 if (print_arg_types)
783 string_appends (decl, &arg);
784 string_delete (&arg);
785 need_comma = 1;
786 }
787 }
788
789 if (**type == 'v')
790 *type += 1;
791 else if (**type == 'e')
792 {
793 *type += 1;
794 if (print_arg_types)
795 {
796 if (need_comma)
797 string_append (decl, ",");
798 string_append (decl, "...");
799 }
800 }
801
802 if (print_arg_types)
803 string_append (decl, ")");
804 return 1;
805 }
806
807 static void
808 munge_function_name (name, arg_mode)
809 string *name;
810 int arg_mode;
811 {
812 if (!string_empty (name) && name->p - name->b >= 3
813 && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$')
814 {
815 int i;
816 /* see if it's an assignment expression */
817 if (name->p - name->b >= 10 /* op$assign_ */
818 && memcmp (name->b + 3, "assign_", 7) == 0)
819 {
820 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
821 {
822 int len = name->p - name->b - 10;
823 if (strlen (optable[i].in) == len
824 && memcmp (optable[i].in, name->b + 10, len) == 0)
825 {
826 string_clear (name);
827 string_append (name, "operator");
828 string_append (name, optable[i].out);
829 string_append (name, "=");
830 return;
831 }
832 }
833 }
834 else
835 {
836 for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++)
837 {
838 int len = name->p - name->b - 3;
839 if (strlen (optable[i].in) == len
840 && memcmp (optable[i].in, name->b + 3, len) == 0)
841 {
842 string_clear (name);
843 string_append (name, "operator");
844 string_append (name, optable[i].out);
845 return;
846 }
847 }
848 }
849 return;
850 }
851 else if (!string_empty (name) && name->p - name->b >= 5
852 && memcmp (name->b, "type$", 5) == 0)
853 {
854 /* type conversion operator */
855 string type;
856 const char *tem = name->b + 5;
857 if (do_type (&tem, &type, arg_mode))
858 {
859 string_clear (name);
860 string_append (name, "operator ");
861 string_appends (name, &type);
862 string_delete (&type);
863 return;
864 }
865 }
866 }
867
868 /* a mini string-handling package */
869
870 static void
871 string_need (s, n)
872 string *s;
873 int n;
874 {
875 if (s->b == NULL)
876 {
877 if (n < 32)
878 n = 32;
879 s->p = s->b = (char *) xmalloc (n);
880 s->e = s->b + n;
881 }
882 else if (s->e - s->p < n)
883 {
884 int tem = s->p - s->b;
885 n += tem;
886 n *= 2;
887 s->b = (char *) xrealloc (s->b, n);
888 s->p = s->b + tem;
889 s->e = s->b + n;
890 }
891 }
892
893 static void
894 string_delete (s)
895 string *s;
896 {
897 if (s->b != NULL)
898 {
899 free (s->b);
900 s->b = s->e = s->p = NULL;
901 }
902 }
903
904 static void
905 string_init (s)
906 string *s;
907 {
908 s->b = s->p = s->e = NULL;
909 }
910
911 static void
912 string_clear (s)
913 string *s;
914 {
915 s->p = s->b;
916 }
917
918 static int
919 string_empty (s)
920 string *s;
921 {
922 return s->b == s->p;
923 }
924
925 static void
926 string_append (p, s)
927 string *p;
928 const char *s;
929 {
930 int n;
931 if (s == NULL || *s == '\0')
932 return;
933 n = strlen (s);
934 string_need (p, n);
935 memcpy (p->p, s, n);
936 p->p += n;
937 }
938
939 static void
940 string_appends (p, s)
941 string *p, *s;
942 {
943 int n;
944 if (s->b == s->p)
945 return;
946 n = s->p - s->b;
947 string_need (p, n);
948 memcpy (p->p, s->b, n);
949 p->p += n;
950 }
951
952 static void
953 string_appendn (p, s, n)
954 string *p;
955 const char *s;
956 int n;
957 {
958 if (n == 0)
959 return;
960 string_need (p, n);
961 memcpy (p->p, s, n);
962 p->p += n;
963 }
964
965 static void
966 string_prepend (p, s)
967 string *p;
968 const char *s;
969 {
970 if (s == NULL || *s == '\0')
971 return;
972 string_prependn (p, s, strlen (s));
973 }
974
975 #if 0
976 static void
977 string_prepends (p, s)
978 string *p, *s;
979 {
980 if (s->b == s->p)
981 return;
982 string_prependn (p, s->b, s->p - s->b);
983 }
984 #endif
985
986 static void
987 string_prependn (p, s, n)
988 string *p;
989 const char *s;
990 int n;
991 {
992 char *q;
993
994 if (n == 0)
995 return;
996 string_need (p, n);
997 for (q = p->p - 1; q >= p->b; q--)
998 q[n] = q[0];
999 memcpy (p->b, s, n);
1000 p->p += n;
1001 }
This page took 0.050567 seconds and 4 git commands to generate.