OSDN Git Service

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