Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/810683/?format=api
{ "id": 810683, "url": "http://patchwork.ozlabs.org/api/patches/810683/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/34c52ab3-a673-b1d8-7860-f8273bad5670@acm.org/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<34c52ab3-a673-b1d8-7860-f8273bad5670@acm.org>", "list_archive_url": null, "date": "2017-09-06T15:36:56", "name": "[C++] Merge fn and non-fn lookup interface", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "d67d722b05a66b7f0dcb6aadd6a127f514fdfae3", "submitter": { "id": 9970, "url": "http://patchwork.ozlabs.org/api/people/9970/?format=api", "name": "Nathan Sidwell", "email": "nathan@acm.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/34c52ab3-a673-b1d8-7860-f8273bad5670@acm.org/mbox/", "series": [ { "id": 1841, "url": "http://patchwork.ozlabs.org/api/series/1841/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=1841", "date": "2017-09-06T15:36:56", "name": "[C++] Merge fn and non-fn lookup interface", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/1841/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/810683/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/810683/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-return-461625-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=gcc-patches-return-461625-incoming=patchwork.ozlabs.org@gcc.gnu.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org\n\theader.b=\"KtWNv7Hi\"; dkim-atps=neutral", "sourceware.org; auth=none" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xnSPg0GPdz9t43\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 7 Sep 2017 01:37:10 +1000 (AEST)", "(qmail 127461 invoked by alias); 6 Sep 2017 15:37:03 -0000", "(qmail 127446 invoked by uid 89); 6 Sep 2017 15:37:02 -0000", "from mail-yw0-f169.google.com (HELO mail-yw0-f169.google.com)\n\t(209.85.161.169) by sourceware.org\n\t(qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP;\n\tWed, 06 Sep 2017 15:37:00 +0000", "by mail-yw0-f169.google.com with SMTP id x144so22905864ywg.2 for\n\t<gcc-patches@gcc.gnu.org>; Wed, 06 Sep 2017 08:37:00 -0700 (PDT)", "from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254?\n\t([2620:10d:c091:200::16fd]) by smtp.googlemail.com with\n\tESMTPSA id y193sm46995ywy.5.2017.09.06.08.36.57\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256\n\tbits=128/128); Wed, 06 Sep 2017 08:36:58 -0700 (PDT)" ], "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:to\n\t:from:subject:message-id:date:mime-version:content-type; q=dns;\n\ts=default; b=b2zdOIfP++zgM/iNFeMvEWpIvzyS45ovacAQwZpjUgigWh8B1a\n\tieif7QBZdkV71c4V6osnmK9dcxS0gUvhHOqyqFLNW2XVQbk+p08NzT4+IibWhYsD\n\tW+0FnpHi53pADNjncbtMXmImwI7RFCfipzsHqvkG8nJCtlcGU9TigLLiA=", "DKIM-Signature": "v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:to\n\t:from:subject:message-id:date:mime-version:content-type; s=\n\tdefault; bh=T0MxLr20s/ThODm0VJTaSPc5IS8=; b=KtWNv7Hi9p+buBs76m3b\n\tgtt4cI3xBI0rqRm1RmfFrrBUB0vbKh0TFBVc3wreSzrURnXZDPq6zQixIhohXGpt\n\tixCFJFiwqyD+Nu/fI6IGBEaHVKX30wUKvHsOxq6AJN4lGb2h03k0eAgpqtV+x4zp\n\tq4zMyTDoWx6g7TtfbYSnEBg=", "Mailing-List": "contact gcc-patches-help@gcc.gnu.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "List-Archive": "<http://gcc.gnu.org/ml/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-help@gcc.gnu.org>", "Sender": "gcc-patches-owner@gcc.gnu.org", "X-Virus-Found": "No", "X-Spam-SWARE-Status": "No, score=-15.6 required=5.0 tests=BAYES_00,\n\tFREEMAIL_FROM, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3,\n\tKAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM,\n\tSPF_PASS autolearn=ham version=3.3.2 spammy=punch", "X-HELO": "mail-yw0-f169.google.com", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net;\n\ts=20161025;\n\th=x-gm-message-state:sender:to:from:subject:message-id:date\n\t:user-agent:mime-version:content-language;\n\tbh=KU9scXMUlh1AtbDrMCslveqHffmgUP41dnpokRgN6F0=;\n\tb=UU2t5GtEoKxOFKFrChD1hMVL7ciK5qKITpyplSVfilprH19jwooXb3VdP/YD3fu3hI\n\tEKh7mgJ9+lMgX06f6JJYioGAsyJS9X2zuEs7mZ2hyhCA9R8BG2ZDG7fG39crSd3ssX4k\n\taVjPvMhoVmy2NyL+P3wOJbv8irj11aT56tLhgMT6vWu9fpbwqJRoKg9EemQQqVQ5EyER\n\tA3x4yVm03LB4YePHBhqt2ZUFdcV6yryhmrWQX40+hSnBA9K3nbCMraCxMss2d8bpTUq0\n\tFzjWFCNRvE3xaHnS5zx5/FJ1c/pr7amrQwPzovBrtszscHwV1+XvXlJ+G+HdQ87gc/Oa\n\tPL/g==", "X-Gm-Message-State": "AHPjjUhzEqpHZBm2hufKKh8Q3S92cn01DT3oeMrYEwV3kgzNba+yPvay\t0q5/T7/+2A51kg==", "X-Google-Smtp-Source": "ADKCNb4VrSYsGbvD/2c14C/iKOO8qOl15HUQxnuUEsnPLBQEmsYY1jO+AV6QZin754AJ2WK9syJOFg==", "X-Received": "by 10.129.193.74 with SMTP id e10mr2285886ywl.262.1504712218784;\n\tWed, 06 Sep 2017 08:36:58 -0700 (PDT)", "To": "GCC Patches <gcc-patches@gcc.gnu.org>", "From": "Nathan Sidwell <nathan@acm.org>", "Subject": "[C++ PATCH] Merge fn and non-fn lookup interface", "Message-ID": "<34c52ab3-a673-b1d8-7860-f8273bad5670@acm.org>", "Date": "Wed, 6 Sep 2017 11:36:56 -0400", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64;\n\trv:52.0) Gecko/20100101 Thunderbird/52.2.1", "MIME-Version": "1.0", "Content-Type": "multipart/mixed;\n\tboundary=\"------------20D79AA4B109EA110EF277FC\"" }, "content": "This patch merges the lookup of function and non-function member lookup \ninto get_class_binding_direct. lookup_field_1 becomes an internal detail.\n\nWe grow a tri-valued argument to get_class_binding_direct:\n<0 -- caller wants functions\n=0 -- caller wants whatever is bound\n >0 -- caller wants type_decl binding.\n\nThis has the nice property that lookup_field_1's want_type argument maps \nonto the latter two values. The default is the first, which matches the \nexisting get_class_binding usage. The two places where lookup_field_1 \nwas being called directly are converted and were:\n\n1) hierarchy searching. This functionality is swallowed by \nget_class_binding_direct, and it passes in the want_type argument.\n\n2) named initializers. this now passes in 0. You'll notice this case \nis with the type being complete, so we now might get a binary search of \nMETHOD_VEC that we didn;t before. This is going to be a short-lived \nperformance regression.\n\napplied to trunk.\n\nI'm going to hold off the next patch as (a) it's more invasive, but (b) \nit steals the punch line from my name-lookup cauldron talk.\n\nnathan", "diff": "2017-09-06 Nathan Sidwell <nathan@acm.org>\n\n\t* name-lookup.h (lookup_field_1): Delete.\n\t(get_class_binding_direct, get_class_binding): Add type_or_fns arg.\n\t* name-lookup.c\t(lookup_field_1): make static\n\t(method_vec_binary_search, method_vec_linear_search): New. Broken\n\tout of ...\n\t(get_class_binding_direct): ... here. Add TYPE_OR_FNS argument.\n\tDo complete search of this level.\n\t(get_class_binding): Adjust.\n\t* decl.c (reshape_init_class): Call get_class_binding.\n\t* search.c (lookup_field_r): Move field searching into\n\tget_class_binding_direct.\n\nIndex: decl.c\n===================================================================\n--- decl.c\t(revision 251782)\n+++ decl.c\t(working copy)\n@@ -5746,7 +5746,7 @@ reshape_init_class (tree type, reshape_i\n \t /* We already reshaped this. */\n \t gcc_assert (d->cur->index == field);\n \t else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)\n-\t field = lookup_field_1 (type, d->cur->index, /*want_type=*/false);\n+\t field = get_class_binding (type, d->cur->index, false);\n \t else\n \t {\n \t if (complain & tf_error)\nIndex: name-lookup.c\n===================================================================\n--- name-lookup.c\t(revision 251794)\n+++ name-lookup.c\t(working copy)\n@@ -1113,79 +1113,54 @@ extract_conversion_operator (tree fns, t\n return convs;\n }\n \n-/* TYPE is a class type. Return the member functions in the method\n- vector with name NAME. Does not lazily declare implicitly-declared\n- member functions. */\n+/* Binary search of (ordered) METHOD_VEC for NAME. */\n \n-tree\n-get_class_binding_direct (tree type, tree name)\n+static tree\n+method_vec_binary_search (vec<tree, va_gc> *method_vec, tree name)\n {\n- vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (type);\n- if (!method_vec)\n- return NULL_TREE;\n-\n- /* Conversion operators can only be found by the marker conversion\n- operator name. */\n- bool conv_op = IDENTIFIER_CONV_OP_P (name);\n- tree lookup = conv_op ? conv_op_identifier : name;\n- tree val = NULL_TREE;\n- tree fns;\n-\n- /* If the type is complete, use binary search. */\n- if (COMPLETE_TYPE_P (type))\n+ for (unsigned lo = 0, hi = method_vec->length (); lo < hi;)\n {\n- int lo = 0;\n- int hi = method_vec->length ();\n- while (lo < hi)\n-\t{\n-\t int i = (lo + hi) / 2;\n-\n-\t fns = (*method_vec)[i];\n-\t tree fn_name = OVL_NAME (fns);\n-\t if (fn_name > lookup)\n-\t hi = i;\n-\t else if (fn_name < lookup)\n-\t lo = i + 1;\n-\t else\n-\t {\n-\t val = fns;\n-\t break;\n-\t }\n-\t}\n+ unsigned mid = (lo + hi) / 2;\n+ tree binding = (*method_vec)[mid];\n+ tree binding_name = OVL_NAME (binding);\n+\n+ if (binding_name > name)\n+\thi = mid;\n+ else if (binding_name < name)\n+\tlo = mid + 1;\n+ else\n+\treturn binding;\n }\n- else\n- for (int i = 0; vec_safe_iterate (method_vec, i, &fns); ++i)\n- /* We can get a NULL binding during insertion of a new\n-\t method name, because the identifier_binding machinery\n-\t performs a lookup. If we find such a NULL slot, that's\n-\t the thing we were looking for, so we might as well bail\n-\t out immediately. */\n- if (!fns)\n-\tbreak;\n- else if (OVL_NAME (fns) == lookup)\n-\t{\n-\t val = fns;\n-\t break;\n-\t}\n \n- /* Extract the conversion operators asked for, unless the general\n- conversion operator was requested. */\n- if (val && conv_op)\n- {\n- gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);\n- val = OVL_CHAIN (val);\n- if (tree type = TREE_TYPE (name))\n-\tval = extract_conversion_operator (val, type);\n- }\n+ return NULL_TREE;\n+}\n \n- return val;\n+/* Linear search of (unordered) METHOD_VEC for NAME. */\n+\n+static tree\n+method_vec_linear_search (vec<tree, va_gc> *method_vec, tree name)\n+{\n+ for (int ix = method_vec->length (); ix--;)\n+ /* We can get a NULL binding during insertion of a new method\n+ name, because the identifier_binding machinery performs a\n+ lookup. If we find such a NULL slot, that's the thing we were\n+ looking for, so we might as well bail out immediately. */\n+ if (tree binding = (*method_vec)[ix])\n+ {\n+\tif (OVL_NAME (binding) == name)\n+\t return binding;\n+ }\n+ else\n+ break;\n+\n+ return NULL_TREE;\n }\n \n /* Do a 1-level search for NAME as a member of TYPE. The caller must\n figure out whether it can access this field. (Since it is only one\n level, this is reasonable.) */\n \n-tree\n+static tree\n lookup_field_1 (tree type, tree name, bool want_type)\n {\n tree field;\n@@ -1281,11 +1256,62 @@ lookup_field_1 (tree type, tree name, bo\n return NULL_TREE;\n }\n \n-/* TYPE is a class type. Return the overloads in\n- the method vector with name NAME. Lazily create ctors etc. */\n+/* Look for NAME as an immediate member of KLASS (including\n+ anon-members or unscoped enum member). TYPE_OR_FNS is zero for\n+ regular search. >0 to get a type binding (if there is one) and <0\n+ if you want (just) the member function binding.\n+\n+ Use this if you do not want lazy member creation. */\n+\n+tree\n+get_class_binding_direct (tree klass, tree name, int type_or_fns)\n+{\n+ gcc_checking_assert (RECORD_OR_UNION_TYPE_P (klass));\n+\n+ /* Conversion operators can only be found by the marker conversion\n+ operator name. */\n+ bool conv_op = IDENTIFIER_CONV_OP_P (name);\n+ tree lookup = conv_op ? conv_op_identifier : name;\n+ tree val = NULL_TREE;\n+ vec<tree, va_gc> *method_vec = CLASSTYPE_METHOD_VEC (klass);\n+\n+ if (!method_vec || type_or_fns > 0)\n+ ;\n+ else if (COMPLETE_TYPE_P (klass))\n+ val = method_vec_binary_search (method_vec, lookup);\n+ else\n+ val = method_vec_linear_search (method_vec, lookup);\n+\n+ if (type_or_fns < 0)\n+ /* Don't bother looking for field. We don't want it. */;\n+ else if (!val || (TREE_CODE (val) == OVERLOAD && OVL_USING_P (val)))\n+ {\n+ /* Dependent using declarations are a 'field', make sure we\n+\t return that even if we saw an overload already. */\n+ if (tree field_val = lookup_field_1 (klass, lookup, type_or_fns > 0))\n+\tif (!val || TREE_CODE (field_val) == USING_DECL)\n+\t val = field_val;\n+ }\n+\n+ /* Extract the conversion operators asked for, unless the general\n+ conversion operator was requested. */\n+ if (val && conv_op)\n+ {\n+ gcc_checking_assert (OVL_FUNCTION (val) == conv_op_marker);\n+ val = OVL_CHAIN (val);\n+ if (tree type = TREE_TYPE (name))\n+\tval = extract_conversion_operator (val, type);\n+ }\n+\n+ return val;\n+}\n+\n+/* Look for NAME's binding in exactly KLASS. See\n+ get_class_binding_direct for argument description. Does lazy\n+ special function creation as necessary. */\n \n tree\n-get_class_binding (tree type, tree name)\n+get_class_binding (tree type, tree name, int type_or_fns)\n {\n type = complete_type (type);\n \n@@ -1314,7 +1340,7 @@ get_class_binding (tree type, tree name)\n \t}\n }\n \n- return get_class_binding_direct (type, name);\n+ return get_class_binding_direct (type, name, type_or_fns);\n }\n \n /* Find the slot containing overloads called 'NAME'. If there is no\nIndex: name-lookup.h\n===================================================================\n--- name-lookup.h\t(revision 251782)\n+++ name-lookup.h\t(working copy)\n@@ -319,9 +319,8 @@ extern void pop_decl_namespace (void);\n extern void do_namespace_alias (tree, tree);\n extern tree do_class_using_decl (tree, tree);\n extern tree lookup_arg_dependent (tree, tree, vec<tree, va_gc> *);\n-extern tree lookup_field_1\t\t\t(tree, tree, bool);\n-extern tree get_class_binding_direct (tree, tree);\n-extern tree get_class_binding (tree, tree);\n+extern tree get_class_binding_direct (tree, tree, int type_or_fns = -1);\n+extern tree get_class_binding (tree, tree, int type_or_fns = -1);\n extern tree *get_method_slot (tree klass, tree name);\n extern void resort_type_method_vec (void *, void *,\n \t\t\t\t gt_pointer_operator, void *);\nIndex: search.c\n===================================================================\n--- search.c\t(revision 251782)\n+++ search.c\t(working copy)\n@@ -974,23 +974,7 @@ lookup_field_r (tree binfo, void *data)\n && !BINFO_VIRTUAL_P (binfo))\n return dfs_skip_bases;\n \n- /* First, look for a function. There can't be a function and a data\n- member with the same name, and if there's a function and a type\n- with the same name, the type is hidden by the function. */\n- if (!lfi->want_type)\n- nval = get_class_binding (type, lfi->name);\n-\n- if (!nval)\n- /* Look for a data member or type. */\n- nval = lookup_field_1 (type, lfi->name, lfi->want_type);\n- else if (TREE_CODE (nval) == OVERLOAD && OVL_USING_P (nval))\n- {\n- /* If we have both dependent and non-dependent using-declarations, return\n-\t the dependent one rather than an incomplete list of functions. */\n- tree dep_using = lookup_field_1 (type, lfi->name, lfi->want_type);\n- if (dep_using && TREE_CODE (dep_using) == USING_DECL)\n-\tnval = dep_using;\n- }\n+ nval = get_class_binding (type, lfi->name, lfi->want_type);\n \n /* If we're looking up a type (as with an elaborated type specifier)\n we ignore all non-types we find. */\n", "prefixes": [ "C++" ] }