From patchwork Tue Sep 7 09:12:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tristan Gingold X-Patchwork-Id: 63975 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E8EB5B70CC for ; Tue, 7 Sep 2010 19:12:55 +1000 (EST) Received: (qmail 28310 invoked by alias); 7 Sep 2010 09:12:52 -0000 Received: (qmail 28300 invoked by uid 22791); 7 Sep 2010 09:12:51 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL,BAYES_20,TW_CP X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 07 Sep 2010 09:12:17 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 0FE77CB022C for ; Tue, 7 Sep 2010 11:12:15 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IspA-PQTm1QY for ; Tue, 7 Sep 2010 11:12:15 +0200 (CEST) Received: from ulanbator.act-europe.fr (ulanbator.act-europe.fr [10.10.1.67]) by mel.act-europe.fr (Postfix) with ESMTP id F1766CB01B2 for ; Tue, 7 Sep 2010 11:12:14 +0200 (CEST) Received: by ulanbator.act-europe.fr (Postfix, from userid 501) id DDCA75D440B; Tue, 7 Sep 2010 11:12:14 +0200 (CEST) Date: Tue, 7 Sep 2010 11:12:14 +0200 From: Tristan Gingold To: gcc-patches@gcc.gnu.org Subject: [Patch] Improve ada demangler Message-ID: <20100907091214.GA27991@ulanbator.act-europe.fr> Mime-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.4.2.3i X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * 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