OSDN Git Service

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