summaryrefslogtreecommitdiff
path: root/gcc/ada/adadecode.c
diff options
context:
space:
mode:
authorbosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-08 22:49:35 +0000
committerbosch <bosch@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-08 22:49:35 +0000
commitb9e214e0e1ffeece8a4baf59a1c3b0cbfbff14f8 (patch)
treee1966bb24cb5ddb58313cbf62e39a664a3776d73 /gcc/ada/adadecode.c
parent6a81282b53802d45c05cf25c1fdb6e57f24e8835 (diff)
downloadgcc-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.c325
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;
+}