From patchwork Sat May 9 18:27:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 470365 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 2438E140281 for ; Sun, 10 May 2015 04:27:18 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=dxiLodKw; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:content-type; q= dns; s=default; b=orIi+/R3MsGPnVhWCd9WiyIwcwfY8dHuFtp6QERS+A6SHW Y/HsTtvPIf/nFzCf6/CI1I3w/09qiHwSSV2q/QgVxZ6TXMVVAkLf6FIB5Nn2/bMQ kz+C5/rfCVGOWGS7w0WcrOo7iqeqQDPYXpT2Tr8AOxcGR5Iz5Q2kVx+GifFa0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:content-type; s= default; bh=O/yT7PaVKOmQDR4WOexThYiiH0I=; b=dxiLodKw47ORHvRvXcJk 6sDCT7+hDMrtR/LVUuiDm8iOddTAoWEBcHvLIX5z3sOYetwVPD+eBgtzZKknQMqO rFwSiHGD5sNBreGauXKF2vhzLri0XqRGGiJ6YLsZW3sIoqpBhd6BQ+YsnooH/Rhu CaqcLvOFpEqE0ElqKfewdh0= Received: (qmail 114373 invoked by alias); 9 May 2015 18:27:10 -0000 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 Received: (qmail 114358 invoked by uid 89); 9 May 2015 18:27:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qc0-f177.google.com Received: from mail-qc0-f177.google.com (HELO mail-qc0-f177.google.com) (209.85.216.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sat, 09 May 2015 18:27:07 +0000 Received: by qcyk17 with SMTP id k17so51826961qcy.1 for ; Sat, 09 May 2015 11:27:03 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.140.151.212 with SMTP id 203mr4908033qhx.8.1431196023863; Sat, 09 May 2015 11:27:03 -0700 (PDT) Received: by 10.229.215.4 with HTTP; Sat, 9 May 2015 11:27:03 -0700 (PDT) Date: Sat, 9 May 2015 20:27:03 +0200 Message-ID: Subject: [PATCH] D demangle: Include type modifiers in demangled function symbols From: Iain Buclaw To: gcc-patches Like C++ const and volatile, in D mangled symbols can exist modifiers that represent the const, immutable, inout and shared-ness of the 'this' parameter. This information should be written out in the demangled symbol to show that each variant has a unique identity. --- libiberty/ChangeLog: 2015-05-09 Iain Buclaw * d-demangle.c (dlang_type_modifiers): New function. (dlang_type_modifier_p): New function. (dlang_call_convention_p): Ignore any kind of type modifier. (dlang_parse_symbol): Emit the type modifier after the symbol. * testsuite/d-demangle-expected: Add coverage tests for all valid usages of functions symbols with type modifiers. --- diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index bb481c0..9e6c46f 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -692,6 +692,44 @@ dlang_identifier (string *decl, const char *mangled) return mangled; } +/* Extract the type modifiers from MANGLED and append them to DECL. + Returns the remaining signature on success or NULL on failure. */ +static const char * +dlang_type_modifiers (string *decl, const char *mangled) +{ + if (mangled == NULL || *mangled == '\0') + return mangled; + + switch (*mangled) + { + case 'x': /* const */ + mangled++; + string_append (decl, " const"); + return mangled; + case 'y': /* immutable */ + mangled++; + string_append (decl, " immutable"); + return mangled; + case 'O': /* shared */ + mangled++; + string_append (decl, " shared"); + return dlang_type_modifiers (decl, mangled); + case 'N': + mangled++; + if (*mangled == 'g') /* wild */ + { + mangled++; + string_append (decl, " inout"); + return dlang_type_modifiers (decl, mangled); + } + else + return NULL; + + default: + return mangled; + } +} + /* Extract the integer value from MANGLED and append it to DECL, where TYPE is the type it should be represented as. Return the remaining string on success or NULL on failure. */ @@ -1104,6 +1142,41 @@ dlang_value (string *decl, const char *mangled, const char *name, char type) return mangled; } +/* Extract the type modifiers from MANGLED and return the string + length that it consumes in MANGLED on success or 0 on failure. */ +static int +dlang_type_modifier_p (const char *mangled) +{ + int i; + + switch (*mangled) + { + case 'x': case 'y': + return 1; + + case 'O': + mangled++; + i = dlang_type_modifier_p (mangled); + return i + 1; + + case 'N': + mangled++; + if (*mangled == 'g') + { + mangled++; + i = dlang_type_modifier_p (mangled); + return i + 2; + } + + default: + break; + } + + return 0; +} + +/* Extract the function calling convention from MANGLED and + return 1 on success or 0 on failure. */ static int dlang_call_convention_p (const char *mangled) { @@ -1116,9 +1189,9 @@ dlang_call_convention_p (const char *mangled) return 1; case 'M': /* Prefix for functions needing 'this' */ - i = 1; - if (mangled[i] == 'x') - i++; + mangled++; + /* Skip over any type modifiers. */ + i = dlang_type_modifier_p (mangled); switch (mangled[i]) { @@ -1147,11 +1220,16 @@ dlang_parse_symbol (string *decl, const char *mangled) if (mangled && dlang_call_convention_p (mangled)) { + string mods; int saved; /* Skip over 'this' parameter. */ if (*mangled == 'M') - mangled += (mangled[1] == 'x') ? 2 : 1; + mangled++; + + /* Save the type modifiers for appending at the end. */ + string_init (&mods); + mangled = dlang_type_modifiers (&mods, mangled); /* Skip over calling convention and attributes in qualified name. */ saved = string_length (decl); @@ -1170,6 +1248,10 @@ dlang_parse_symbol (string *decl, const char *mangled) mangled = dlang_type (decl, mangled); string_setlength (decl, saved); } + + /* Add any const/immutable/shared modifier. */ + string_appendn (decl, mods.b, string_length (&mods)); + string_delete (&mods); } } while (mangled && ISDIGIT (*mangled)); diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index 2aeacb8..358372a 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -753,6 +753,38 @@ demangle.test!(demangle.S(1, 2)) _D8demangle35__T4testVS8demangle1SS2i1a3_616263Zv demangle.test!(demangle.S(1, "abc")) # +--format=dlang +_D8demangle4testMxFZv +demangle.test() const +# +--format=dlang +_D8demangle4testMyFZv +demangle.test() immutable +# +--format=dlang +_D8demangle4testMNgFZv +demangle.test() inout +# +--format=dlang +_D8demangle4testMNgxFZv +demangle.test() inout const +# +--format=dlang +_D8demangle4testMOFZv +demangle.test() shared +# +--format=dlang +_D8demangle4testMOxFZv +demangle.test() shared const +# +--format=dlang +_D8demangle4testMONgFZv +demangle.test() shared inout +# +--format=dlang +_D8demangle4testMONgxFZv +demangle.test() shared inout const +# # Unittests # --format=dlang