z8kgen: temp file to generate z8k-opc.h from
[external/binutils.git] / bfd / 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)
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__
67 extern char *cplus_demangle (const char *type);
68 #else
69 extern char *cplus_demangle ();
70 #endif
71
72 static char **typevec = 0;
73 static int ntypes = 0;
74 static int typevec_size = 0;
75
76 static 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
118 typedef 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__
125 static void string_need (string *s, int n);
126 static void string_delete (string *s);
127 static void string_init (string *s);
128 static void string_clear (string *s);
129 static int string_empty (string *s);
130 static void string_append (string *p, const char *s);
131 static void string_appends (string *p, string *s);
132 static void string_appendn (string *p, const char *s, int n);
133 static void string_prepend (string *p, const char *s);
134 #if 0
135 static void string_prepends (string *p, string *s);
136 #endif
137 static void string_prependn (string *p, const char *s, int n);
138 static int get_count (const char **type, int *count);
139 static int do_args (const char **type, string *decl);
140 static int do_type (const char **type, string *result);
141 static int do_arg (const char **type, string *result);
142 static int do_args (const char **type, string *decl);
143 static void munge_function_name (string *name);
144 #else
145 static void string_need ();
146 static void string_delete ();
147 static void string_init ();
148 static void string_clear ();
149 static int string_empty ();
150 static void string_append ();
151 static void string_appends ();
152 static void string_appendn ();
153 static void string_prepend ();
154 static void string_prepends ();
155 static void string_prependn ();
156 static int get_count ();
157 static int do_args ();
158 static int do_type ();
159 static int do_arg ();
160 static int do_args ();
161 static void munge_function_name ();
162 #endif
163
164 char *
165 cplus_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
323 static int
324 get_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
355 static int
356 do_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
653 static int
654 do_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
691 static int
692 do_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
760 static void
761 munge_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
822 static void
823 string_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
845 static void
846 string_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
856 static void
857 string_init (s)
858      string *s;
859 {
860   s->b = s->p = s->e = NULL;
861 }
862
863 static void 
864 string_clear (s)
865      string *s;
866 {
867   s->p = s->b;
868 }
869
870 static int
871 string_empty (s)
872      string *s;
873 {
874   return s->b == s->p;
875 }
876
877 static void
878 string_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
891 static void
892 string_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
904 static void
905 string_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
917 static void
918 string_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
927 static void
928 string_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 }