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
);