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