1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 2001-2006, Free Software Foundation, Inc. *
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, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, USA. *
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. *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
31 ****************************************************************************/
39 #define ISDIGIT(c) isdigit(c)
40 #define PARMS(ARGS) ARGS
43 #include "adadecode.h"
45 static void add_verbose (const char *, char *);
46 static int has_prefix (const char *, const char *);
47 static int has_suffix (const char *, const char *);
49 /* This is a safe version of strcpy that can be used with overlapped
50 pointers. Does nothing if s2 <= s1. */
51 static void ostrcpy (char *s1
, char *s2
);
53 /* Set to nonzero if we have written any verbose info. */
54 static int verbose_info
;
56 /* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending
59 static void add_verbose (const char *text
, char *ada_name
)
61 strcat (ada_name
, verbose_info
? ", " : " (");
62 strcat (ada_name
, text
);
67 /* Returns 1 if NAME starts with PREFIX. */
70 has_prefix (const char *name
, const char *prefix
)
72 return strncmp (name
, prefix
, strlen (prefix
)) == 0;
75 /* Returns 1 if NAME ends with SUFFIX. */
78 has_suffix (const char *name
, const char *suffix
)
80 int nlen
= strlen (name
);
81 int slen
= strlen (suffix
);
83 return nlen
> slen
&& strncmp (name
+ nlen
- slen
, suffix
, slen
) == 0;
86 /* Safe overlapped pointers version of strcpy. */
89 ostrcpy (char *s1
, char *s2
)
93 while (*s2
) *s1
++ = *s2
++;
98 /* This function will return the Ada name from the encoded form.
99 The Ada coding is done in exp_dbug.ads and this is the inverse function.
100 see exp_dbug.ads for full encoding rules, a short description is added
101 below. Right now only objects and routines are handled. Ada types are
102 stripped of their encodings.
104 CODED_NAME is the encoded entity name.
106 ADA_NAME is a pointer to a buffer, it will receive the Ada name. A safe
107 size for this buffer is: strlen (coded_name) * 2 + 60. (60 is for the
108 verbose information).
110 VERBOSE is nonzero if more information about the entity is to be
111 added at the end of the Ada name and surrounded by ( and ).
113 Coded name Ada name verbose info
114 ---------------------------------------------------------------------
115 _ada_xyz xyz library level
117 x__yTKB x.y task body
119 x__yX x.y body nested
120 x__yXb x.y body nested
122 x__y$2 x.y overloaded
123 x__y__3 x.y overloaded
145 __gnat_decode (const char *coded_name
, char *ada_name
, int verbose
)
153 /* Check for library level subprogram. */
154 if (has_prefix (coded_name
, "_ada_"))
156 strcpy (ada_name
, coded_name
+ 5);
160 strcpy (ada_name
, coded_name
);
162 /* Check for the first triple underscore in the name. This indicates
163 that the name represents a type with encodings; in this case, we
164 need to strip the encodings. */
168 if ((encodings
= (char *) strstr (ada_name
, "___")) != NULL
)
174 /* Check for task body. */
175 if (has_suffix (ada_name
, "TKB"))
177 ada_name
[strlen (ada_name
) - 3] = '\0';
181 if (has_suffix (ada_name
, "B"))
183 ada_name
[strlen (ada_name
) - 1] = '\0';
187 /* Check for body-nested entity: X[bn] */
188 if (has_suffix (ada_name
, "X"))
190 ada_name
[strlen (ada_name
) - 1] = '\0';
194 if (has_suffix (ada_name
, "Xb"))
196 ada_name
[strlen (ada_name
) - 2] = '\0';
200 if (has_suffix (ada_name
, "Xn"))
202 ada_name
[strlen (ada_name
) - 2] = '\0';
206 /* Change instance of TK__ (object declared inside a task) to __. */
210 while ((tktoken
= (char *) strstr (ada_name
, "TK__")) != NULL
)
212 ostrcpy (tktoken
, tktoken
+ 2);
217 /* Check for overloading: name terminated by $nn or __nn. */
219 int len
= strlen (ada_name
);
223 while (ISDIGIT ((int) ada_name
[(int) len
- 1 - n_digits
]))
226 /* Check if we have $ or __ before digits. */
227 if (ada_name
[len
- 1 - n_digits
] == '$')
229 ada_name
[len
- 1 - n_digits
] = '\0';
232 else if (ada_name
[len
- 1 - n_digits
] == '_'
233 && ada_name
[len
- 1 - n_digits
- 1] == '_')
235 ada_name
[len
- 1 - n_digits
- 1] = '\0';
240 /* Change all "__" to ".". */
242 int len
= strlen (ada_name
);
247 if (ada_name
[k
] == '_' && ada_name
[k
+1] == '_')
250 ostrcpy (ada_name
+ k
+ 1, ada_name
+ k
+ 2);
257 /* Checks for operator name. */
259 const char *trans_table
[][2]
260 = {{"Oabs", "\"abs\""}, {"Oand", "\"and\""}, {"Omod", "\"mod\""},
261 {"Onot", "\"not\""}, {"Oor", "\"or\""}, {"Orem", "\"rem\""},
262 {"Oxor", "\"xor\""}, {"Oeq", "\"=\""}, {"One", "\"/=\""},
263 {"Olt", "\"<\""}, {"Ole", "\"<=\""}, {"Ogt", "\">\""},
264 {"Oge", "\">=\""}, {"Oadd", "\"+\""}, {"Osubtract", "\"-\""},
265 {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""},
266 {"Oexpon", "\"**\""}, {NULL
, NULL
} };
273 if ((optoken
= (char *) strstr (ada_name
, trans_table
[k
][0])) != NULL
)
275 int codedlen
= strlen (trans_table
[k
][0]);
276 int oplen
= strlen (trans_table
[k
][1]);
278 if (codedlen
> oplen
)
279 /* We shrink the space. */
280 ostrcpy (optoken
, optoken
+ codedlen
- oplen
);
281 else if (oplen
> codedlen
)
283 /* We need more space. */
284 int len
= strlen (ada_name
);
285 int space
= oplen
- codedlen
;
286 int num_to_move
= &ada_name
[len
] - optoken
;
289 for (t
= 0; t
< num_to_move
; t
++)
290 ada_name
[len
+ space
- t
- 1] = ada_name
[len
- t
- 1];
293 /* Write symbol in the space. */
294 strncpy (optoken
, trans_table
[k
][1], oplen
);
299 /* Check for table's ending. */
300 if (trans_table
[k
][0] == NULL
)
305 /* If verbose mode is on, we add some information to the Ada name. */
309 add_verbose ("overloaded", ada_name
);
312 add_verbose ("library level", ada_name
);
315 add_verbose ("body nested", ada_name
);
318 add_verbose ("in task", ada_name
);
321 add_verbose ("task body", ada_name
);
323 if (verbose_info
== 1)
324 strcat (ada_name
, ")");
329 ada_demangle (const char *coded_name
)
333 __gnat_decode (coded_name
, ada_name
, 0);
334 return xstrdup (ada_name
);
338 get_encoding (const char *coded_name
, char *encoding
)
340 char * dest_index
= encoding
;
345 /* The heuristics is the following: we assume that the first triple
346 underscore in an encoded name indicates the beginning of the
347 first encoding, and that subsequent triple underscores indicate
348 the next encodings. We assume that the encodings are always at the
349 end of encoded names. */
351 for (p
= coded_name
; *p
!= '\0'; p
++)
362 dest_index
= dest_index
- 2;