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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [adadecode.c] - Blame information for rev 728

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 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-2012, 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"  /* for a macro version of xstrdup.  */
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
  /* Deal with empty input early.  This allows assuming non-null length
166
     later on, simplifying coding.  In principle, it should be our callers
167
     business not to call here for empty inputs.  It is easy enough to
168
     allow it, however, and might allow simplifications upstream so is not
169
     a bad thing per se.  We need a guard in any case.  */
170
 
171
  if (*coded_name == '\0')
172
    {
173
      *ada_name = '\0';
174
      return;
175
    }
176
 
177
  /* Check for library level subprogram.  */
178
  else if (has_prefix (coded_name, "_ada_"))
179
    {
180
      strcpy (ada_name, coded_name + 5);
181
      lib_subprog = 1;
182
    }
183
  else
184
    strcpy (ada_name, coded_name);
185
 
186
  /* Check for the first triple underscore in the name. This indicates
187
     that the name represents a type with encodings; in this case, we
188
     need to strip the encodings.  */
189
  {
190
    char *encodings;
191
 
192
    if ((encodings = (char *) strstr (ada_name, "___")) != NULL)
193
      {
194
        *encodings = '\0';
195
      }
196
  }
197
 
198
  /* Check for task body.  */
199
  if (has_suffix (ada_name, "TKB"))
200
    {
201
      ada_name[strlen (ada_name) - 3] = '\0';
202
      task_body = 1;
203
    }
204
 
205
  if (has_suffix (ada_name, "B"))
206
    {
207
      ada_name[strlen (ada_name) - 1] = '\0';
208
      task_body = 1;
209
    }
210
 
211
  /* Check for body-nested entity: X[bn] */
212
  if (has_suffix (ada_name, "X"))
213
    {
214
      ada_name[strlen (ada_name) - 1] = '\0';
215
      body_nested = 1;
216
    }
217
 
218
  if (has_suffix (ada_name, "Xb"))
219
    {
220
      ada_name[strlen (ada_name) - 2] = '\0';
221
      body_nested = 1;
222
    }
223
 
224
  if (has_suffix (ada_name, "Xn"))
225
    {
226
      ada_name[strlen (ada_name) - 2] = '\0';
227
      body_nested = 1;
228
    }
229
 
230
  /* Change instance of TK__ (object declared inside a task) to __.  */
231
  {
232
    char *tktoken;
233
 
234
    while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL)
235
      {
236
        ostrcpy (tktoken, tktoken + 2);
237
        in_task = 1;
238
      }
239
  }
240
 
241
  /* Check for overloading: name terminated by $nn or __nn.  */
242
  {
243
    int len = strlen (ada_name);
244
    int n_digits = 0;
245
 
246
    if (len > 1)
247
      while (ISDIGIT ((int) ada_name[(int) len - 1 - n_digits]))
248
        n_digits++;
249
 
250
    /* Check if we have $ or __ before digits.  */
251
    if (ada_name[len - 1 - n_digits] == '$')
252
      {
253
        ada_name[len - 1 - n_digits] = '\0';
254
        overloaded = 1;
255
      }
256
    else if (ada_name[len - 1 - n_digits] == '_'
257
             && ada_name[len - 1 - n_digits - 1] == '_')
258
      {
259
        ada_name[len - 1 - n_digits - 1] = '\0';
260
        overloaded = 1;
261
      }
262
  }
263
 
264
  /* Check for nested subprogram ending in .nnnn and strip suffix. */
265
  {
266
    int last = strlen (ada_name) - 1;
267
 
268
    while (ISDIGIT (ada_name[last]) && last > 0)
269
      {
270
        last--;
271
      }
272
 
273
    if (ada_name[last] == '.')
274
      {
275
        ada_name[last] = (char) 0;
276
      }
277
  }
278
 
279
  /* Change all "__" to ".". */
280
  {
281
    int len = strlen (ada_name);
282
    int k = 0;
283
 
284
    while (k < len)
285
      {
286
        if (ada_name[k] == '_' && ada_name[k+1] == '_')
287
          {
288
            ada_name[k] = '.';
289
            ostrcpy (ada_name + k + 1, ada_name + k + 2);
290
            len = len - 1;
291
          }
292
        k++;
293
      }
294
  }
295
 
296
  /* Checks for operator name.  */
297
  {
298
    const char *trans_table[][2]
299
      = {{"Oabs", "\"abs\""},  {"Oand", "\"and\""},    {"Omod", "\"mod\""},
300
         {"Onot", "\"not\""},  {"Oor", "\"or\""},      {"Orem", "\"rem\""},
301
         {"Oxor", "\"xor\""},  {"Oeq", "\"=\""},       {"One", "\"/=\""},
302
         {"Olt", "\"<\""},     {"Ole", "\"<=\""},      {"Ogt", "\">\""},
303
         {"Oge", "\">=\""},    {"Oadd", "\"+\""},      {"Osubtract", "\"-\""},
304
         {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""},
305
         {"Oexpon", "\"**\""}, {NULL, NULL} };
306
    int k = 0;
307
 
308
    while (1)
309
      {
310
        char *optoken;
311
 
312
        if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL)
313
          {
314
            int codedlen = strlen (trans_table[k][0]);
315
            int oplen = strlen (trans_table[k][1]);
316
 
317
            if (codedlen > oplen)
318
              /* We shrink the space.  */
319
              ostrcpy (optoken, optoken + codedlen - oplen);
320
            else if (oplen > codedlen)
321
              {
322
                /* We need more space.  */
323
                int len = strlen (ada_name);
324
                int space = oplen - codedlen;
325
                int num_to_move = &ada_name[len] - optoken;
326
                int t;
327
 
328
                for (t = 0; t < num_to_move; t++)
329
                  ada_name[len + space - t - 1] = ada_name[len - t - 1];
330
              }
331
 
332
            /* Write symbol in the space.  */
333
            strncpy (optoken, trans_table[k][1], oplen);
334
          }
335
        else
336
          k++;
337
 
338
        /* Check for table's ending.  */
339
        if (trans_table[k][0] == NULL)
340
          break;
341
      }
342
  }
343
 
344
  /* If verbose mode is on, we add some information to the Ada name.  */
345
  if (verbose)
346
    {
347
      if (overloaded)
348
        add_verbose ("overloaded", ada_name);
349
 
350
      if (lib_subprog)
351
        add_verbose ("library level", ada_name);
352
 
353
      if (body_nested)
354
        add_verbose ("body nested", ada_name);
355
 
356
      if (in_task)
357
        add_verbose ("in task", ada_name);
358
 
359
      if (task_body)
360
        add_verbose ("task body", ada_name);
361
 
362
      if (verbose_info == 1)
363
        strcat (ada_name, ")");
364
    }
365
}
366
 
367
#ifdef __cplusplus
368
extern "C" {
369
#endif
370
 
371
#ifdef IN_GCC
372
char *
373
ada_demangle (const char *coded_name)
374
{
375
  char ada_name[2048];
376
 
377
  __gnat_decode (coded_name, ada_name, 0);
378
  return xstrdup (ada_name);
379
}
380
#endif
381
 
382
void
383
get_encoding (const char *coded_name, char *encoding)
384
{
385
  char * dest_index = encoding;
386
  const char *p;
387
  int found = 0;
388
  int count = 0;
389
 
390
  /* The heuristics is the following: we assume that the first triple
391
     underscore in an encoded name indicates the beginning of the
392
     first encoding, and that subsequent triple underscores indicate
393
     the next encodings. We assume that the encodings are always at the
394
     end of encoded names.  */
395
 
396
  for (p = coded_name; *p != '\0'; p++)
397
    {
398
      if (*p != '_')
399
        count = 0;
400
      else
401
        if (++count == 3)
402
          {
403
            count = 0;
404
 
405
            if (found)
406
              {
407
                dest_index = dest_index - 2;
408
                *dest_index++ = ':';
409
              }
410
 
411
            p++;
412
            found = 1;
413
          }
414
 
415
      if (found)
416
        *dest_index++ = *p;
417
    }
418
 
419
  *dest_index = '\0';
420
}
421
 
422
#ifdef __cplusplus
423
}
424
#endif

powered by: WebSVN 2.1.0

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