From patchwork Tue Jun 4 15:13:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1109970 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502312-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.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 45JFmr40j1z9s3l for ; Wed, 5 Jun 2019 01:13:28 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=Jygar6XCQJsqcTxBIvPOr0AHKoTvZ7GbkBYWGiA5Y9KaH2FPgQ 8WoiUCWkTr7EiZ41GZM8SEsNTqZuOVetebancgSoHzoPpuxPbR360ylZj2Zbm73g Dp5En+3MHisZAE4C3Z67p7imhfdUn3i39+Xr8gZ3fL33HnRPeLFKe3n1Q= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=A6InCiRnKO52oPoUosgRMaVDOXc=; b=gK+zuh1RbVsXPHRr3BQM ktYxOqcRJLMaQFl2xH2F1E7GanULZM2oqBzj/yJnKcgu71LdE5DTc7LzwXRIyui6 KPplE4uleOoCJlb6xzU6BDUHgwCsrkE+M+AFbvntNqCPmRRklGpz8SW/MPMbazr1 THYnheYbBPuX/wUvpXjtQsc= Received: (qmail 30997 invoked by alias); 4 Jun 2019 15:13:21 -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 30985 invoked by uid 89); 4 Jun 2019 15:13:20 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=wandering, H*r:sk:mail-pf, HX-Spam-Relays-External:sk:mail-pf, HX-HELO:sk:mail-pf X-HELO: mail-pf1-f172.google.com Received: from mail-pf1-f172.google.com (HELO mail-pf1-f172.google.com) (209.85.210.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 04 Jun 2019 15:13:19 +0000 Received: by mail-pf1-f172.google.com with SMTP id i189so876989pfg.10 for ; Tue, 04 Jun 2019 08:13:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=ZqEHIm4dbfAHpDs5yqzwZ3aVAjzV1CGkjHRfCs5+vZA=; b=eQ1+G6mvwdyvvd5BnYRDHkEsFu9DnB5SoT2ek+2H9F5ErrrGgfNk9RiJWCAMBG8aNj RIfbbU/oMqrzuCKyTF7WoOZcG724Cc0yd/2CNIEUH7NrVhcvMyX01k1M/BzXgLejkkAx YcgN+OpGgzFICtyKMrjfVoat5OrxgX7Bp2BhKSqUKrthACf5yPm7ws9sFHoPOIg6zu1x UOcXuSXAOYD3Kc+toF2zOfu68nvjc1pcAcfMs0/Run0WMFdy06ptPq5zAhsjmS4GA9jJ IloeW7UM6OOR89ZI+noxmQIYq7VHIF5n8+T6ZzryZFQzEGynNAkgBpJueqN6unYlqQEd cZww== Received: from ?IPv6:2620:10d:c0a3:1407:c411:df86:c8ab:13c8? ([2620:10d:c091:500::980e]) by smtp.googlemail.com with ESMTPSA id k22sm9032280pfa.87.2019.06.04.08.13.16 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Tue, 04 Jun 2019 08:13:16 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] structure tag lookup. Message-ID: <8cd2bcd7-3c2c-32d6-e3df-ead95b2403a5@acm.org> Date: Tue, 4 Jun 2019 11:13:14 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 lookup of a structure tag, via xref tag, is rather confused, and I found myself wandering into that code. We lookup a tag on the binding scopes, then if that fails we try the innermost enclosing namespace. /Then/ we see if we were allowed to look at the scope we found something in. I've reimplemented this so we stop looking when we reach a scope we're not to look in. It also neatly separates the local binding-scope chain walking from the namespace lookup, which is the goal I had. applying to trunk. nathan 2019-06-04 Nathan Sidwell * name-lookup.c (lookup_type_scope_1): Reimplement, handle local and namespace scopes separately. Index: gcc/cp/name-lookup.c =================================================================== --- gcc/cp/name-lookup.c (revision 271906) +++ gcc/cp/name-lookup.c (working copy) @@ -6461,79 +6461,64 @@ static tree lookup_type_scope_1 (tree name, tag_scope scope) { - cxx_binding *iter = NULL; - tree val = NULL_TREE; - cp_binding_level *level = NULL; - - /* Look in non-namespace scope first. */ - if (current_binding_level->kind != sk_namespace) - iter = outer_binding (name, NULL, /*class_p=*/ true); - for (; iter; iter = outer_binding (name, iter, /*class_p=*/ true)) - { - /* Check if this is the kind of thing we're looking for. - If SCOPE is TS_CURRENT, also make sure it doesn't come from - base class. For ITER->VALUE, we can simply use - INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to use - our own check. - - We check ITER->TYPE before ITER->VALUE in order to handle - typedef struct C {} C; - correctly. */ - - if (qualify_lookup (iter->type, LOOKUP_PREFER_TYPES) - && (scope != ts_current - || LOCAL_BINDING_P (iter) - || DECL_CONTEXT (iter->type) == iter->scope->this_entity)) - val = iter->type; - else if ((scope != ts_current - || !INHERITED_VALUE_BINDING_P (iter)) - && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES)) - val = iter->value; - - if (val) - break; - } - - /* Look in namespace scope. */ - if (val) - level = iter->scope; - else - { - tree ns = current_decl_namespace (); - - if (tree *slot = find_namespace_slot (ns, name)) - { - /* If this is the kind of thing we're looking for, we're done. */ - if (tree type = MAYBE_STAT_TYPE (*slot)) - if (qualify_lookup (type, LOOKUP_PREFER_TYPES)) - val = type; - if (!val) - { - if (tree decl = MAYBE_STAT_DECL (*slot)) - if (qualify_lookup (decl, LOOKUP_PREFER_TYPES)) - val = decl; - } - level = NAMESPACE_LEVEL (ns); - } - } + cp_binding_level *b = current_binding_level; - /* Type found, check if it is in the allowed scopes, ignoring cleanup - and template parameter scopes. */ - if (val) + if (b->kind != sk_namespace) + /* Look in non-namespace scopes. */ + for (cxx_binding *iter = NULL; + (iter = outer_binding (name, iter, /*class_p=*/ true)); ) + { + /* First check we're supposed to be looking in this scope -- + if we're not, we're done. */ + for (; b != iter->scope; b = b->level_chain) + if (!(b->kind == sk_cleanup + || b->kind == sk_template_parms + || b->kind == sk_function_parms + || (b->kind == sk_class + && scope == ts_within_enclosing_non_class))) + return NULL_TREE; + + /* Check if this is the kind of thing we're looking for. If + SCOPE is TS_CURRENT, also make sure it doesn't come from + base class. For ITER->VALUE, we can simply use + INHERITED_VALUE_BINDING_P. For ITER->TYPE, we have to + use our own check. + + We check ITER->TYPE before ITER->VALUE in order to handle + typedef struct C {} C; + correctly. */ + if (tree type = iter->type) + if ((scope != ts_current + || LOCAL_BINDING_P (iter) + || DECL_CONTEXT (type) == iter->scope->this_entity) + && qualify_lookup (iter->type, LOOKUP_PREFER_TYPES)) + return iter->type; + + if ((scope != ts_current + || !INHERITED_VALUE_BINDING_P (iter)) + && qualify_lookup (iter->value, LOOKUP_PREFER_TYPES)) + return iter->value; + } + + /* Now check if we can look in namespace scope. */ + for (; b->kind != sk_namespace; b = b->level_chain) + if (!(b->kind == sk_cleanup + || b->kind == sk_template_parms + || b->kind == sk_function_parms + || (b->kind == sk_class + && scope == ts_within_enclosing_non_class))) + return NULL_TREE; + + /* Look in the innermost namespace. */ + tree ns = b->this_entity; + if (tree *slot = find_namespace_slot (ns, name)) { - cp_binding_level *b = current_binding_level; - while (b) - { - if (level == b) - return val; - - if (b->kind == sk_cleanup || b->kind == sk_template_parms - || b->kind == sk_function_parms) - b = b->level_chain; - else if (b->kind == sk_class - && scope == ts_within_enclosing_non_class) - b = b->level_chain; - else - break; - } + /* If this is the kind of thing we're looking for, we're done. */ + if (tree type = MAYBE_STAT_TYPE (*slot)) + if (qualify_lookup (type, LOOKUP_PREFER_TYPES)) + return type; + + if (tree decl = MAYBE_STAT_DECL (*slot)) + if (qualify_lookup (decl, LOOKUP_PREFER_TYPES)) + return decl; }