aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-08-25 12:35:07 -0700
committerNathan Sidwell <nathan@acm.org>2020-08-26 05:26:53 -0700
commit1f53d8f1d3e7519bd81cc5874e43ed9896cf6180 (patch)
treeee5325815140f2b204394594cd5c7e108279958a /gcc/cp/decl.c
parentf523aaa039cc0ab59791045a840e4e35f1b1eb24 (diff)
downloadgcc-1f53d8f1d3e7519bd81cc5874e43ed9896cf6180.zip
gcc-1f53d8f1d3e7519bd81cc5874e43ed9896cf6180.tar.gz
gcc-1f53d8f1d3e7519bd81cc5874e43ed9896cf6180.tar.bz2
c++: template operator lookup caching
Jason's fix to retain operator lookups inside dependent lambda functions turns out to be needed on the modules branch for all template functions. Because the context for that lookup no longer exists in imports. There were also a couple of shortcomings, which this patch fixes. (a) we conflate 'we found nothing' and 'we can redo this at instantiation time'. Fixed by making the former produce error_mark_node. That needs a fix in name-lookup to know that finding a binding containing error_mark_node, means 'stop looking' you found nothing. (b) we'd continually do lookups for every operator, if nothing needed to be retained. Fixed by always caching that information, and then dealing with it when pushing the bindings. (c) if what we found was that find by a global namespace lookup, we'd not cache that. But that'd cause us to either find decls declared after the template, potentially hiding those we expected to find. So don't do that check. This still retains only recording on lambdas. As the comment says, we could enable for all templates. gcc/cp/ * decl.c (poplevel): A local-binding tree list holds the name in TREE_PURPOSE. * name-lookup.c (update_local_overload): Add id to TREE_PURPOSE. (lookup_name_1): Deal with local-binding error_mark_node marker. (op_unqualified_lookup): Return error_mark_node for 'nothing found'. Retain global binding, check class binding here. (maybe_save_operator_binding): Reimplement to always cache a result. (push_operator_bindings): Deal with 'ignore' marker. gcc/testsuite/ * g++.dg/lookup/operator-1.C: New. * g++.dg/lookup/operator-2.C: New.
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d1af63e..5e17e4d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -692,8 +692,18 @@ poplevel (int keep, int reverse, int functionbody)
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
{
- decl = TREE_CODE (link) == TREE_LIST ? TREE_VALUE (link) : link;
- tree name = OVL_NAME (decl);
+ tree name;
+ if (TREE_CODE (link) == TREE_LIST)
+ {
+ decl = TREE_VALUE (link);
+ name = TREE_PURPOSE (link);
+ gcc_checking_assert (name);
+ }
+ else
+ {
+ decl = link;
+ name = DECL_NAME (decl);
+ }
/* Remove the binding. */
if (TREE_CODE (decl) == LABEL_DECL)