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