Add hppa-openbsd target
[official-gcc.git] / gcc / ada / adadecode.c
blobe3ab46d41fc2219d25463db0ff3365aa9211e3a8
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * G N A T D E C O *
6 * *
7 * *
8 * C Implementation File *
9 * *
10 * Copyright (C) 2001-2002, Free Software Foundation, Inc. *
11 * *
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. *
22 * *
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. *
28 * *
29 * GNAT was originally developed by the GNAT team at New York University. *
30 * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). *
31 * *
32 ****************************************************************************/
34 #ifdef IN_GCC
35 #include "config.h"
36 #include "system.h"
37 #else
38 #include <stdio.h>
39 #define PARMS(ARGS) ARGS
40 #endif
42 #include "ctype.h"
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
53 on VERBOSE_INFO. */
55 static void add_verbose (text, ada_name)
56 const char *text;
57 char *ada_name;
59 strcat (ada_name, verbose_info ? ", " : " (");
60 strcat (ada_name, text);
62 verbose_info = 1;
65 /* Returns 1 if NAME starts with PREFIX. */
67 static int
68 has_prefix (name, prefix)
69 char *name;
70 const char *prefix;
72 return strncmp (name, prefix, strlen (prefix)) == 0;
75 /* Returns 1 if NAME ends with SUFFIX. */
77 static int
78 has_suffix (name, suffix)
79 char *name;
80 const char *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
92 for Ada types.
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
98 verbose information).
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
106 x__y__z x.y.z
107 x__yTKB x.y task body
108 x__yB x.y task body
109 x__yX x.y body nested
110 x__yXb x.y body nested
111 xTK__y x.y in task
112 x__y$2 x.y overloaded
113 x__y__3 x.y overloaded
114 x__Oabs "abs"
115 x__Oand "and"
116 x__Omod "mod"
117 x__Onot "not"
118 x__Oor "or"
119 x__Orem "rem"
120 x__Oxor "xor"
121 x__Oeq "="
122 x__One "/="
123 x__Olt "<"
124 x__Ole "<="
125 x__Ogt ">"
126 x__Oge ">="
127 x__Oadd "+"
128 x__Osubtract "-"
129 x__Oconcat "&"
130 x__Omultiply "*"
131 x__Odivide "/"
132 x__Oexpon "**" */
134 void
135 __gnat_decode (coded_name, ada_name, verbose)
136 const char *coded_name;
137 char *ada_name;
138 int verbose;
140 int lib_subprog = 0;
141 int overloaded = 0;
142 int task_body = 0;
143 int in_task = 0;
144 int body_nested = 0;
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);
154 lib_subprog = 1;
157 /* Check for task body. */
158 if (has_suffix (ada_name, "TKB"))
160 ada_name[strlen (ada_name) - 3] = '\0';
161 task_body = 1;
164 if (has_suffix (ada_name, "B"))
166 ada_name[strlen (ada_name) - 1] = '\0';
167 task_body = 1;
170 /* Check for body-nested entity: X[bn] */
171 if (has_suffix (ada_name, "X"))
173 ada_name[strlen (ada_name) - 1] = '\0';
174 body_nested = 1;
177 if (has_suffix (ada_name, "Xb"))
179 ada_name[strlen (ada_name) - 2] = '\0';
180 body_nested = 1;
183 if (has_suffix (ada_name, "Xn"))
185 ada_name[strlen (ada_name) - 2] = '\0';
186 body_nested = 1;
189 /* Change instance of TK__ (object declared inside a task) to __. */
191 char *tktoken;
193 while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
195 strcpy (tktoken, tktoken + 2);
196 in_task = 1;
200 /* Check for overloading: name terminated by $nn or __nn. */
202 int len = strlen (ada_name);
203 int n_digits = 0;
205 if (len > 1)
206 while (isdigit ((int) ada_name[(int) len - 1 - n_digits]))
207 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';
213 overloaded = 1;
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';
219 overloaded = 1;
223 /* Change all "__" to ".". */
225 int len = strlen (ada_name);
226 int k = 0;
228 while (k < len)
230 if (ada_name[k] == '_' && ada_name[k+1] == '_')
232 ada_name[k] = '.';
233 strcpy (ada_name + k + 1, ada_name + k + 2);
234 len = len - 1;
236 k++;
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} };
250 int k = 0;
252 while (1)
254 char *optoken;
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;
270 int t;
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);
279 else
280 k++;
282 /* Check for table's ending. */
283 if (trans_table[k][0] == NULL)
284 break;
288 /* If verbose mode is on, we add some information to the Ada name. */
289 if (verbose)
291 if (overloaded)
292 add_verbose ("overloaded", ada_name);
294 if (lib_subprog)
295 add_verbose ("library level", ada_name);
297 if (body_nested)
298 add_verbose ("body nested", ada_name);
300 if (in_task)
301 add_verbose ("in task", ada_name);
303 if (task_body)
304 add_verbose ("task body", ada_name);
306 if (verbose_info == 1)
307 strcat (ada_name, ")");
311 char *
312 ada_demangle (coded_name)
313 const char *coded_name;
315 char ada_name[2048];
317 __gnat_decode (coded_name, ada_name, 0);
318 return xstrdup (ada_name);