summaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorgingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-11 11:38:35 +0000
committergingold <gingold@138bc75d-0d04-0410-961f-82ee72b054a4>2010-01-11 11:38:35 +0000
commit10650b19f7bae9a64a61cb17471f68b5db78df5e (patch)
treee9141376caf9e1df607447776b1ab61a3d73fcbd /libiberty
parent5846e92cf1fb406d1c6457d369ac7f278c4f3ffa (diff)
downloadgcc-10650b19f7bae9a64a61cb17471f68b5db78df5e.tar.gz
include/
2010-01-11 Tristan Gingold <gingold@adacore.com> * demangle.h (ada_demangle): Add prototype. libiberty/ 2010-01-11 Tristan Gingold <gingold@adacore.com> * cplus-dem.c (ada_demangle): Remove prototype. (grow_vect): Removed. (ada_demangle): Rewritten. (cplus_demangle): Fix indentation. * testsuite/demangle-expected: Add tests for Ada. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155804 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog8
-rw-r--r--libiberty/cplus-dem.c277
-rw-r--r--libiberty/testsuite/demangle-expected95
3 files changed, 272 insertions, 108 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index effb327ea22..6d30823569a 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,11 @@
+2010-01-11 Tristan Gingold <gingold@adacore.com>
+
+ * cplus-dem.c (ada_demangle): Remove prototype.
+ (grow_vect): Removed.
+ (ada_demangle): Rewritten.
+ (cplus_demangle): Fix indentation.
+ * testsuite/demangle-expected: Add tests for Ada.
+
2010-01-09 Ian Lance Taylor <iant@google.com>
PR other/42230
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 66285141ffa..f20a5ef9d84 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -62,8 +62,6 @@ void * realloc ();
#include "libiberty.h"
-static char *ada_demangle (const char *, int);
-
#define min(X,Y) (((X) < (Y)) ? (X) : (Y))
/* A value at least one greater than the maximum number of characters
@@ -478,8 +476,6 @@ demangle_arm_hp_template (struct work_stuff *, const char **, int, string *);
static void
recursively_demangle (struct work_stuff *, const char **, string *, int);
-static void grow_vect (char **, size_t *, size_t, int);
-
/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.
@@ -872,129 +868,194 @@ cplus_demangle (const char *mangled, int options)
}
if (GNAT_DEMANGLING)
- return ada_demangle(mangled,options);
+ return ada_demangle (mangled, options);
ret = internal_cplus_demangle (work, mangled);
squangle_mop_up (work);
return (ret);
}
+/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
-/* Assuming *OLD_VECT points to an array of *SIZE objects of size
- ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
- updating *OLD_VECT and *SIZE as necessary. */
-
-static void
-grow_vect (char **old_vect, size_t *size, size_t min_size, int element_size)
-{
- if (*size < min_size)
- {
- *size *= 2;
- if (*size < min_size)
- *size = min_size;
- *old_vect = XRESIZEVAR (char, *old_vect, *size * element_size);
- }
-}
-
-/* Demangle ada names:
- 1. Discard final __{DIGIT}+ or ${DIGIT}+
- 2. Convert other instances of embedded "__" to `.'.
- 3. Discard leading _ada_.
- 4. Remove everything after first ___ if it is followed by 'X'.
- 5. Put symbols that should be suppressed in <...> brackets.
- The resulting string is valid until the next call of ada_demangle. */
-
-static char *
+char *
ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
- int i, j;
int len0;
const char* p;
- char *demangled = NULL;
- int changed;
- size_t demangled_size = 0;
+ char *d;
+ char *demangled;
- changed = 0;
-
+ /* Discard leading _ada_, which is used for library level subprograms. */
if (strncmp (mangled, "_ada_", 5) == 0)
- {
- mangled += 5;
- changed = 1;
- }
-
- if (mangled[0] == '_' || mangled[0] == '<')
- goto Suppress;
+ mangled += 5;
+
+ /* All ada unit names are lower-case. */
+ if (!ISLOWER (mangled[0]))
+ goto unknown;
+
+ /* Most of the demangling will trivially remove chars. Operator names
+ may add one char but because they are always preceeded by '__' which is
+ replaced by '.', they eventually never expand the size. '___elabs' and
+ '___elabb' add only 2 chars, but they occur only once. */
+ len0 = strlen (mangled) + 2 + 1;
+ demangled = XNEWVEC (char, len0);
- p = strstr (mangled, "___");
- if (p == NULL)
- len0 = strlen (mangled);
- else
+ d = demangled;
+ p = mangled;
+ while (1)
{
- if (p[3] == 'X')
- {
- len0 = p - mangled;
- changed = 1;
- }
+ /* Convert name, which is always lower-case. */
+ if (ISLOWER (*p))
+ {
+ do
+ *d++ = *p++;
+ while (ISLOWER(*p) || ISDIGIT (*p)
+ || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1]))));
+ }
+ else if (p[0] == 'O')
+ {
+ static const char * const operators[][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;
+
+ for (k = 0; operators[k][0]; k++)
+ {
+ int l = strlen (operators[k][0]);
+ if (!strncmp (p, operators[k][0], l))
+ {
+ p += l;
+ l = strlen (operators[k][1]);
+ *d++ = '"';
+ memcpy (d, operators[k][1], l);
+ d += l;
+ *d++ = '"';
+ break;
+ }
+ }
+ /* Operator not found. */
+ if (!operators[k][0])
+ goto unknown;
+ }
else
- goto Suppress;
- }
-
- /* Make demangled big enough for possible expansion by operator name. */
- grow_vect (&demangled,
- &demangled_size, 2 * len0 + 1,
- sizeof (char));
-
- if (ISDIGIT ((unsigned char) mangled[len0 - 1])) {
- for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1)
- ;
- if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_')
- {
- len0 = i - 1;
- changed = 1;
- }
- else if (mangled[i] == '$')
- {
- len0 = i;
- changed = 1;
- }
- }
-
- for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]);
- i += 1, j += 1)
- demangled[j] = mangled[i];
-
- while (i < len0)
- {
- if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_')
- {
- demangled[j] = '.';
- changed = 1;
- i += 2; j += 1;
- }
+ {
+ /* Not a GNAT encoding. */
+ goto unknown;
+ }
+
+ if (p[0] == '_')
+ {
+ /* Separator. */
+ if (p[1] == '_')
+ {
+ /* Standard separator. Handled first. */
+ p += 2;
+ if (ISDIGIT (*p))
+ {
+ /* Overloading. */
+ do
+ p++;
+ while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
+ }
+ else if (*p == '_' && !strcmp (p + 1, "elabb"))
+ {
+ memcpy (d, "'Elab_Body", 10);
+ d += 10;
+ break;
+ }
+ else if (*p == '_' && !strcmp (p + 1, "elabs"))
+ {
+ memcpy (d, "'Elab_Spec", 10);
+ d += 10;
+ break;
+ }
+ else
+ {
+ *d++ = '.';
+ continue;
+ }
+ }
+ else if (p[1] == 'B' || p[1] == 'E')
+ {
+ /* Entry Body or barrier Evaluation. */
+ p += 2;
+ while (ISDIGIT (*p))
+ p++;
+ if (p[0] == 's' && p[1] == 0)
+ break;
+ else
+ goto unknown;
+ }
+ else
+ goto unknown;
+ }
+
+ if (p[0] == 'T' && p[1] == 'K')
+ {
+ if (p[2] == 'B' && p[3] == 0)
+ {
+ /* Subprogram for task body. */
+ break;
+ }
+ else if (p[2] == '_' && p[3] == '_')
+ {
+ /* Inner declarations in a task. */
+ p += 4;
+ *d++ = '.';
+ continue;
+ }
+ else
+ goto unknown;
+ }
+ if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
+ {
+ /* Protected type subprogram. */
+ break;
+ }
+ if (p[0] == 'E' && p[1] == 0)
+ {
+ /* Exception name. */
+ goto unknown;
+ }
+ if (*p == 'N' || *p == 'S')
+ {
+ /* Enumerated type name table. */
+ goto unknown;
+ }
+ if (p[0] == 'X')
+ {
+ /* Body nested. */
+ if (p[1] == 'n' || p[1] == 'b')
+ p += 2;
+ else if (p[1] == 0)
+ p++;
+ }
+ if (p[0] == '.' && ISDIGIT (p[1]))
+ {
+ /* Nested subprogram. */
+ p += 2;
+ while (ISDIGIT (*p))
+ p++;
+ }
+ if (*p == 0)
+ {
+ /* End of mangled name. */
+ break;
+ }
else
- {
- demangled[j] = mangled[i];
- i += 1; j += 1;
- }
+ goto unknown;
}
- demangled[j] = '\000';
-
- for (i = 0; demangled[i] != '\0'; i += 1)
- if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ')
- goto Suppress;
+ *d = 0;
+ return demangled;
- if (! changed)
- {
- free (demangled);
- return NULL;
- }
- else
- return demangled;
-
- Suppress:
- grow_vect (&demangled,
- &demangled_size, strlen (mangled) + 3,
- sizeof (char));
+ unknown:
+ len0 = strlen (mangled);
+ demangled = XNEWVEC (char, len0 + 3);
if (mangled[0] == '<')
strcpy (demangled, mangled);
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 6798154d2f3..c201a983271 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3926,3 +3926,98 @@ S<int>::x::{lambda()#3}::operator()() const
--format=gnu-v3
_Z1fN1SUt_E
f(S::{unnamed type#1})
+#
+# Ada (GNAT) tests.
+#
+# Simple test.
+--format=gnat
+yz__qrs
+yz.qrs
+# Operator
+--format=gnat
+oper__Oadd
+oper."+"
+# Overloaded subprogram.
+--format=gnat
+yz__qrs__2
+yz.qrs
+# Nested subprogram.
+--format=gnat
+yz__qrs__tuv.1661
+yz.qrs.tuv
+# Nested and overloaded subprograms.
+--format=gnat
+yz__qrs__tuv__2_1.1667
+yz.qrs.tuv
+--format=gnat
+yz__qrs__tuv__2_2.1670
+yz.qrs.tuv
+--format=gnat
+yz__qrs__tuv__2_3.1674
+yz.qrs.tuv
+# Elaborated flag (not demangled)
+--format=gnat
+x_E
+<x_E>
+# Nested package
+--format=gnat
+x__m1
+x.m1
+--format=gnat
+x__m3
+x.m3
+--format=gnat
+x__y__m2X
+x.y.m2
+--format=gnat
+x__y__z__rXb
+x.y.z.r
+# Child package
+--format=gnat
+x__y__j
+x.y.j
+# Library level
+--format=gnat
+_ada_x__m3
+x.m3
+# Package body elaborator
+--format=gnat
+p___elabb
+p'Elab_Body
+# Package spec elaborator
+--format=gnat
+p___elabs
+p'Elab_Spec
+# Task body
+--format=gnat
+p__taskobjTKB
+p.taskobj
+# Task subprogram
+--format=gnat
+p__taskobjTK__f1.2330
+p.taskobj.f1
+# Protected types subprograms
+--format=gnat
+prot__lock__getN
+prot.lock.get
+--format=gnat
+prot__lock__getP
+prot.lock.get
+--format=gnat
+prot__lock__get__sub.2590
+prot.lock.get.sub
+--format=gnat
+prot__lock__setN
+prot.lock.set
+--format=gnat
+prot__lock__setP
+prot.lock.set
+# Protected type entries
+--format=gnat
+prot__lock__update_B7s
+prot.lock.update
+--format=gnat
+prot__lock__update_E6s
+prot.lock.update
+
+