summaryrefslogtreecommitdiff
path: root/libiberty/cplus-dem.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@delorie.com>2010-09-27 21:01:11 +0000
committerDJ Delorie <dj@delorie.com>2010-09-27 21:01:11 +0000
commit8bf055c94d7fe0c58e5c0fdd724d0fcce6dcf2a0 (patch)
treed0705b28f5695c9de48429f19e3f4891b00811af /libiberty/cplus-dem.c
parent8f12d6cd84773dc22d1e7b3ec36c0e8d91fcd188 (diff)
downloadgdb-8bf055c94d7fe0c58e5c0fdd724d0fcce6dcf2a0.tar.gz
merge from gcc
Diffstat (limited to 'libiberty/cplus-dem.c')
-rw-r--r--libiberty/cplus-dem.c200
1 files changed, 137 insertions, 63 deletions
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index f20a5ef9d84..0d812d5ef83 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -895,18 +895,20 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
/* 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;
+ replaced by '.', they eventually never expand the size.
+ A few special names such as '___elabs' add a few chars (at most 7), but
+ they occur only once. */
+ len0 = strlen (mangled) + 7 + 1;
demangled = XNEWVEC (char, len0);
d = demangled;
p = mangled;
while (1)
{
- /* Convert name, which is always lower-case. */
+ /* An entity names is expected. */
if (ISLOWER (*p))
{
+ /* An identifier, which is always lower case. */
do
*d++ = *p++;
while (ISLOWER(*p) || ISDIGIT (*p)
@@ -914,6 +916,7 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
}
else if (p[0] == 'O')
{
+ /* An operator name. */
static const char * const operators[][2] =
{{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"},
{"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"},
@@ -924,22 +927,22 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{"Oexpon", "**"}, {NULL, NULL}};
int k;
- for (k = 0; operators[k][0]; k++)
+ for (k = 0; operators[k][0] != NULL; k++)
{
- int l = strlen (operators[k][0]);
- if (!strncmp (p, operators[k][0], l))
+ size_t slen = strlen (operators[k][0]);
+ if (strncmp (p, operators[k][0], slen) == 0)
{
- p += l;
- l = strlen (operators[k][1]);
+ p += slen;
+ slen = strlen (operators[k][1]);
*d++ = '"';
- memcpy (d, operators[k][1], l);
- d += l;
+ memcpy (d, operators[k][1], slen);
+ d += slen;
*d++ = '"';
break;
}
}
/* Operator not found. */
- if (!operators[k][0])
+ if (operators[k][0] == NULL)
goto unknown;
}
else
@@ -948,6 +951,92 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
goto unknown;
}
+ /* The name can be directly followed by some uppercase letters. */
+ if (p[0] == 'T' && p[1] == 'K')
+ {
+ /* Task stuff. */
+ 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] == 'E' && p[1] == 0)
+ {
+ /* Exception name. */
+ goto unknown;
+ }
+ if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0)
+ {
+ /* Protected type subprogram. */
+ break;
+ }
+ if ((*p == 'N' || *p == 'S') && p[1] == 0)
+ {
+ /* Enumerated type name table. */
+ goto unknown;
+ }
+ if (p[0] == 'X')
+ {
+ /* Body nested. */
+ p++;
+ while (p[0] == 'n' || p[0] == 'b')
+ p++;
+ }
+ if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0))
+ {
+ /* Stream operations. */
+ const char *name;
+ switch (p[1])
+ {
+ case 'R':
+ name = "'Read";
+ break;
+ case 'W':
+ name = "'Write";
+ break;
+ case 'I':
+ name = "'Input";
+ break;
+ case 'O':
+ name = "'Output";
+ break;
+ default:
+ goto unknown;
+ }
+ p += 2;
+ strcpy (d, name);
+ d += strlen (name);
+ }
+ else if (p[0] == 'D')
+ {
+ /* Controlled type operation. */
+ const char *name;
+ switch (p[1])
+ {
+ case 'F':
+ name = ".Finalize";
+ break;
+ case 'A':
+ name = ".Adjust";
+ break;
+ default:
+ goto unknown;
+ }
+ strcpy (d, name);
+ d += strlen (name);
+ break;
+ }
+
if (p[0] == '_')
{
/* Separator. */
@@ -955,24 +1044,49 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
{
/* Standard separator. Handled first. */
p += 2;
+
if (ISDIGIT (*p))
{
- /* Overloading. */
+ /* Overloading number. */
do
p++;
while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1])));
+ if (*p == 'X')
+ {
+ p++;
+ while (p[0] == 'n' || p[0] == 'b')
+ p++;
+ }
}
- else if (*p == '_' && !strcmp (p + 1, "elabb"))
- {
- memcpy (d, "'Elab_Body", 10);
- d += 10;
- break;
- }
- else if (*p == '_' && !strcmp (p + 1, "elabs"))
+ else if (p[0] == '_' && p[1] != '_')
{
- memcpy (d, "'Elab_Spec", 10);
- d += 10;
- break;
+ /* Special names. */
+ static const char * const special[][2] = {
+ { "_elabb", "'Elab_Body" },
+ { "_elabs", "'Elab_Spec" },
+ { "_size", "'Size" },
+ { "_alignment", "'Alignment" },
+ { "_assign", ".\":=\"" },
+ { NULL, NULL }
+ };
+ int k;
+
+ for (k = 0; special[k][0] != NULL; k++)
+ {
+ size_t slen = strlen (special[k][0]);
+ if (strncmp (p, special[k][0], slen) == 0)
+ {
+ p += slen;
+ slen = strlen (special[k][1]);
+ memcpy (d, special[k][1], slen);
+ d += slen;
+ break;
+ }
+ }
+ if (special[k][0] != NULL)
+ break;
+ else
+ goto unknown;
}
else
{
@@ -995,46 +1109,6 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
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. */