OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc3/] [gcc/] [ada/] [adadecode.c] - Blame information for rev 516

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 281 jeremybenn
/****************************************************************************
2
 *                                                                          *
3
 *                         GNAT COMPILER COMPONENTS                         *
4
 *                                                                          *
5
 *                            A D A D E C O D E                             *
6
 *                                                                          *
7
 *                          C Implementation File                           *
8
 *                                                                          *
9
 *           Copyright (C) 2001-2009, 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 3,  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.                                     *
17
 *                                                                          *
18
 * As a special exception under Section 7 of GPL version 3, you are granted *
19
 * additional permissions described in the GCC Runtime Library Exception,   *
20
 * version 3.1, as published by the Free Software Foundation.               *
21
 *                                                                          *
22
 * You should have received a copy of the GNU General Public License and    *
23
 * a copy of the GCC Runtime Library Exception along with this program;     *
24
 * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
25
 * <http://www.gnu.org/licenses/>.                                          *
26
 *                                                                          *
27
 * GNAT was originally developed  by the GNAT team at  New York University. *
28
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
29
 *                                                                          *
30
 ****************************************************************************/
31
 
32
 
33
#if defined(IN_RTS)
34
#include "tconfig.h"
35
#include "tsystem.h"
36
#elif defined(IN_GCC)
37
#include "config.h"
38
#include "system.h"
39
#endif
40
 
41
#include <string.h>
42
#include <stdio.h>
43
#include <ctype.h>
44
 
45
#include "adaint.h"
46
 
47
#ifndef ISDIGIT
48
#define ISDIGIT(c) isdigit(c)
49
#endif
50
 
51
#ifndef PARMS
52
#define PARMS(ARGS) ARGS
53
#endif
54
 
55
#include "adadecode.h"
56
 
57
static void add_verbose (const char *, char *);
58
static int has_prefix (const char *, const char *);
59
static int has_suffix (const char *, const char *);
60
 
61
/* This is a safe version of strcpy that can be used with overlapped
62
   pointers. Does nothing if s2 <= s1.  */
63
static void ostrcpy (char *s1, char *s2);
64
 
65
/* Set to nonzero if we have written any verbose info.  */
66
static int verbose_info;
67
 
68
/* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending
69
   on VERBOSE_INFO.  */
70
 
71
static void add_verbose (const char *text, char *ada_name)
72
{
73
  strcat (ada_name, verbose_info ? ", " : " (");
74
  strcat (ada_name, text);
75
 
76
  verbose_info = 1;
77
}
78
 
79
/* Returns 1 if NAME starts with PREFIX.  */
80
 
81
static int
82
has_prefix (const char *name, const char *prefix)
83
{
84
  return strncmp (name, prefix, strlen (prefix)) == 0;
85
}
86
 
87
/* Returns 1 if NAME ends with SUFFIX.  */
88
 
89
static int
90
has_suffix (const char *name, const char *suffix)
91
{
92
  int nlen = strlen (name);
93
  int slen = strlen (suffix);
94
 
95
  return nlen > slen && strncmp (name + nlen - slen, suffix, slen) == 0;
96
}
97
 
98
/* Safe overlapped pointers version of strcpy.  */
99
 
100
static void
101
ostrcpy (char *s1, char *s2)
102
{
103
  if (s2 > s1)
104
    {
105
      while (*s2) *s1++ = *s2++;
106
      *s1 = '\0';
107
    }
108
}
109
 
110
/* This function will return the Ada name from the encoded form.
111
   The Ada coding is done in exp_dbug.ads and this is the inverse function.
112
   see exp_dbug.ads for full encoding rules, a short description is added
113
   below. Right now only objects and routines are handled. Ada types are
114
   stripped of their encodings.
115
 
116
   CODED_NAME is the encoded entity name.
117
 
118
   ADA_NAME is a pointer to a buffer, it will receive the Ada name. A safe
119
   size for this buffer is: strlen (coded_name) * 2 + 60. (60 is for the
120
   verbose information).
121
 
122
   VERBOSE is nonzero if more information about the entity is to be
123
   added at the end of the Ada name and surrounded by ( and ).
124
 
125
     Coded name           Ada name                verbose info
126
  ---------------------------------------------------------------------
127
  _ada_xyz                xyz                     library level
128
  x__y__z                 x.y.z
129
  x__yTKB                 x.y                     task body
130
  x__yB                   x.y                     task body
131
  x__yX                   x.y                     body nested
132
  x__yXb                  x.y                     body nested
133
  xTK__y                  x.y                     in task
134
  x__y$2                  x.y                     overloaded
135
  x__y__3                 x.y                     overloaded
136
  x__Oabs                 "abs"
137
  x__Oand                 "and"
138
  x__Omod                 "mod"
139
  x__Onot                 "not"
140
  x__Oor                  "or"
141
  x__Orem                 "rem"
142
  x__Oxor                 "xor"
143
  x__Oeq                  "="
144
  x__One                  "/="
145
  x__Olt                  "<"
146
  x__Ole                  "<="
147
  x__Ogt                  ">"
148
  x__Oge                  ">="
149
  x__Oadd                 "+"
150
  x__Osubtract            "-"
151
  x__Oconcat              "&"
152
  x__Omultiply            "*"
153
  x__Odivide              "/"
154
  x__Oexpon               "**"     */
155
 
156
void
157
__gnat_decode (const char *coded_name, char *ada_name, int verbose)
158
{
159
  int lib_subprog = 0;
160
  int overloaded = 0;
161
  int task_body = 0;
162
  int in_task = 0;
163
  int body_nested = 0;
164
 
165
  /* Check for library level subprogram.  */
166
  if (has_prefix (coded_name, "_ada_"))
167
    {
168
      strcpy (ada_name, coded_name + 5);
169
      lib_subprog = 1;
170
    }
171
  else
172
    strcpy (ada_name, coded_name);
173
 
174
  /* Check for the first triple underscore in the name. This indicates
175
     that the name represents a type with encodings; in this case, we
176
     need to strip the encodings.  */
177
  {
178
    char *encodings;
179
 
180
    if ((encodings = (char *) strstr (ada_name, "___")) != NULL)
181
      {
182
        *encodings = '\0';
183
      }
184
  }
185
 
186
  /* Check for task body.  */
187
  if (has_suffix (ada_name, "TKB"))
188
    {
189
      ada_name[strlen (ada_name) - 3] = '\0';
190
      task_body = 1;
191
    }
192
 
193
  if (has_suffix (ada_name, "B"))
194
    {
195
      ada_name[strlen (ada_name) - 1] = '\0';
196
      task_body = 1;
197
    }
198
 
199
  /* Check for body-nested entity: X[bn] */
200
  if (has_suffix (ada_name, "X"))
201
    {
202
      ada_name[strlen (ada_name) - 1] = '\0';
203
      body_nested = 1;
204
    }
205
 
206
  if (has_suffix (ada_name, "Xb"))
207
    {
208
      ada_name[strlen (ada_name) - 2] = '\0';
209
      body_nested = 1;
210
    }
211
 
212
  if (has_suffix (ada_name, "Xn"))
213
    {
214
      ada_name[strlen (ada_name) - 2] = '\0';
215
      body_nested = 1;
216
    }
217
 
218
  /* Change instance of TK__ (object declared inside a task) to __.  */
219
  {
220
    char *tktoken;
221
 
222
    while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
223
      {
224
        ostrcpy (tktoken, tktoken + 2);
225
        in_task = 1;
226
      }
227
  }
228
 
229
  /* Check for overloading: name terminated by $nn or __nn.  */
230
  {
231
    int len = strlen (ada_name);
232
    int n_digits = 0;
233
 
234
    if (len > 1)
235
      while (ISDIGIT ((int) ada_name[(int) len - 1 - n_digits]))
236
        n_digits++;
237
 
238
    /* Check if we have $ or __ before digits.  */
239
    if (ada_name[len - 1 - n_digits] == '$')
240
      {
241
        ada_name[len - 1 - n_digits] = '\0';
242
        overloaded = 1;
243
      }
244
    else if (ada_name[len - 1 - n_digits] == '_'
245
             && ada_name[len - 1 - n_digits - 1] == '_')
246
      {
247
        ada_name[len - 1 - n_digits - 1] = '\0';
248
        overloaded = 1;
249
      }
250
  }
251
 
252
  /* Check for nested subprogram ending in .nnnn and strip suffix. */
253
  {
254
    int last = strlen (ada_name) - 1;
255
 
256
    while (ISDIGIT (ada_name[last]) && last > 0)
257
      {
258
        last--;
259
      }
260
 
261
    if (ada_name[last] == '.')
262
      {
263
        ada_name[last] = (char) 0;
264
      }
265
  }
266
 
267
  /* Change all "__" to ".". */
268
  {
269
    int len = strlen (ada_name);
270
    int k = 0;
271
 
272
    while (k < len)
273
      {
274
        if (ada_name[k] == '_' && ada_name[k+1] == '_')
275
          {
276
            ada_name[k] = '.';
277
            ostrcpy (ada_name + k + 1, ada_name + k + 2);
278
            len = len - 1;
279
          }
280
        k++;
281
      }
282
  }
283
 
284
  /* Checks for operator name.  */
285
  {
286
    const char *trans_table[][2]
287
      = {{"Oabs", "\"abs\""},  {"Oand", "\"and\""},    {"Omod", "\"mod\""},
288
         {"Onot", "\"not\""},  {"Oor", "\"or\""},      {"Orem", "\"rem\""},
289
         {"Oxor", "\"xor\""},  {"Oeq", "\"=\""},       {"One", "\"/=\""},
290
         {"Olt", "\"<\""},     {"Ole", "\"<=\""},      {"Ogt", "\">\""},
291
         {"Oge", "\">=\""},    {"Oadd", "\"+\""},      {"Osubtract", "\"-\""},
292
         {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""},
293
         {"Oexpon", "\"**\""}, {NULL, NULL} };
294
    int k = 0;
295
 
296
    while (1)
297
      {
298
        char *optoken;
299
 
300
        if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL)
301
          {
302
            int codedlen = strlen (trans_table[k][0]);
303
            int oplen = strlen (trans_table[k][1]);
304
 
305
            if (codedlen > oplen)
306
              /* We shrink the space.  */
307
              ostrcpy (optoken, optoken + codedlen - oplen);
308
            else if (oplen > codedlen)
309
              {
310
                /* We need more space.  */
311
                int len = strlen (ada_name);
312
                int space = oplen - codedlen;
313
                int num_to_move = &ada_name[len] - optoken;
314
                int t;
315
 
316
                for (t = 0; t < num_to_move; t++)
317
                  ada_name[len + space - t - 1] = ada_name[len - t - 1];
318
              }
319
 
320
            /* Write symbol in the space.  */
321
            strncpy (optoken, trans_table[k][1], oplen);
322
          }
323
        else
324
          k++;
325
 
326
        /* Check for table's ending.  */
327
        if (trans_table[k][0] == NULL)
328
          break;
329
      }
330
  }
331
 
332
  /* If verbose mode is on, we add some information to the Ada name.  */
333
  if (verbose)
334
    {
335
      if (overloaded)
336
        add_verbose ("overloaded", ada_name);
337
 
338
      if (lib_subprog)
339
        add_verbose ("library level", ada_name);
340
 
341
      if (body_nested)
342
        add_verbose ("body nested", ada_name);
343
 
344
      if (in_task)
345
        add_verbose ("in task", ada_name);
346
 
347
      if (task_body)
348
        add_verbose ("task body", ada_name);
349
 
350
      if (verbose_info == 1)
351
        strcat (ada_name, ")");
352
    }
353
}
354
 
355
#ifdef IN_GCC
356
char *
357
ada_demangle (const char *coded_name)
358
{
359
  char ada_name[2048];
360
 
361
  __gnat_decode (coded_name, ada_name, 0);
362
  return xstrdup (ada_name);
363
}
364
#endif
365
 
366
void
367
get_encoding (const char *coded_name, char *encoding)
368
{
369
  char * dest_index = encoding;
370
  const char *p;
371
  int found = 0;
372
  int count = 0;
373
 
374
  /* The heuristics is the following: we assume that the first triple
375
     underscore in an encoded name indicates the beginning of the
376
     first encoding, and that subsequent triple underscores indicate
377
     the next encodings. We assume that the encodings are always at the
378
     end of encoded names.  */
379
 
380
  for (p = coded_name; *p != '\0'; p++)
381
    {
382
      if (*p != '_')
383
        count = 0;
384
      else
385
        if (++count == 3)
386
          {
387
            count = 0;
388
 
389
            if (found)
390
              {
391
                dest_index = dest_index - 2;
392
                *dest_index++ = ':';
393
              }
394
 
395
            p++;
396
            found = 1;
397
          }
398
 
399
      if (found)
400
        *dest_index++ = *p;
401
    }
402
 
403
  *dest_index = '\0';
404
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.