From patchwork Wed May 24 15:59:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 766544 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 3wXxtj55BFz9sNY for ; Thu, 25 May 2017 02:00:12 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="oBWMWlmj"; 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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=txiCKLVzuuYKBUU/OeMgoqe+Uap0tw47D683BC5evgZzQHEtND Wznm6kPCwzVlJzTgXytsbARkMmgAkA7CZdyCjLZ3L1eft/TAic9ezwPQqwEx+2tX ZjM3EKS5SMPoi0/gG/7jAi5fZm9Xb1CjLQj1/XYBge8WVaHw+xv56xYCc= 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=UWfOib1ootpvMxdzRK+o8uMS7fc=; b=oBWMWlmjhJ2InjPGDPts WIEsz7l4fCQqGCHT71aFRltYnTBnzpFalfEb0B7Mmuq8t0pzziciLD1TTk48EyvZ 1x8HqEfSe6y1bUF9ExQ+y1x/0Nyv9FSA7yXMChQUDNro65tgf09qpwpHeVHL9DiT aQazHVKYWhsajbunNPy/6Ps= Received: (qmail 30691 invoked by alias); 24 May 2017 15:59:57 -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 30669 invoked by uid 89); 24 May 2017 15:59:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-yw0-f174.google.com Received: from mail-yw0-f174.google.com (HELO mail-yw0-f174.google.com) (209.85.161.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 24 May 2017 15:59:54 +0000 Received: by mail-yw0-f174.google.com with SMTP id b68so91363721ywe.3 for ; Wed, 24 May 2017 08:59:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=EjtD/5OVma6I7qhDHUb2qQ8YehqTD84rlLBnyK9xQRI=; b=EamDvmLctQ0mCYCf9KddejL9W/Nb1ZCzsyQSGJrVUHEAJLbEGzdJgS5WMT1d/tGyEk m4S9fsTs4Pdq8UYjMA01rJbJZgJkNw6ACRp5IxEXikKXR8JHoH3iXjnFcnYoXns7NaSA /rCHvy2bTEwojhjDFTnQyPWirMMuYpYopk1W1CkwYHAFbzaDQtnY719hiZO4n+pIv1ZU 6Y1Ji7gDZ6rCCkF/91LBbYjINiRawBShGYUta9lGu4Jfc+Vc71g+stBdx3atnaV+/+8Z UmC1hh735fcAscbiVU/m60hJy0VNmoVRsfIQwUKS9TdKTxVGN1kioF+kPNw60jwZuHuz UPAA== X-Gm-Message-State: AODbwcB526FJg6jLXhUCksSpEGck1usZsHNpq2n0S72KNZK9eyQBU4Il XvuPa8BKfmJ3aw== X-Received: by 10.129.72.1 with SMTP id v1mr25571856ywa.23.1495641596854; Wed, 24 May 2017 08:59:56 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a1:1102:b9b0:1beb:d21c:b3f4? ([2620:10d:c091:180::1:11db]) by smtp.googlemail.com with ESMTPSA id a16sm1902915ywh.21.2017.05.24.08.59.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 May 2017 08:59:56 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] Hidden name removal Message-ID: <54c5f328-e351-cefe-e788-768f7bdccbea@acm.org> Date: Wed, 24 May 2017 11:59:54 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.0 MIME-Version: 1.0 Now that overloads are kept ordered, I can replace the existing remove_hidden_names fn with ovl_skip_hidden. The former works by scanning the overloads, then if it discovers a hidden one, copying the list (from the beginning) omitting the hidden ones. Now, overloads aren't usually huge, but this forces scanning on every lookup, and is O(N^2), so bad. ovl_skip_hidden simply drops the OVL_HIDDEN_P nodes at the start of an overload. Often doing nothing. For extra badness, lookup_name_real was applying remove_hidden_names to a result that had already had it run! Applied to trunk. nathan 2017-05-24 Nathan Sidwell * cp-tree.h (ovl_skip_hidden): Declare. * tree.c (ovl_skip_hidden): New. * name-lookup.c (arg_assoc_namespace): Call ovl_skip_hidden. (lookup_arg_dependent_1): Likewise. (ambiguous_decl): Use DECL_HIDDEN_P, ovl_skip_hidden. (hidden_name_p, remove_hidden_names): Delete. (lookup_name_real_1): Do not strip hidden names. * name-lookup.h (hidden_name_p, remove_hidden_names): Delete. Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 248422) +++ cp/cp-tree.h (working copy) @@ -6852,6 +6852,7 @@ extern tree ovl_make (tree fn, tree next = NULL_TREE); extern tree ovl_insert (tree fn, tree maybe_ovl, bool using_p = false); +extern tree ovl_skip_hidden (tree); extern tree lookup_add (tree fns, tree lookup); extern void lookup_keep (tree lookup, bool keep); extern int is_overloaded_fn (tree); Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 248422) +++ cp/name-lookup.c (working copy) @@ -275,14 +275,10 @@ arg_assoc_namespace (struct arg_lookup * if (!value) return false; + value = ovl_skip_hidden (value); + for (; value; value = OVL_NEXT (value)) { - /* We don't want to find arbitrary hidden functions via argument - dependent lookup. We only want to find friends of associated - classes, which we'll do via arg_assoc_class. */ - if (hidden_name_p (OVL_CURRENT (value))) - continue; - if (add_function (k, OVL_CURRENT (value))) return true; } @@ -630,7 +626,7 @@ lookup_arg_dependent_1 (tree name, tree /* Remove any hidden friend functions from the list of functions found so far. They will be added back by arg_assoc_class as appropriate. */ - fns = remove_hidden_names (fns); + fns = ovl_skip_hidden (fns); k.name = name; k.args = args; @@ -4347,7 +4343,7 @@ ambiguous_decl (struct scope_binding *ol /* Copy the type. */ type = new_binding->type; if (LOOKUP_NAMESPACES_ONLY (flags) - || (type && hidden_name_p (type) && !(flags & LOOKUP_HIDDEN))) + || (type && !(flags & LOOKUP_HIDDEN) && DECL_HIDDEN_P (type))) type = NULL_TREE; /* Copy the value. */ @@ -4355,7 +4351,7 @@ ambiguous_decl (struct scope_binding *ol if (val) { if (!(flags & LOOKUP_HIDDEN)) - val = remove_hidden_names (val); + val = ovl_skip_hidden (val); if (val) switch (TREE_CODE (val)) { @@ -4465,59 +4461,6 @@ qualify_lookup (tree val, int flags) return true; } -/* Given a lookup that returned VAL, decide if we want to ignore it or - not based on DECL_ANTICIPATED. */ - -bool -hidden_name_p (tree val) -{ - if (DECL_P (val) - && DECL_LANG_SPECIFIC (val) - && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val) - && DECL_ANTICIPATED (val)) - return true; - if (TREE_CODE (val) == OVERLOAD) - { - for (tree o = val; o; o = OVL_CHAIN (o)) - if (!hidden_name_p (OVL_FUNCTION (o))) - return false; - return true; - } - return false; -} - -/* Remove any hidden declarations from a possibly overloaded set - of functions. */ - -tree -remove_hidden_names (tree fns) -{ - if (!fns) - return fns; - - if (DECL_P (fns) && hidden_name_p (fns)) - fns = NULL_TREE; - else if (TREE_CODE (fns) == OVERLOAD) - { - tree o; - - for (o = fns; o; o = OVL_NEXT (o)) - if (hidden_name_p (OVL_CURRENT (o))) - break; - if (o) - { - tree n = NULL_TREE; - - for (o = fns; o; o = OVL_NEXT (o)) - if (!hidden_name_p (OVL_CURRENT (o))) - n = lookup_add (OVL_CURRENT (o), n); - fns = n; - } - } - - return fns; -} - /* Suggest alternatives for NAME, an IDENTIFIER_NODE for which name lookup failed. Search through all available namespaces and print out possible candidates. If no exact matches are found, and @@ -5337,10 +5280,6 @@ lookup_name_real_1 (tree name, int prefe if (!val) val = unqualified_namespace_lookup (name, flags); - /* Anticipated built-ins and friends aren't found by normal lookup. */ - if (val && !(flags & LOOKUP_HIDDEN)) - val = remove_hidden_names (val); - /* If we have a single function from a using decl, pull it out. */ if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val)) val = OVL_FUNCTION (val); Index: cp/name-lookup.h =================================================================== --- cp/name-lookup.h (revision 248422) +++ cp/name-lookup.h (working copy) @@ -308,8 +308,6 @@ extern tree lookup_name_real (tree, int, extern tree lookup_type_scope (tree, tag_scope); extern tree get_namespace_binding (tree ns, tree id); extern void set_global_binding (tree id, tree val); -extern bool hidden_name_p (tree); -extern tree remove_hidden_names (tree); extern tree lookup_qualified_name (tree, tree, int, bool, /*hidden*/bool = false); extern tree lookup_name_nonclass (tree); extern tree lookup_name_innermost_nonclass_level (tree); Index: cp/tree.c =================================================================== --- cp/tree.c (revision 248422) +++ cp/tree.c (working copy) @@ -2204,6 +2204,27 @@ ovl_insert (tree fn, tree maybe_ovl, boo return result; } +/* Skip any hidden names at the beginning of OVL. */ + +tree +ovl_skip_hidden (tree ovl) +{ + for (; + ovl && TREE_CODE (ovl) == OVERLOAD && OVL_HIDDEN_P (ovl); + ovl = OVL_CHAIN (ovl)) + gcc_checking_assert (DECL_HIDDEN_P (OVL_FUNCTION (ovl))); + + if (ovl && TREE_CODE (ovl) != OVERLOAD && DECL_HIDDEN_P (ovl)) + { + /* Any hidden functions should have been wrapped in an + overload, but injected friend classes will not. */ + gcc_checking_assert (!DECL_DECLARES_FUNCTION_P (ovl)); + ovl = NULL_TREE; + } + + return ovl; +} + /* NODE is an OVL_HIDDEN_P node which is now revealed. */ tree