diff options
author | bosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-08 22:49:35 +0000 |
---|---|---|
committer | bosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-08 22:49:35 +0000 |
commit | b9e214e0e1ffeece8a4baf59a1c3b0cbfbff14f8 (patch) | |
tree | e1966bb24cb5ddb58313cbf62e39a664a3776d73 /gcc/ada/adadecode.c | |
parent | 6a81282b53802d45c05cf25c1fdb6e57f24e8835 (diff) | |
download | gcc-b9e214e0e1ffeece8a4baf59a1c3b0cbfbff14f8.tar.gz |
* adadecode.c, adadecode.h, aux-io.c, s-traces.adb, s-traces.ads,
s-tratas.adb, s-tratas.ads, sinput-d.adb, sinput-d.ads,
switch-b.adb, switch-b.ads, switch-c.adb, switch-c.ads,
switch-m.adb, switch-m.ads : New files.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50466 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/adadecode.c')
-rw-r--r-- | gcc/ada/adadecode.c | 325 |
1 files changed, 325 insertions, 0 deletions
diff --git a/gcc/ada/adadecode.c b/gcc/ada/adadecode.c new file mode 100644 index 00000000000..cafd1c35b09 --- /dev/null +++ b/gcc/ada/adadecode.c @@ -0,0 +1,325 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * G N A T D E C O * + * * + * $Revision$ + * * + * C Implementation File * + * * + * Copyright (C) 2001-2002, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 2, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * + * for more details. You should have received a copy of the GNU General * + * Public License distributed with GNAT; see file COPYING. If not, write * + * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, * + * MA 02111-1307, USA. * + * * + * As a special exception, if you link this file with other files to * + * produce an executable, this file does not by itself cause the resulting * + * executable to be covered by the GNU General Public License. This except- * + * ion does not however invalidate any other reasons why the executable * + * file might be covered by the GNU Public License. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). * + * * + ****************************************************************************/ + +#ifdef IN_GCC +#include "config.h" +#include "system.h" +#else +#include <stdio.h> +#define PARMS(ARGS) ARGS +#endif + +#include "ctype.h" +#include "adadecode.h" + +static void add_verbose PARAMS ((const char *, char *)); +static int has_prefix PARAMS ((char *, const char *)); +static int has_suffix PARAMS ((char *, const char *)); + +/* Set to nonzero if we have written any verbose info. */ +static int verbose_info; + +/* Add TEXT to end of ADA_NAME, putting a leading " (" or ", ", depending + on VERBOSE_INFO. */ + +static void add_verbose (text, ada_name) + const char *text; + char *ada_name; +{ + strcat (ada_name, verbose_info ? ", " : " ("); + strcat (ada_name, text); + + verbose_info = 1; +} + +/* Returns 1 if NAME starts with PREFIX. */ + +static int +has_prefix (name, prefix) + char *name; + const char *prefix; +{ + return strncmp (name, prefix, strlen (prefix)) == 0; +} + +/* Returns 1 if NAME ends with SUFFIX. */ + +static int +has_suffix (name, suffix) + char *name; + const char *suffix; +{ + int nlen = strlen (name); + int slen = strlen (suffix); + + return nlen > slen && strncmp (name + nlen - slen, suffix, slen) == 0; +} + +/* This function will return the Ada name from the encoded form. + The Ada coding is done in exp_dbug.ads and this is the inverse function. + see exp_dbug.ads for full encoding rules, a short description is added + below. Right now only objects and routines are handled. There is no support + for Ada types. + + CODED_NAME is the encoded entity name. + + ADA_NAME is a pointer to a buffer, it will receive the Ada name. A safe + size for this buffer is: strlen (coded_name) * 2 + 60. (60 is for the + verbose information). + + VERBOSE is nonzero if more information about the entity is to be + added at the end of the Ada name and surrounded by ( and ). + + Coded name Ada name verbose info + --------------------------------------------------------------------- + _ada_xyz xyz library level + x__y__z x.y.z + x__yTKB x.y task body + x__yB x.y task body + x__yX x.y body nested + x__yXb x.y body nested + xTK__y x.y in task + x__y$2 x.y overloaded + x__y__3 x.y overloaded + x__Oabs "abs" + x__Oand "and" + x__Omod "mod" + x__Onot "not" + x__Oor "or" + x__Orem "rem" + x__Oxor "xor" + x__Oeq "=" + x__One "/=" + x__Olt "<" + x__Ole "<=" + x__Ogt ">" + x__Oge ">=" + x__Oadd "+" + x__Osubtract "-" + x__Oconcat "&" + x__Omultiply "*" + x__Odivide "/" + x__Oexpon "**" */ + +void +__gnat_decode (coded_name, ada_name, verbose) + const char *coded_name; + char *ada_name; + int verbose; +{ + int lib_subprog = 0; + int overloaded = 0; + int task_body = 0; + int in_task = 0; + int body_nested = 0; + + /* Copy the coded name into the ada name string, the rest of the code will + just replace or add characters into the ada_name. */ + strcpy (ada_name, coded_name); + + /* Check for library level subprogram. */ + if (has_prefix (ada_name, "_ada_")) + { + strcpy (ada_name, ada_name + 5); + lib_subprog = 1; + } + + /* Check for task body. */ + if (has_suffix (ada_name, "TKB")) + { + ada_name[strlen (ada_name) - 3] = '\0'; + task_body = 1; + } + + if (has_suffix (ada_name, "B")) + { + ada_name[strlen (ada_name) - 1] = '\0'; + task_body = 1; + } + + /* Check for body-nested entity: X[bn] */ + if (has_suffix (ada_name, "X")) + { + ada_name[strlen (ada_name) - 1] = '\0'; + body_nested = 1; + } + + if (has_suffix (ada_name, "Xb")) + { + ada_name[strlen (ada_name) - 2] = '\0'; + body_nested = 1; + } + + if (has_suffix (ada_name, "Xn")) + { + ada_name[strlen (ada_name) - 2] = '\0'; + body_nested = 1; + } + + /* Change instance of TK__ (object declared inside a task) to __. */ + { + char *tktoken; + + while ((tktoken = (char *) strstr (ada_name, "TK__")) != NULL) + { + strcpy (tktoken, tktoken + 2); + in_task = 1; + } + } + + /* Check for overloading: name terminated by $nn or __nn. */ + { + int len = strlen (ada_name); + int n_digits = 0; + + if (len > 1) + while (isdigit ((int) ada_name[(int) len - 1 - n_digits])) + n_digits++; + + /* Check if we have $ or __ before digits. */ + if (ada_name[len - 1 - n_digits] == '$') + { + ada_name[len - 1 - n_digits] = '\0'; + overloaded = 1; + } + else if (ada_name[len - 1 - n_digits] == '_' + && ada_name[len - 1 - n_digits - 1] == '_') + { + ada_name[len - 1 - n_digits - 1] = '\0'; + overloaded = 1; + } + } + + /* Change all "__" to ".". */ + { + int len = strlen (ada_name); + int k = 0; + + while (k < len) + { + if (ada_name[k] == '_' && ada_name[k+1] == '_') + { + ada_name[k] = '.'; + strcpy (ada_name + k + 1, ada_name + k + 2); + len = len - 1; + } + k++; + } + } + + /* Checks for operator name. */ + { + const char *trans_table[][2] + = {{"Oabs", "\"abs\""}, {"Oand", "\"and\""}, {"Omod", "\"mod\""}, + {"Onot", "\"not\""}, {"Oor", "\"or\""}, {"Orem", "\"rem\""}, + {"Oxor", "\"xor\""}, {"Oeq", "\"=\""}, {"One", "\"/=\""}, + {"Olt", "\"<\""}, {"Ole", "\"<=\""}, {"Ogt", "\">\""}, + {"Oge", "\">=\""}, {"Oadd", "\"+\""}, {"Osubtract", "\"-\""}, + {"Oconcat", "\"&\""}, {"Omultiply", "\"*\""}, {"Odivide", "\"/\""}, + {"Oexpon", "\"**\""}, {NULL, NULL} }; + int k = 0; + + while (1) + { + char *optoken; + + if ((optoken = (char *) strstr (ada_name, trans_table[k][0])) != NULL) + { + int codedlen = strlen (trans_table[k][0]); + int oplen = strlen (trans_table[k][1]); + + if (codedlen > oplen) + /* We shrink the space. */ + strcpy (optoken, optoken + codedlen - oplen); + else if (oplen > codedlen) + { + /* We need more space. */ + int len = strlen (ada_name); + int space = oplen - codedlen; + int num_to_move = &ada_name[len] - optoken; + int t; + + for (t = 0; t < num_to_move; t++) + ada_name[len + space - t - 1] = ada_name[len - t - 1]; + } + + /* Write symbol in the space. */ + strncpy (optoken, trans_table[k][1], oplen); + } + else + k++; + + /* Check for table's ending. */ + if (trans_table[k][0] == NULL) + break; + } + } + + /* If verbose mode is on, we add some information to the Ada name. */ + if (verbose) + { + if (overloaded) + add_verbose ("overloaded", ada_name); + + if (lib_subprog) + add_verbose ("library level", ada_name); + + if (body_nested) + add_verbose ("body nested", ada_name); + + if (in_task) + add_verbose ("in task", ada_name); + + if (task_body) + add_verbose ("task body", ada_name); + + if (verbose_info == 1) + strcat (ada_name, ")"); + } +} + +char * +ada_demangle (coded_name) + const char *coded_name; +{ + char ada_name[2048]; + char *result; + + __gnat_decode (coded_name, ada_name, 0); + + result = (char *) xmalloc (strlen (ada_name) + 1); + strcpy (result, ada_name); + + return result; +} |