From patchwork Tue Apr 6 18:18:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1462976 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=o/QEHPZl; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FFG582nvfz9sRf for ; Wed, 7 Apr 2021 04:19:22 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 80C7A3844013; Tue, 6 Apr 2021 18:19:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80C7A3844013 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1617733160; bh=wQsWietNTUjP5WJywvEjruZ2AhPtRZnCEaGVJTMneME=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=o/QEHPZluyvEWyM+uM9eIv3Dphjwzgy9JcHvXslrDL9pS1E9kgSZMRS7SkjN1SZzp +htZcrCkjtKP3J+YtBWrDUYezR1mTngMHk7snCkQXC+MEbsEZajjv0GMk/jS2HrilF dsvPC2knZ7OaLUgXzrOlzJqcVeLSiGfvtpya7C+s= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [IPv6:2001:67c:2050::465:202]) by sourceware.org (Postfix) with ESMTPS id C9E6A3857819 for ; Tue, 6 Apr 2021 18:19:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C9E6A3857819 Received: from smtp2.mailbox.org (smtp2.mailbox.org [80.241.60.241]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4FFG4w2G94zQk14; Tue, 6 Apr 2021 20:19:12 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp2.mailbox.org ([80.241.60.241]) by spamfilter06.heinlein-hosting.de (spamfilter06.heinlein-hosting.de [80.241.56.125]) (amavisd-new, port 10030) with ESMTP id eAVLDeEHLt2m; Tue, 6 Apr 2021 20:19:08 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] libiberty: d: Add support for `typeof(*null)' and function literal symbols. Date: Tue, 6 Apr 2021 20:18:51 +0200 Message-Id: <20210406181851.1668959-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: * X-Rspamd-Score: 1.33 / 15.00 / 15.00 X-Rspamd-Queue-Id: 3591317F6 X-Rspamd-UID: 96b799 X-Spam-Status: No, score=-16.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Cc: ian@airs.com Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch adds support for demangling function literals as template value parameters, as well as adding the new bottom type `typeof(*null)'. Null types were incorrectly being demangled as `none', this has been fixed to be `typeof(null)'. Bootstrapped and regression tested on x86_64-linux-gnu. OK for mainline? Regards, Iain. --- libiberty/ChangeLog: * d-demangle.c (dlang_attributes): Handle typeof(*null). (dlang_type): Likewise. Demangle 'n' as typeof(null). (dlang_identifier): Skip over fake parent manglings. (dlang_parse_arrayliteral): Add 'info' parameter. (dlang_parse_assocarray): Likewise. (dlang_parse_structlit): Likewise. (dlang_value): Likewise. Handle function literal symbols. (dlang_template_args): Pass 'info' to dlang_value. * testsuite/d-demangle-expected: Update tests. --- libiberty/d-demangle.c | 71 +++++++++++++++++++------ libiberty/testsuite/d-demangle-expected | 34 +++++++++++- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/libiberty/d-demangle.c b/libiberty/d-demangle.c index 822c7580782..a2152cc6551 100644 --- a/libiberty/d-demangle.c +++ b/libiberty/d-demangle.c @@ -191,7 +191,8 @@ static const char *dlang_function_args (string *, const char *, static const char *dlang_type (string *, const char *, struct dlang_info *); -static const char *dlang_value (string *, const char *, const char *, char); +static const char *dlang_value (string *, const char *, const char *, char, + struct dlang_info *); static const char *dlang_parse_qualified (string *, const char *, struct dlang_info *, int); @@ -573,9 +574,11 @@ dlang_attributes (string *decl, const char *mangled) case 'g': case 'h': case 'k': + case 'n': /* inout parameter is represented as 'Ng'. vector parameter is represented as 'Nh'. - return paramenter is represented as 'Nk'. + return parameter is represented as 'Nk'. + typeof(*null) parameter is represented as 'Nn'. If we see this, then we know we're really in the parameter list. Rewind and break. */ mangled--; @@ -787,6 +790,12 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info) string_append (decl, ")"); return mangled; } + else if (*mangled == 'n') /* typeof(*null) */ + { + mangled++; + string_append (decl, "typeof(*null)"); + return mangled; + } else return NULL; case 'A': /* dynamic array (T[]) */ @@ -884,7 +893,7 @@ dlang_type (string *decl, const char *mangled, struct dlang_info *info) /* Basic types */ case 'n': mangled++; - string_append (decl, "none"); + string_append (decl, "typeof(null)"); return mangled; case 'v': mangled++; @@ -1035,6 +1044,25 @@ dlang_identifier (string *decl, const char *mangled, struct dlang_info *info) && (mangled[2] == 'T' || mangled[2] == 'U')) return dlang_parse_template (decl, mangled, info, len); + /* There can be multiple different declarations in the same function that have + the same mangled name. To make the mangled names unique, a fake parent in + the form `__Sddd' is added to the symbol. */ + if (len >= 4 && mangled[0] == '_' && mangled[1] == '_' && mangled[2] == 'S') + { + const char *numptr = mangled + 3; + while (numptr < (mangled + len) && ISDIGIT (*numptr)) + numptr++; + + if (mangled + len == numptr) + { + /* Skip over the fake parent. */ + mangled += len; + return dlang_identifier (decl, mangled, info); + } + + /* else demangle it as a plain identifier. */ + } + return dlang_lname (decl, mangled, len); } @@ -1378,7 +1406,8 @@ dlang_parse_string (string *decl, const char *mangled) /* Extract the static array value from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * -dlang_parse_arrayliteral (string *decl, const char *mangled) +dlang_parse_arrayliteral (string *decl, const char *mangled, + struct dlang_info *info) { unsigned long elements; @@ -1389,7 +1418,7 @@ dlang_parse_arrayliteral (string *decl, const char *mangled) string_append (decl, "["); while (elements--) { - mangled = dlang_value (decl, mangled, NULL, '\0'); + mangled = dlang_value (decl, mangled, NULL, '\0', info); if (mangled == NULL) return NULL; @@ -1404,7 +1433,8 @@ dlang_parse_arrayliteral (string *decl, const char *mangled) /* Extract the associative array value from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * -dlang_parse_assocarray (string *decl, const char *mangled) +dlang_parse_assocarray (string *decl, const char *mangled, + struct dlang_info *info) { unsigned long elements; @@ -1415,12 +1445,12 @@ dlang_parse_assocarray (string *decl, const char *mangled) string_append (decl, "["); while (elements--) { - mangled = dlang_value (decl, mangled, NULL, '\0'); + mangled = dlang_value (decl, mangled, NULL, '\0', info); if (mangled == NULL) return NULL; string_append (decl, ":"); - mangled = dlang_value (decl, mangled, NULL, '\0'); + mangled = dlang_value (decl, mangled, NULL, '\0', info); if (mangled == NULL) return NULL; @@ -1435,7 +1465,8 @@ dlang_parse_assocarray (string *decl, const char *mangled) /* Extract the struct literal value for NAME from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * -dlang_parse_structlit (string *decl, const char *mangled, const char *name) +dlang_parse_structlit (string *decl, const char *mangled, const char *name, + struct dlang_info *info) { unsigned long args; @@ -1449,7 +1480,7 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name) string_append (decl, "("); while (args--) { - mangled = dlang_value (decl, mangled, NULL, '\0'); + mangled = dlang_value (decl, mangled, NULL, '\0', info); if (mangled == NULL) return NULL; @@ -1464,7 +1495,8 @@ dlang_parse_structlit (string *decl, const char *mangled, const char *name) /* Extract the value from MANGLED and append it to DECL. Return the remaining string on success or NULL on failure. */ static const char * -dlang_value (string *decl, const char *mangled, const char *name, char type) +dlang_value (string *decl, const char *mangled, const char *name, char type, + struct dlang_info *info) { if (mangled == NULL || *mangled == '\0') return NULL; @@ -1525,15 +1557,24 @@ dlang_value (string *decl, const char *mangled, const char *name, char type) case 'A': mangled++; if (type == 'H') - mangled = dlang_parse_assocarray (decl, mangled); + mangled = dlang_parse_assocarray (decl, mangled, info); else - mangled = dlang_parse_arrayliteral (decl, mangled); + mangled = dlang_parse_arrayliteral (decl, mangled, info); break; /* Struct values. */ case 'S': mangled++; - mangled = dlang_parse_structlit (decl, mangled, name); + mangled = dlang_parse_structlit (decl, mangled, name, info); + break; + + /* Function literal symbol. */ + case 'f': + mangled++; + if (strncmp (mangled, "_D", 2) != 0 + || !dlang_symbol_name_p (mangled + 2, info)) + return NULL; + mangled = dlang_parse_mangle (decl, mangled, info); break; default: @@ -1806,7 +1847,7 @@ dlang_template_args (string *decl, const char *mangled, struct dlang_info *info) string_need (&name, 1); *(name.p) = '\0'; - mangled = dlang_value (decl, mangled, name.b, type); + mangled = dlang_value (decl, mangled, name.b, type, info); string_delete (&name); break; } diff --git a/libiberty/testsuite/d-demangle-expected b/libiberty/testsuite/d-demangle-expected index ba0ffed5c8d..c35185c3e1e 100644 --- a/libiberty/testsuite/d-demangle-expected +++ b/libiberty/testsuite/d-demangle-expected @@ -83,7 +83,11 @@ demangle.test(ulong) # --format=dlang _D8demangle4testFnZv -demangle.test(none) +demangle.test(typeof(null)) +# +--format=dlang +_D8demangle4testFNnZv +demangle.test(typeof(*null)) # --format=dlang _D8demangle4testFoZv @@ -1414,3 +1418,31 @@ std.algorithm.iteration.FilterResult!(std.typecons.Tuple!(int, "a", int, "b", in --format=dlang _D3std3uni__T6toCaseS_DQvQt12toLowerIndexFNaNbNiNewZtVii1043S_DQCjQCi10toLowerTabFNaNbNiNemZwSQDo5ascii7toLowerTAyaZQDzFNaNeQmZ14__foreachbody2MFNaNeKmKwZ14__foreachbody3MFNaNeKwZi std.uni.toCase!(std.uni.toLowerIndex(dchar), 1043, std.uni.toLowerTab(ulong), std.ascii.toLower, immutable(char)[]).toCase(immutable(char)[]).__foreachbody2(ref ulong, ref dchar).__foreachbody3(ref dchar) +# +--format=dlang +_D8demangle4mainFZ1xi +demangle.main().x +# +--format=dlang +_D8demangle4mainFZ4__S11xi +demangle.main().x +# +--format=dlang +_D8demangle4mainFZ1fMFNaNbNiNfZv +demangle.main().f() +# +--format=dlang +_D8demangle4mainFZ4__S11fMFNaNbNiNfZv +demangle.main().f() +# +--format=dlang +_D3mod4funcFZ__T6nestedTiZQkMFNaNbNiNfZi +mod.func().nested!(int).nested() +# +--format=dlang +_D3mod4funcFZ__T6nestedTiZ4__S1QpMFNaNbNiNfZi +mod.func().nested!(int).nested() +# +--format=dlang +_D6mangle__T8fun21753VSQv6S21753S1f_DQBj10__lambda71MFNaNbNiNfZvZQCbQp +mangle.fun21753!(mangle.S21753(mangle.__lambda71())).fun21753