OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ada / adadecode.c
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                             G N A T D E C O                              *
6  *                                                                          *
7  *                                                                          *
8  *                          C Implementation File                           *
9  *                                                                          *
10  *           Copyright (C) 2001-2002, Free Software Foundation, Inc.        *
11  *                                                                          *
12  * GNAT is free software;  you can  redistribute it  and/or modify it under *
13  * terms of the  GNU General Public License as published  by the Free Soft- *
14  * ware  Foundation;  either version 2,  or (at your option) any later ver- *
15  * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
16  * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
18  * for  more details.  You should have  received  a copy of the GNU General *
19  * Public License  distributed with GNAT;  see file COPYING.  If not, write *
20  * to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, *
21  * MA 02111-1307, USA.                                                      *
22  *                                                                          *
23  * As a  special  exception,  if you  link  this file  with other  files to *
24  * produce an executable,  this file does not by itself cause the resulting *
25  * executable to be covered by the GNU General Public License. This except- *
26  * ion does not  however invalidate  any other reasons  why the  executable *
27  * file might be covered by the  GNU Public License.                        *
28  *                                                                          *
29  * GNAT was originally developed  by the GNAT team at  New York University. *
30  * Extensive contributions were provided by Ada Core Technologies Inc.      *
31  *                                                                          *
32  ****************************************************************************/
33
34 #ifdef IN_GCC
35 #include "config.h"
36 #include "system.h"
37 #else
38 #include <stdio.h>
39 #define PARMS(ARGS) ARGS
40 #endif
41
42 #include "ctype.h"
43 #include "adadecode.h"
44
45 static void add_verbose PARAMS ((const char *, char *));
46 static int has_prefix   PARAMS ((char *, const char *));
47 static int has_suffix   PARAMS ((char *, const char *));
48
49 /* Set to nonzero if we have written any verbose info.  */
50 static int verbose_info;
51
52 /* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending
53    on VERBOSE_INFO.  */
54
55 static void add_verbose (text, ada_name)
56      const char *text;
57      char *ada_name;
58 {
59   strcat (ada_name, verbose_info ? ", " : " (");
60   strcat (ada_name, text);
61
62   verbose_info = 1;
63 }
64
65 /* Returns 1 if NAME starts with PREFIX.  */
66
67 static int
68 has_prefix (name, prefix)
69      char *name;
70      const char *prefix;
71 {
72   return strncmp (name, prefix, strlen (prefix)) == 0;
73 }
74
75 /* Returns 1 if NAME ends with SUFFIX.  */
76
77 static int
78 has_suffix (name, suffix)
79      char *name;
80      const char *suffix;
81 {
82   int nlen = strlen (name);
83   int slen = strlen (suffix);
84
85   return nlen > slen && strncmp (name + nlen - slen, suffix, slen) == 0;
86 }
87
88 /* This function will return the Ada name from the encoded form.
89    The Ada coding is done in exp_dbug.ads and this is the inverse function.
90    see exp_dbug.ads for full encoding rules, a short description is added
91    below. Right now only objects and routines are handled. There is no support
92    for Ada types.
93
94    CODED_NAME is the encoded entity name.
95
96    ADA_NAME is a pointer to a buffer, it will receive the Ada name. A safe
97    size for this buffer is: strlen (coded_name) * 2 + 60. (60 is for the
98    verbose information).
99
100    VERBOSE is nonzero if more information about the entity is to be
101    added at the end of the Ada name and surrounded by ( and ).
102
103      Coded name           Ada name                verbose info
104   ---------------------------------------------------------------------
105   _ada_xyz                xyz                     library level
106   x__y__z                 x.y.z
107   x__yTKB                 x.y                     task body
108   x__yB                   x.y                     task body
109   x__yX                   x.y                     body nested
110   x__yXb                  x.y                     body nested
111   xTK__y                  x.y                     in task
112   x__y$2                  x.y                     overloaded
113   x__y__3                 x.y                     overloaded
114   x__Oabs                 "abs"
115   x__Oand                 "and"
116   x__Omod                 "mod"
117   x__Onot                 "not"
118   x__Oor                  "or"
119   x__Orem                 "rem"
120   x__Oxor                 "xor"
121   x__Oeq                  "="
122   x__One                  "/="
123   x__Olt                  "<"
124   x__Ole                  "<="
125   x__Ogt                  ">"
126   x__Oge                  ">="
127   x__Oadd                 "+"
128   x__Osubtract            "-"
129   x__Oconcat              "&"
130   x__Omultiply            "*"
131   x__Odivide              "/"
132   x__Oexpon               "**"     */
133
134 void
135 __gnat_decode (coded_name, ada_name, verbose)
136      const char *coded_name;
137      char *ada_name;
138      int verbose;
139 {
140   int lib_subprog = 0;
141   int overloaded = 0;
142   int task_body = 0;
143   int in_task = 0;
144   int body_nested = 0;
145
146   /* Copy the coded name into the ada name string, the rest of the code will
147      just replace or add characters into the ada_name.  */
148   strcpy (ada_name, coded_name);
149
150   /* Check for library level subprogram.  */
151   if (has_prefix (ada_name, "_ada_"))
152     {
153       strcpy (ada_name, ada_name + 5);
154       lib_subprog = 1;
155     }
156
157   /* Check for task body.  */
158   if (has_suffix (ada_name, "TKB"))
159     {
160       ada_name[strlen (ada_name) - 3] = '\0';
161       task_body = 1;
162     }
163
164   if (has_suffix (ada_name, "B"))
165     {
166       ada_name[strlen (ada_name) - 1] = '\0';
167       task_body = 1;
168     }
169
170   /* Check for body-nested entity: X[bn] */
171   if (has_suffix (ada_name, "X"))
172     {
173       ada_name[strlen (ada_name) - 1] = '\0';
174       body_nested = 1;
175     }
176
177   if (has_suffix (ada_name, "Xb"))
178     {
179       ada_name[strlen (ada_name) - 2] = '\0';
180       body_nested = 1;
181     }
182
183   if (has_suffix (ada_name, "Xn"))
184     {
185       ada_name[strlen (ada_name) - 2] = '\0';
186       body_nested = 1;
187     }
188
189   /* Change instance of TK__ (object declared inside a task) to __.  */
190   {
191     char *tktoken;
192
193     while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
194       {
195         strcpy (tktoken, tktoken + 2);
196         in_task = 1;
197       }
198   }
199
200   /* Check for overloading: name terminated by $nn or __nn.  */
201   {
202     int len = strlen (ada_name);
203     int n_digits = 0;
204
205     if (len > 1)
206       while (isdigit ((int) ada_name[(int) len - 1 - n_digits]))
207         n_digits++;
208
209     /* Check if we have $ or __ before digits.  */
210     if (ada_name[len - 1 - n_digits] == '$')
211       {
212         ada_name[len - 1 - n_digits] = '\0';
213         overloaded = 1;
214       }
215     else if (ada_name[len - 1 - n_digits] == '_'
216              && ada_name[len - 1 - n_digits - 1] == '_')
217       {
218         ada_name[len - 1 - n_digits - 1] = '\0';
219         overloaded = 1;
220       }
221   }
222
223   /* Change all "__" to ".". */
224   {
225     int len = strlen (ada_name);
226     int k = 0;
227
228     while (k < len)
229       {
230         if (ada_name[k] == '_' && ada_name[k+1] == '_')
231           {
232             ada_name[k] = '.';
233             strcpy (ada_name + k + 1, ada_name + k + 2);
234             len = len - 1;
235           }
236         k++;
237       }
238   }
239
240   /* Checks for operator name.  */
241   {
242     const char *trans_table[][2]
243       = {{"Oabs", "\"abs\""},  {"Oand", "\"and\""},    {"Omod", "\"mod\""},
244          {"Onot", "\"not\""},  {"Oor", "\"or\""},      {"Orem", "\"rem\""},
245          {"Oxor", "\"xor\""},  {"Oeq", "\"=\""},       {"One", "\"/=\""},
246          {"Olt", "\"<\""},     {"Ole", "\"<=\""},      {"Ogt", "\">\""},
247          {"Oge", "\">=\""},    {"Oadd", "\"+\""},      {"Osubtract", "\"-\""},
248          {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""},
249          {"Oexpon", "\"**\""}, {NULL, NULL} };
250     int k = 0;
251
252     while (1)
253       {
254         char *optoken;
255
256         if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL)
257           {
258             int codedlen = strlen (trans_table[k][0]);
259             int oplen = strlen (trans_table[k][1]);
260
261             if (codedlen > oplen)
262               /* We shrink the space.  */
263               strcpy (optoken, optoken + codedlen - oplen);
264             else if (oplen > codedlen)
265               {
266                 /* We need more space.  */
267                 int len = strlen (ada_name);
268                 int space = oplen - codedlen;
269                 int num_to_move = &ada_name[len] - optoken;
270                 int t;
271
272                 for (t = 0; t < num_to_move; t++)
273                   ada_name[len + space - t - 1] = ada_name[len - t - 1];
274               }
275
276             /* Write symbol in the space.  */
277             strncpy (optoken, trans_table[k][1], oplen);
278           }
279         else
280           k++;
281
282         /* Check for table's ending.  */
283         if (trans_table[k][0] == NULL)
284           break;
285       }
286   }
287
288   /* If verbose mode is on, we add some information to the Ada name.  */
289   if (verbose) 
290     {
291       if (overloaded)
292         add_verbose ("overloaded", ada_name);
293
294       if (lib_subprog)
295         add_verbose ("library level", ada_name);
296
297       if (body_nested)
298         add_verbose ("body nested", ada_name);
299
300       if (in_task)
301         add_verbose ("in task", ada_name);
302
303       if (task_body)
304         add_verbose ("task body", ada_name);
305
306       if (verbose_info == 1)
307         strcat (ada_name, ")");
308     }
309 }
310
311 char *
312 ada_demangle (coded_name)
313      const char *coded_name;
314 {
315   char ada_name[2048];
316
317   __gnat_decode (coded_name, ada_name, 0);
318   return xstrdup (ada_name);
319 }