Message ID | 20100907091214.GA27991@ulanbator.act-europe.fr |
---|---|
State | New |
Headers | show |
Ping for this libiberty patch. Thanks, Tristan. On Sep 7, 2010, at 11:12 AM, Tristan Gingold wrote: > Hi, > > this patch adds demangling of Ada stream operations and controlled type > operations. It also fixes a few corner cases that can occur within > instantiated generics. > > Ok for mainline ? > > Tristan. > > > libiberty: > 2010-09-07 Tristan Gingold <gingold@adacore.com> > > * cplus-dem.c (ada_demangle): Add comments. > Handle stream and controlled type operations. > Decoding of some uppercase letters moved before separators. > * testsuite/demangle-expected: Add tests. > > diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c > index f20a5ef..396e617 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"}, > @@ -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] && (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]; k++) > + { > + int l = strlen (special[k][0]); > + if (!strncmp (p, special[k][0], l)) > + { > + p += l; > + l = strlen (special[k][1]); > + memcpy (d, special[k][1], l); > + d += l; > + break; > + } > + } > + if (special[k][0]) > + 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. */ > diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected > index 15a0fe7..2cd5251 100644 > --- a/libiberty/testsuite/demangle-expected > +++ b/libiberty/testsuite/demangle-expected > @@ -4047,6 +4047,36 @@ prot.lock.update > --format=gnat > prot__lock__update_E6s > prot.lock.update > +# Controlled types > +--format=gnat > +gnat__sockets__sockets_library_controllerDF__2 > +gnat.sockets.sockets_library_controller.Finalize > +--format=gnat > +system__partition_interface__racw_stub_typeDA > +system.partition_interface.racw_stub_type.Adjust > +# Stream operations > +--format=gnat > +gnat__wide_wide_string_split__slice_setSR__2 > +gnat.wide_wide_string_split.slice_set'Read > +--format=gnat > +ada__real_time__timing_events__events__listSW__2Xnn > +ada.real_time.timing_events.events.list'Write > +--format=gnat > +system__finalization_root__root_controlledSI > +system.finalization_root.root_controlled'Input > +--format=gnat > +ada__finalization__limited_controlledSO__2 > +ada.finalization.limited_controlled'Output > +# Tagged types > +--format=gnat > +ada__synchronous_task_control___size__2 > +ada.synchronous_task_control'Size > +--format=gnat > +ada__real_time__timing_events__events___alignment__2Xnn > +ada.real_time.timing_events.events'Alignment > +--format=gnat > +system__finalization_root___assign__2 > +system.finalization_root.":=" > # > # Used to crash the demangler. > --format=gnu-v3
Tristan Gingold <gingold@adacore.com> writes: >> libiberty: >> 2010-09-07 Tristan Gingold <gingold@adacore.com> >> >> * cplus-dem.c (ada_demangle): Add comments. >> Handle stream and controlled type operations. >> Decoding of some uppercase letters moved before separators. >> * testsuite/demangle-expected: Add tests. >> + if (p[0] == 'S' && p[1] && (p[2] == '_' || p[2] == 0)) Write p[1] != 0 or p[1] != '\0'. >> + int l = strlen (special[k][0]); l is kind of a poor choice of variable name in this code which is littered with 1's. Consider len. Also consider changing the type to size_t. >> + if (!strncmp (p, special[k][0], l)) Write strncmp (p, special[k][0], l) != 0 rather than using ! (I know the existing code used !). >> + if (special[k][0]) Write special[k][0] != 0 or special[k][0] != '\0'. This is OK with those changes. Thanks. Ian
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index f20a5ef..396e617 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"}, @@ -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] && (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]; k++) + { + int l = strlen (special[k][0]); + if (!strncmp (p, special[k][0], l)) + { + p += l; + l = strlen (special[k][1]); + memcpy (d, special[k][1], l); + d += l; + break; + } + } + if (special[k][0]) + 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. */ diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 15a0fe7..2cd5251 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4047,6 +4047,36 @@ prot.lock.update --format=gnat prot__lock__update_E6s prot.lock.update +# Controlled types +--format=gnat +gnat__sockets__sockets_library_controllerDF__2 +gnat.sockets.sockets_library_controller.Finalize +--format=gnat +system__partition_interface__racw_stub_typeDA +system.partition_interface.racw_stub_type.Adjust +# Stream operations +--format=gnat +gnat__wide_wide_string_split__slice_setSR__2 +gnat.wide_wide_string_split.slice_set'Read +--format=gnat +ada__real_time__timing_events__events__listSW__2Xnn +ada.real_time.timing_events.events.list'Write +--format=gnat +system__finalization_root__root_controlledSI +system.finalization_root.root_controlled'Input +--format=gnat +ada__finalization__limited_controlledSO__2 +ada.finalization.limited_controlled'Output +# Tagged types +--format=gnat +ada__synchronous_task_control___size__2 +ada.synchronous_task_control'Size +--format=gnat +ada__real_time__timing_events__events___alignment__2Xnn +ada.real_time.timing_events.events'Alignment +--format=gnat +system__finalization_root___assign__2 +system.finalization_root.":=" # # Used to crash the demangler. --format=gnu-v3