From patchwork Wed May 18 11:25:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 54160 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CA7193856241 for ; Wed, 18 May 2022 11:27:53 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x82b.google.com (mail-qt1-x82b.google.com [IPv6:2607:f8b0:4864:20::82b]) by sourceware.org (Postfix) with ESMTPS id B3F47385625D for ; Wed, 18 May 2022 11:25:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B3F47385625D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-qt1-x82b.google.com with SMTP id g3so1304455qtb.7 for ; Wed, 18 May 2022 04:25:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:message-id:date:mime-version:user-agent:content-language:to :from:subject; bh=zXJ+jBEXZY4Pnf62Hr7/XeGKBU1FCixWsjMOawaCexY=; b=m3nO3T3Sxu2g3HRsRTZgg8u8yI+jRX4+ob/vj6LYabKQXoe4YUgEfnfVdedYBOYPnF Hr2DVW+yMDwCh6RZFxRAK59TWMfUTbRKTQ/419MrBSIxWENd/zooDsgFx/z7xuosZ+SI lBal8164CQv75kQTx5nKYeS1ZgziAHX+65fw2QU8G+6VAH/UTZHm9D5tXNGFiewPu0wH 6NoxZ6RZDK74Pdl5KBtwvYGTaX5Gop1zbwR6/FeKluzmI9GK8SjOSM9ZHmPZCb5rVJdh M+qvde4Bwjap44JmvD9kkWzJ74yrQgSlYusDwWCZ5AvsRseUMnxrPkb6YGegPMWnCAAg az5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:message-id:date:mime-version:user-agent :content-language:to:from:subject; bh=zXJ+jBEXZY4Pnf62Hr7/XeGKBU1FCixWsjMOawaCexY=; b=ldlwQjfmGmMxzBofMEAANtmHM1eRjB4LR/tUlBC5G0NY1xnJsHmjCTfG1w9k6mQZbP bfQLAUJQACxYSgqKYzmNIik/Acp3I/N+3E8y+daUiv1LfFG67+Dgt3wkQx0EsrK1wwQx tfO+ck6lJb1eSoPBcm/gVDT3jqu+D8DYeZ/yJbJ2oEMHOcoSYwd1jRX5QdA9LP6REVP+ PfZFUkwOjH+vXNPU0u3QhaMBiGzk2zIwt1BqCNDROJfOFeHJUKjakVsE3ogRxKsLqvnF 780P/iauDCwIPtaPAlS5mjzT4R59JCkb+lQz2sg4s7dmqyK8H/c5FXmTgdL5dPbcA8n7 /XaQ== X-Gm-Message-State: AOAM533uFTFyaJvMiuUpCnNtEOEgoEkuvpDg5J8Yxue8pn9X5ldoTZ/v WFj5H/Nzk15g7S1SeVym5uIU7H/zywc= X-Google-Smtp-Source: ABdhPJy5EJ5igNR9ORBmqqdj9zAFCDc4n199P9jN1URSRIs/v59zHMB/4i53kZy3eSd44QlcMqBKBg== X-Received: by 2002:a05:622a:c4:b0:2f3:e383:7386 with SMTP id p4-20020a05622a00c400b002f3e3837386mr23504104qtw.521.1652873146803; Wed, 18 May 2022 04:25:46 -0700 (PDT) Received: from ?IPV6:2620:10d:c0a3:1407:c07f:d121:e30c:4ec? ([2620:10d:c091:500::2:63e5]) by smtp.googlemail.com with ESMTPSA id 141-20020a370593000000b0069fc13ce202sm1275651qkf.51.2022.05.18.04.25.44 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 18 May 2022 04:25:44 -0700 (PDT) Message-ID: Date: Wed, 18 May 2022 07:25:43 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.2.0 Content-Language: en-US To: GCC Patches From: Nathan Sidwell Subject: demangler: Reorganize for module demangling X-Spam-Status: No, score=-3038.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Module demangling requires some changes in how substitutions are handled. This adjusts things to make that possible, these are similar changes to that made in the the llvm demangler. nathan From 65851d65fb36e847a9b8ef3b0519f06d29865a14 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 8 Mar 2022 10:53:39 -0800 Subject: [PATCH] demangler: Reorganize for module demangling Module demangling requires some changes in how substitutions are handled. This adjusts things to make that possible. libiberty/ * cp-demangle.c (d_name): Add SUBSTABLE parameter, push substitution if requested. Adjust unscoped name handling. (d_prefix): Reorder main loop. Adjust all calls. (d_unqualified_name): Add SCOPE parameter, create qualified name here. Adjust all calls. (cplus_demangle_type): Do not handle 'S' here, leave all to d_class_enum_type. (d_class_enum_type): Add SUBSTABLE parameter. --- libiberty/cp-demangle.c | 224 +++++++++++++++------------------------- 1 file changed, 84 insertions(+), 140 deletions(-) diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index fc618fa7383..cf451c5aff2 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -425,13 +425,14 @@ is_ctor_dtor_or_conversion (struct demangle_component *); static struct demangle_component *d_encoding (struct d_info *, int); -static struct demangle_component *d_name (struct d_info *); +static struct demangle_component *d_name (struct d_info *, int substable); static struct demangle_component *d_nested_name (struct d_info *); static struct demangle_component *d_prefix (struct d_info *, int); -static struct demangle_component *d_unqualified_name (struct d_info *); +static struct demangle_component *d_unqualified_name (struct d_info *, + struct demangle_component *scope); static struct demangle_component *d_source_name (struct d_info *); @@ -462,7 +463,7 @@ static struct demangle_component * d_bare_function_type (struct d_info *, int); static struct demangle_component * -d_class_enum_type (struct d_info *); +d_class_enum_type (struct d_info *, int); static struct demangle_component *d_array_type (struct d_info *); @@ -1323,7 +1324,7 @@ d_encoding (struct d_info *di, int top_level) dc = d_special_name (di); else { - dc = d_name (di); + dc = d_name (di, 0); if (!dc) /* Failed already. */; @@ -1417,80 +1418,64 @@ d_abi_tags (struct d_info *di, struct demangle_component *dc) */ static struct demangle_component * -d_name (struct d_info *di) +d_name (struct d_info *di, int substable) { char peek = d_peek_char (di); - struct demangle_component *dc; + struct demangle_component *dc = NULL; + int subst = 0; switch (peek) { case 'N': - return d_nested_name (di); + dc = d_nested_name (di); + break; case 'Z': - return d_local_name (di); + dc = d_local_name (di); + break; case 'U': - return d_unqualified_name (di); + dc = d_unqualified_name (di, NULL); + break; case 'S': { - int subst; - - if (d_peek_next_char (di) != 't') - { - dc = d_substitution (di, 0); - subst = 1; - } - else + if (d_peek_next_char (di) == 't') { d_advance (di, 2); - dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, - d_make_name (di, "std", 3), - d_unqualified_name (di)); + dc = d_make_name (di, "std", 3); di->expansion += 3; - subst = 0; - } - - if (d_peek_char (di) != 'I') - { - /* The grammar does not permit this case to occur if we - called d_substitution() above (i.e., subst == 1). We - don't bother to check. */ } else { - /* This is , which means that we just saw - , which is a substitution - candidate if we didn't just get it from a - substitution. */ - if (! subst) - { - if (! d_add_substitution (di, dc)) - return NULL; - } - dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, - d_template_args (di)); + dc = d_substitution (di, 0); + if (!dc) + return NULL; + subst = 1; } - - return dc; } + /* FALLTHROUGH */ case 'L': default: - dc = d_unqualified_name (di); + if (!subst) + dc = d_unqualified_name (di, dc); if (d_peek_char (di) == 'I') { /* This is , which means that we just saw , which is a substitution candidate. */ - if (! d_add_substitution (di, dc)) + if (!subst && !d_add_substitution (di, dc)) return NULL; dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc, d_template_args (di)); + subst = 0; } - return dc; + break; } + if (substable && !subst && !d_add_substitution (di, dc)) + return NULL; + return dc; } /* ::= N [] [] E @@ -1546,54 +1531,51 @@ d_nested_name (struct d_info *di) if not (in an unresolved-name). */ static struct demangle_component * -d_prefix (struct d_info *di, int subst) +d_prefix (struct d_info *di, int substable) { struct demangle_component *ret = NULL; - while (1) + for (;;) { - char peek; - enum demangle_component_type comb_type; - struct demangle_component *dc; - - peek = d_peek_char (di); - if (peek == '\0') - return NULL; + char peek = d_peek_char (di); /* The older code accepts a here, but I don't see that in the grammar. The older code does not accept a here. */ - comb_type = DEMANGLE_COMPONENT_QUAL_NAME; - if (peek == 'D') + if (peek == 'D' + && (d_peek_next_char (di) == 'T' + || d_peek_next_char (di) == 't')) { - char peek2 = d_peek_next_char (di); - if (peek2 == 'T' || peek2 == 't') - /* Decltype. */ - dc = cplus_demangle_type (di); - else - /* Destructor name. */ - dc = d_unqualified_name (di); + /* Decltype. */ + if (ret) + return NULL; + ret = cplus_demangle_type (di); } - else if (IS_DIGIT (peek) - || IS_LOWER (peek) - || peek == 'C' - || peek == 'U' - || peek == 'L') - dc = d_unqualified_name (di); else if (peek == 'S') - dc = d_substitution (di, 1); + { + if (ret) + return NULL; + ret = d_substitution (di, 1); + if (!ret) + return NULL; + continue; + } else if (peek == 'I') { if (ret == NULL) return NULL; - comb_type = DEMANGLE_COMPONENT_TEMPLATE; - dc = d_template_args (di); + struct demangle_component *dc = d_template_args (di); + if (!dc) + return NULL; + ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, dc); } else if (peek == 'T') - dc = d_template_param (di); - else if (peek == 'E') - return ret; + { + if (ret) + return NULL; + ret = d_template_param (di); + } else if (peek == 'M') { /* Initializer scope for a lambda. We don't need to represent @@ -1602,22 +1584,21 @@ d_prefix (struct d_info *di, int subst) if (ret == NULL) return NULL; d_advance (di, 1); - continue; } else + ret = d_unqualified_name (di, ret); + + if (!ret) + break; + + if (d_peek_char (di) == 'E') + break; + + if (substable && !d_add_substitution (di, ret)) return NULL; - - if (ret == NULL) - ret = dc; - else - ret = d_make_comp (di, comb_type, ret, dc); - - if (peek != 'S' && d_peek_char (di) != 'E' && subst) - { - if (! d_add_substitution (di, ret)) - return NULL; - } } + + return ret; } /* ::= [] @@ -1629,7 +1610,7 @@ d_prefix (struct d_info *di, int subst) */ static struct demangle_component * -d_unqualified_name (struct d_info *di) +d_unqualified_name (struct d_info *di, struct demangle_component *scope) { struct demangle_component *ret; char peek; @@ -1709,6 +1690,9 @@ d_unqualified_name (struct d_info *di) if (d_peek_char (di) == 'B') ret = d_abi_tags (di, ret); + if (scope) + ret = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, scope, ret); + return ret; } @@ -2149,11 +2133,11 @@ d_special_name (struct d_info *di) case 'H': return d_make_comp (di, DEMANGLE_COMPONENT_TLS_INIT, - d_name (di), NULL); + d_name (di, 0), NULL); case 'W': return d_make_comp (di, DEMANGLE_COMPONENT_TLS_WRAPPER, - d_name (di), NULL); + d_name (di, 0), NULL); case 'A': return d_make_comp (di, DEMANGLE_COMPONENT_TPARM_OBJ, @@ -2169,11 +2153,11 @@ d_special_name (struct d_info *di) { case 'V': return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, - d_name (di), NULL); + d_name (di, 0), NULL); case 'R': { - struct demangle_component *name = d_name (di); + struct demangle_component *name = d_name (di, 0); return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, name, d_number_component (di)); } @@ -2504,13 +2488,6 @@ cplus_demangle_type (struct d_info *di) ret = d_function_type (di); break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'N': - case 'Z': - ret = d_class_enum_type (di); - break; - case 'A': ret = d_array_type (di); break; @@ -2581,39 +2558,6 @@ cplus_demangle_type (struct d_info *di) } break; - case 'S': - /* If this is a special substitution, then it is the start of - . */ - { - char peek_next; - - peek_next = d_peek_next_char (di); - if (IS_DIGIT (peek_next) - || peek_next == '_' - || IS_UPPER (peek_next)) - { - ret = d_substitution (di, 0); - /* The substituted name may have been a template name and - may be followed by tepmlate args. */ - if (d_peek_char (di) == 'I') - ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret, - d_template_args (di)); - else - can_subst = 0; - } - else - { - ret = d_class_enum_type (di); - /* If the substitution was a complete type, then it is not - a new substitution candidate. However, if the - substitution was followed by template arguments, then - the whole thing is a substitution candidate. */ - if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD) - can_subst = 0; - } - } - break; - case 'O': d_advance (di, 1); ret = d_make_comp (di, DEMANGLE_COMPONENT_RVALUE_REFERENCE, @@ -2754,7 +2698,7 @@ cplus_demangle_type (struct d_info *di) break; default: - return NULL; + return d_class_enum_type (di, 1); } if (can_subst) @@ -3027,9 +2971,9 @@ d_bare_function_type (struct d_info *di, int has_return_type) /* ::= */ static struct demangle_component * -d_class_enum_type (struct d_info *di) +d_class_enum_type (struct d_info *di, int substable) { - return d_name (di); + return d_name (di, substable); } /* ::= A <(positive dimension) number> _ <(element) type> @@ -3358,11 +3302,11 @@ d_unresolved_name (struct d_info *di) } else type = cplus_demangle_type (di); - name = d_unqualified_name (di); + name = d_unqualified_name (di, type); if (d_peek_char (di) == 'I') name = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name, d_template_args (di)); - return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name); + return name; } /* ::= <(unary) operator-name> @@ -3431,7 +3375,7 @@ d_expression_1 (struct d_info *di) /* operator-function-id, i.e. operator+(t). */ d_advance (di, 2); - name = d_unqualified_name (di); + name = d_unqualified_name (di, NULL); if (name == NULL) return NULL; if (d_peek_char (di) == 'I') @@ -3539,7 +3483,7 @@ d_expression_1 (struct d_info *di) /* fold-expression. */ left = d_operator_name (di); else if (!strcmp (code, "di")) - left = d_unqualified_name (di); + left = d_unqualified_name (di, NULL); else left = d_expression_1 (di); if (!strcmp (code, "cl")) @@ -3557,7 +3501,7 @@ d_expression_1 (struct d_info *di) d_unqualified_name rather than d_expression_1 here for old mangled names that didn't add 'on' before operator names. */ - right = d_unqualified_name (di); + right = d_unqualified_name (di, NULL); if (d_peek_char (di) == 'I') right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, right, d_template_args (di)); @@ -3767,7 +3711,7 @@ d_local_name (struct d_info *di) return NULL; } - name = d_name (di); + name = d_name (di, 0); if (name /* Lambdas and unnamed types have internal discriminators -- 2.30.2