1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
8 * C Implementation File *
10 * Copyright (C) 2001-2002, Free Software Foundation, Inc. *
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. *
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. *
29 * GNAT was originally developed by the GNAT team at New York University. *
30 * Extensive contributions were provided by Ada Core Technologies Inc. *
32 ****************************************************************************/
39 #define PARMS(ARGS) ARGS
43 #include "adadecode.h"
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 *));
49 /* Set to nonzero if we have written any verbose info. */
50 static int verbose_info;
52 /* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending
55 static void add_verbose (text, ada_name)
59 strcat (ada_name, verbose_info ? ", " : " (");
60 strcat (ada_name, text);
65 /* Returns 1 if NAME starts with PREFIX. */
68 has_prefix (name, prefix)
72 return strncmp (name, prefix, strlen (prefix)) == 0;
75 /* Returns 1 if NAME ends with SUFFIX. */
78 has_suffix (name, suffix)
82 int nlen = strlen (name);
83 int slen = strlen (suffix);
85 return nlen > slen && strncmp (name + nlen - slen, suffix, slen) == 0;
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
94 CODED_NAME is the encoded entity name.
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
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 ).
103 Coded name Ada name verbose info
104 ---------------------------------------------------------------------
105 _ada_xyz xyz library level
107 x__yTKB x.y task body
109 x__yX x.y body nested
110 x__yXb x.y body nested
112 x__y$2 x.y overloaded
113 x__y__3 x.y overloaded
135 __gnat_decode (coded_name, ada_name, verbose)
136 const char *coded_name;
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);
150 /* Check for library level subprogram. */
151 if (has_prefix (ada_name, "_ada_"))
153 strcpy (ada_name, ada_name + 5);
157 /* Check for task body. */
158 if (has_suffix (ada_name, "TKB"))
160 ada_name[strlen (ada_name) - 3] = '\0';
164 if (has_suffix (ada_name, "B"))
166 ada_name[strlen (ada_name) - 1] = '\0';
170 /* Check for body-nested entity: X[bn] */
171 if (has_suffix (ada_name, "X"))
173 ada_name[strlen (ada_name) - 1] = '\0';
177 if (has_suffix (ada_name, "Xb"))
179 ada_name[strlen (ada_name) - 2] = '\0';
183 if (has_suffix (ada_name, "Xn"))
185 ada_name[strlen (ada_name) - 2] = '\0';
189 /* Change instance of TK__ (object declared inside a task) to __. */
193 while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
195 strcpy (tktoken, tktoken + 2);
200 /* Check for overloading: name terminated by $nn or __nn. */
202 int len = strlen (ada_name);
206 while (isdigit ((int) ada_name[(int) len - 1 - n_digits]))
209 /* Check if we have $ or __ before digits. */
210 if (ada_name[len - 1 - n_digits] == '$')
212 ada_name[len - 1 - n_digits] = '\0';
215 else if (ada_name[len - 1 - n_digits] == '_'
216 && ada_name[len - 1 - n_digits - 1] == '_')
218 ada_name[len - 1 - n_digits - 1] = '\0';
223 /* Change all "__" to ".". */
225 int len = strlen (ada_name);
230 if (ada_name[k] == '_' && ada_name[k+1] == '_')
233 strcpy (ada_name + k + 1, ada_name + k + 2);
240 /* Checks for operator name. */
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} };
256 if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL)
258 int codedlen = strlen (trans_table[k][0]);
259 int oplen = strlen (trans_table[k][1]);
261 if (codedlen > oplen)
262 /* We shrink the space. */
263 strcpy (optoken, optoken + codedlen - oplen);
264 else if (oplen > codedlen)
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;
272 for (t = 0; t < num_to_move; t++)
273 ada_name[len + space - t - 1] = ada_name[len - t - 1];
276 /* Write symbol in the space. */
277 strncpy (optoken, trans_table[k][1], oplen);
282 /* Check for table's ending. */
283 if (trans_table[k][0] == NULL)
288 /* If verbose mode is on, we add some information to the Ada name. */
292 add_verbose ("overloaded", ada_name);
295 add_verbose ("library level", ada_name);
298 add_verbose ("body nested", ada_name);
301 add_verbose ("in task", ada_name);
304 add_verbose ("task body", ada_name);
306 if (verbose_info == 1)
307 strcat (ada_name, ")");
312 ada_demangle (coded_name)
313 const char *coded_name;
317 __gnat_decode (coded_name, ada_name, 0);
318 return xstrdup (ada_name);