From patchwork Tue May 16 13:19:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 763003 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 3wRyjB22qjz9s3w for ; Tue, 16 May 2017 23:19:42 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ZGwRt11D"; 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=mXhQbdfq9T7O2nmsScizE4ZdL0Ve/4xwqYSTlij8ncuoA0J6SB c+BHmzb/toiQDb9KM1C3F1pXGaHeRWGiP/8n1mQBTaovb+sA5RM9TTJTwh2ZD190 h62MZu3wd0jrVsfKRfMwESdOPKyyqQvULFYfRFCOsV7CNlsH0mpzWD0P8= 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=YVCELZhwkiFgBQ7P0uWIERji7So=; b=ZGwRt11DIlE2QwkSLV2W YR15lj9CLfIyB5H7Lm94SaT5hiBXzM19E2mbJFqyyABOC0DpNBizXFvAC96rVsuI 1Qji2RCtj1WZB3egLavVBuvgT/rp/xjZYpnrrwlgLWHtlG7RpuC1r2IhgcUe/eTu iXK7mhZjLYrIa5VGl7j3Nbo= Received: (qmail 82991 invoked by alias); 16 May 2017 13:19:26 -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 82963 invoked by uid 89); 16 May 2017 13:19:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-yw0-f182.google.com Received: from mail-yw0-f182.google.com (HELO mail-yw0-f182.google.com) (209.85.161.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 May 2017 13:19:22 +0000 Received: by mail-yw0-f182.google.com with SMTP id 203so52455574ywe.0 for ; Tue, 16 May 2017 06:19:25 -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=CTyXYqQKw8CVVQ74SVcaOU9g5T+qMD13h5Il4mVndss=; b=hID9BlTyCLBsa8nxJEpfvaEfPMd4XpGWdSQ7kLt6YbvxGYJO9J4mWE0tByNTWuH6CN 3VzRSTd3l7xNolcUSayTTCqvLDFoKxqIOGiKwdqUc+ESILHJQZCmI4sxC87+FpmwExV8 ZHMwryy8hmL3q2Wy0uD5Af9FBGHTAB4Jzdyif9dp+RrqDa7xtqpL8qwcBzzx2/9CL4jm pv0tJT1+VK9ZNr4wiAive/Z7wWLlFZzRJ8a8Wo7RWHRCC0rLuqnpGgV2ZLYGT5WQ+tD5 95udMIuvIkhh0rWlMiczmmQstlQ+osevx8I8/boJmA5FnAZ+IvXE3uUq4F620imkuodO yA/w== X-Gm-Message-State: AODbwcAIacA3IYuQQoWtzRs0XFphh0iFZlm9nyNjJLGiRyxoi+jtNcZs moYtkWMkf5V+WQ== X-Received: by 10.129.95.195 with SMTP id t186mr10401610ywb.50.1494940763607; Tue, 16 May 2017 06:19:23 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:f6d0:5ac5:64cd:f102? ([2620:10d:c091:200::7:4a1a]) by smtp.googlemail.com with ESMTPSA id x189sm7070170ywg.47.2017.05.16.06.19.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 16 May 2017 06:19:23 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] OVERLOAD abstractions part 1 Message-ID: <9580e6d3-d0e6-e0df-66cf-f9c921240449@acm.org> Date: Tue, 16 May 2017 09:19:21 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.0 MIME-Version: 1.0 My reworking of overload management will be introducing overloads-of-overloads as lookup results. This patch introduces OVL_FIRST to get the first function of a lookup set, and OVL_NAME to get the DECL_NAME of that (a useful accessor). In many case we were unnecessarily using get_fns or get_first_fn, and this patch cleans that up. I made OVL_FIRST forward to a new inline function, which simply loops until the thing it has is not an OVERLOAD. Right now that's only ever one loop, but in future will be more than one. I didn't feel like manually unrolling that loop, which could only ever be done twice. applied to trunk. nathan 2017-05-16 Nathan Sidwell * cp-tree.h (OVL_FIRST, OVL_NAME): New. (ovl_first): New. * constexpr.c (function_concept_check): Use OVL_FIRST. * cvt.c (build_expr_type_conversion): Likewise. * decl.c (poplevel, grokdeclarator): Use OVL_NAME. * decl2.c (mark_used): Use OVL_FIRST. * error.c (dump_decl): Use OVL_FIRST, OVL_NAME. (dump_expr, location_of): Use OVL_FIRST. * friend.c (do_friend): Use OVL_NAME. * init.c (build_offset_ref): Use OVL_FIRST. * mangle.c (write_member_name): Likewise. (write_expression): Use OVL_NAME. * method.c (strip_inheriting_ctors): Use OVL_FIRST. * name-lookup.c (pushdecl_class_level): Use OVL_NAME. * pt.c (check_explicit_specialization): Use OVL_FIRST. (check_template_shadow): Likewise. (tsubst_template_args): Use OVL_NAME. (tsubst_baselink): Use OVL_FIRST. * semantics.c (perform_koenig_lookup): Use OVL_NAME. * tree.c (get_first_fn): Use OVL_FIRST. * typeck.c (finish_class_member_access_expr): Use OVL_NAME. (cp_build_addr_expr_1): Use OVL_FIRST. Index: constraint.cc =================================================================== --- constraint.cc (revision 248095) +++ constraint.cc (working copy) @@ -117,10 +117,9 @@ function_concept_check_p (tree t) gcc_assert (TREE_CODE (t) == CALL_EXPR); tree fn = CALL_EXPR_FN (t); if (fn != NULL_TREE - && TREE_CODE (fn) == TEMPLATE_ID_EXPR - && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD) + && TREE_CODE (fn) == TEMPLATE_ID_EXPR) { - tree f1 = get_first_fn (fn); + tree f1 = OVL_FIRST (TREE_OPERAND (fn, 0)); if (TREE_CODE (f1) == TEMPLATE_DECL && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (f1))) return true; Index: cp-tree.h =================================================================== --- cp-tree.h (revision 248095) +++ cp-tree.h (working copy) @@ -626,6 +626,11 @@ typedef struct ptrmem_cst * ptrmem_cst_t and can be freed afterward. */ #define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE)) +/* The first decl of an overload. */ +#define OVL_FIRST(NODE) ovl_first (NODE) +/* The name of the overload set. */ +#define OVL_NAME(NODE) DECL_NAME (OVL_FIRST (NODE)) + struct GTY(()) tree_overload { struct tree_common common; tree function; @@ -6668,6 +6673,13 @@ extern tree hash_tree_cons (tree, tree extern tree hash_tree_chain (tree, tree); extern tree build_qualified_name (tree, tree, tree, bool); extern tree build_ref_qualified_type (tree, cp_ref_qualifier); +inline tree +ovl_first (tree node) +{ + while (TREE_CODE (node) == OVERLOAD) + node = OVL_FUNCTION (node); + return node; +} extern int is_overloaded_fn (tree); extern tree dependent_name (tree); extern tree get_fns (tree); Index: cvt.c =================================================================== --- cvt.c (revision 248095) +++ cvt.c (working copy) @@ -1722,7 +1722,7 @@ build_expr_type_conversion (int desires, int win = 0; tree candidate; tree cand = TREE_VALUE (conv); - cand = OVL_CURRENT (cand); + cand = OVL_FIRST (cand); if (winner && winner == cand) continue; Index: decl.c =================================================================== --- decl.c (revision 248095) +++ decl.c (working copy) @@ -683,7 +683,7 @@ poplevel (int keep, int reverse, int fun for (link = decls; link; link = TREE_CHAIN (link)) { decl = TREE_CODE (link) == TREE_LIST ? TREE_VALUE (link) : link; - tree name = DECL_NAME (OVL_CURRENT (decl)); + tree name = OVL_NAME (decl); if (leaving_for_scope && VAR_P (decl) /* It's hard to make this ARM compatibility hack play nicely with @@ -10104,10 +10104,7 @@ grokdeclarator (const cp_declarator *dec if (variable_template_p (dname)) dname = DECL_NAME (dname); else - { - gcc_assert (is_overloaded_fn (dname)); - dname = DECL_NAME (get_first_fn (dname)); - } + dname = OVL_NAME (dname); } } /* Fall through. */ Index: decl2.c =================================================================== --- decl2.c (revision 248095) +++ decl2.c (working copy) @@ -5029,7 +5029,7 @@ mark_used (tree decl, tsubst_flags_t com decl = BASELINK_FUNCTIONS (decl); if (really_overloaded_fn (decl)) return true; - decl = OVL_CURRENT (decl); + decl = OVL_FIRST (decl); } /* Set TREE_USED for the benefit of -Wunused. */ Index: error.c =================================================================== --- error.c (revision 248095) +++ error.c (working copy) @@ -1208,7 +1208,7 @@ dump_decl (cxx_pretty_printer *pp, tree /* If there's only one function, just treat it like an ordinary FUNCTION_DECL. */ - t = OVL_CURRENT (t); + t = OVL_FIRST (t); /* Fall through. */ case FUNCTION_DECL: @@ -1235,10 +1235,8 @@ dump_decl (cxx_pretty_printer *pp, tree tree name = TREE_OPERAND (t, 0); tree args = TREE_OPERAND (t, 1); - if (is_overloaded_fn (name)) - name = get_first_fn (name); - if (DECL_P (name)) - name = DECL_NAME (name); + if (!identifier_p (name)) + name = OVL_NAME (name); dump_decl (pp, name, flags); pp_cxx_begin_template_argument_list (pp); if (args == error_mark_node) @@ -2498,7 +2496,7 @@ dump_expr (cxx_pretty_printer *pp, tree /* A::f */ dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS); else if (BASELINK_P (t)) - dump_expr (pp, OVL_CURRENT (BASELINK_FUNCTIONS (t)), + dump_expr (pp, OVL_FIRST (BASELINK_FUNCTIONS (t)), flags | TFF_EXPR_IN_PARENS); else dump_decl (pp, t, flags); @@ -3004,7 +3002,7 @@ location_of (tree t) return input_location; } else if (TREE_CODE (t) == OVERLOAD) - t = OVL_FUNCTION (t); + t = OVL_FIRST (t); if (DECL_P (t)) return DECL_SOURCE_LOCATION (t); Index: friend.c =================================================================== --- friend.c (revision 248095) +++ friend.c (working copy) @@ -494,8 +494,7 @@ do_friend (tree ctype, tree declarator, if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) { declarator = TREE_OPERAND (declarator, 0); - if (is_overloaded_fn (declarator)) - declarator = DECL_NAME (get_first_fn (declarator)); + declarator = OVL_NAME (declarator); } if (ctype) Index: init.c =================================================================== --- init.c (revision 248095) +++ init.c (working copy) @@ -2063,7 +2063,7 @@ build_offset_ref (tree type, tree member if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t)) { /* Get rid of a potential OVERLOAD around it. */ - t = OVL_CURRENT (t); + t = OVL_FIRST (t); /* Unique functions are handled easily. */ Index: mangle.c =================================================================== --- mangle.c (revision 248095) +++ mangle.c (working copy) @@ -2833,8 +2833,7 @@ write_member_name (tree member) else if (TREE_CODE (member) == TEMPLATE_ID_EXPR) { tree name = TREE_OPERAND (member, 0); - if (TREE_CODE (name) == OVERLOAD) - name = OVL_FUNCTION (name); + name = OVL_FIRST (name); write_member_name (name); write_template_args (TREE_OPERAND (member, 1)); } @@ -3053,10 +3052,7 @@ write_expression (tree expr) else if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) { tree fn = TREE_OPERAND (expr, 0); - if (is_overloaded_fn (fn)) - fn = get_first_fn (fn); - if (DECL_P (fn)) - fn = DECL_NAME (fn); + fn = OVL_NAME (fn); if (IDENTIFIER_OPNAME_P (fn)) write_string ("on"); write_unqualified_id (fn); @@ -3257,7 +3253,7 @@ write_expression (tree expr) if ((TREE_CODE (fn) == FUNCTION_DECL || TREE_CODE (fn) == OVERLOAD) && type_dependent_expression_p_push (expr)) - fn = DECL_NAME (get_first_fn (fn)); + fn = OVL_NAME (fn); write_expression (fn); } Index: method.c =================================================================== --- method.c (revision 248095) +++ method.c (working copy) @@ -502,10 +502,8 @@ strip_inheriting_ctors (tree dfn) return dfn; tree fn = dfn; while (tree inh = DECL_INHERITED_CTOR (fn)) - { - inh = OVL_CURRENT (inh); - fn = inh; - } + fn = OVL_FIRST (inh); + if (TREE_CODE (fn) == TEMPLATE_DECL && TREE_CODE (dfn) == FUNCTION_DECL) fn = DECL_TEMPLATE_RESULT (fn); Index: name-lookup.c =================================================================== --- name-lookup.c (revision 248095) +++ name-lookup.c (working copy) @@ -3610,7 +3610,6 @@ set_inherited_value_binding_p (cxx_bindi bool pushdecl_class_level (tree x) { - tree name; bool is_valid = true; bool subtime; @@ -3621,10 +3620,7 @@ pushdecl_class_level (tree x) subtime = timevar_cond_start (TV_NAME_LOOKUP); /* Get the name of X. */ - if (TREE_CODE (x) == OVERLOAD) - name = DECL_NAME (get_first_fn (x)); - else - name = DECL_NAME (x); + tree name = OVL_NAME (x); if (name) { Index: pt.c =================================================================== --- pt.c (revision 248095) +++ pt.c (working copy) @@ -2930,7 +2930,7 @@ check_explicit_specialization (tree decl methods->iterate (idx, &ovl); ++idx) { - if (!DECL_CONV_FN_P (OVL_CURRENT (ovl))) + if (!DECL_CONV_FN_P (OVL_FIRST (ovl))) /* There are no more conversion functions. */ break; @@ -3910,8 +3910,7 @@ check_template_shadow (tree decl) return true; /* Figure out what we're shadowing. */ - if (TREE_CODE (decl) == OVERLOAD) - decl = OVL_CURRENT (decl); + decl = OVL_FIRST (decl); olddecl = innermost_non_namespace_value (DECL_NAME (decl)); /* If there's no previous binding for this name, we're not shadowing @@ -14128,7 +14127,7 @@ tsubst_baselink (tree baselink, tree obj template_args = tsubst_template_args (template_args, args, complain, in_decl); } - name = DECL_NAME (get_first_fn (fns)); + name = OVL_NAME (fns); if (IDENTIFIER_TYPENAME_P (name)) name = mangle_conv_op_name_for_type (optype); baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1); @@ -14150,7 +14149,7 @@ tsubst_baselink (tree baselink, tree obj if (BASELINK_P (baselink)) fns = BASELINK_FUNCTIONS (baselink); if (!template_id_p && !really_overloaded_fn (fns) - && !mark_used (OVL_CURRENT (fns), complain) && !(complain & tf_error)) + && !mark_used (OVL_FIRST (fns), complain) && !(complain & tf_error)) return error_mark_node; /* Add back the template arguments, if present. */ Index: semantics.c =================================================================== --- semantics.c (revision 248095) +++ semantics.c (working copy) @@ -2231,15 +2231,10 @@ perform_koenig_lookup (cp_expr fn, vec