From patchwork Wed May 13 08:51:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 471758 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 888E7140758 for ; Wed, 13 May 2015 18:51:48 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=iuPfA0R8; 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=dexJiVlIaoM2M/OfXlbZN9MifRs2axYWgsczYQDccFTLe4 pVDDVzR11bNjy3N//vvgdE1TPXdaYdvOQgLBQFb+G6YStM+1hkPw8v3t8mYGPvX0 f7tPiSB4ylHpiO8ed8xcV6pjBAcVyl44C9i0LNMg7CG/h3bOk01BBJFuYD19A= 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=FQxxOxqodIC+hHglkLaMCwneArE=; b=iuPfA0R81GR9DL3FFroB elHzInd0UjJJBQZ3TdAiK0AlzfPPYMsR5F8evUvgpwf6ALcTxRPNcJjb8ofGdG2r S6J+tcps3b8U4XcY6T7OPuoYGDajG2ZRzWc1XVbSvMx0e1d1GtVScrrcSRlaQNUs 3vklwgoxnP8mQig9STa/scs= Received: (qmail 118976 invoked by alias); 13 May 2015 08:51:23 -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 117963 invoked by uid 89); 13 May 2015 08:51:21 -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-qk0-f176.google.com Received: from mail-qk0-f176.google.com (HELO mail-qk0-f176.google.com) (209.85.220.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 13 May 2015 08:51:20 +0000 Received: by qkgy4 with SMTP id y4so23553177qkg.2 for ; Wed, 13 May 2015 01:51:18 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.55.25.42 with SMTP id k42mr39593783qkh.66.1431507078137; Wed, 13 May 2015 01:51:18 -0700 (PDT) Received: by 10.229.215.4 with HTTP; Wed, 13 May 2015 01:51:18 -0700 (PDT) Date: Wed, 13 May 2015 10:51:18 +0200 Message-ID: Subject: [PATCH 3/7] [D] libiberty: Include type modifiers in demangled function symbols From: Iain Buclaw To: gcc-patches , Ian Lance Taylor X-IsSubscribed: yes 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-13 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_type): Handle and emit the type modifier after delegate types. (dlang_parse_symbol): Handle and emit the type modifier after the symbol. * testsuite/d-demangle-expected: Add coverage tests for all valid usages of function symbols with type modifiers. From 6836ff778e26dd0312d4d33a0570d979ba59a4ca Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 11 May 2015 09:20:55 +0200 Subject: [PATCH 3/7] D demangle: Include type modifiers in demangled function symbols --- libiberty/d-demangle.c | 111 ++++++++++++++++++++++++++++---- libiberty/testsuite/d-demangle-expected | 32 +++++++++ 2 files changed, 130 insertions(+), 13 deletions(-) diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index 91c6d55..bfad5bb 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -215,6 +215,44 @@ dlang_call_convention (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 NULL; + + 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; + } +} + /* Demangle the D function attributes from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * @@ -476,10 +514,22 @@ dlang_type (string *decl, const char *mangled) mangled++; return dlang_parse_symbol (decl, mangled); case 'D': /* delegate T */ + { + string mods; + size_t szmods; mangled++; + + string_init (&mods); + mangled = dlang_type_modifiers (&mods, mangled); + szmods = string_length (&mods); + mangled = dlang_function_type (decl, mangled); string_append (decl, "delegate"); + string_appendn (decl, mods.b, szmods); + + string_delete (&mods); return mangled; + } case 'B': /* tuple T */ mangled++; return dlang_parse_tuple (decl, mangled); @@ -1135,28 +1185,54 @@ 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_call_convention_p (const char *mangled) +dlang_type_modifier_p (const char *mangled) { - size_t i; + int i; switch (*mangled) { - case 'F': case 'U': case 'V': - case 'W': case 'R': + case 'x': case 'y': return 1; - case 'M': /* Prefix for functions needing 'this' */ - i = 1; - if (mangled[i] == 'x') - i++; + case 'O': + mangled++; + i = dlang_type_modifier_p (mangled); + return i + 1; - switch (mangled[i]) + case 'N': + mangled++; + if (*mangled == 'g') { - case 'F': case 'U': case 'V': - case 'W': case 'R': - return 1; + mangled++; + i = dlang_type_modifier_p (mangled); + return i + 2; } + } + + 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) +{ + /* Prefix for functions needing 'this' */ + if (*mangled == 'M') + { + mangled++; + /* Also skip over any type modifiers. */ + mangled += dlang_type_modifier_p (mangled); + } + + switch (*mangled) + { + case 'F': case 'U': case 'V': + case 'W': case 'R': + return 1; default: return 0; @@ -1178,11 +1254,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); @@ -1201,6 +1282,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 b023f6d..e08c989 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 -- 2.1.0