public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-3633] c++: Hash table iteration for namespace-member spelling suggestions
@ 2020-10-02 18:32 Nathan Sidwell
0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2020-10-02 18:32 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7ee1c0413e251ff0b6a6d526209ef038b9835320
commit r11-3633-g7ee1c0413e251ff0b6a6d526209ef038b9835320
Author: Nathan Sidwell <nathan@acm.org>
Date: Fri Oct 2 11:13:26 2020 -0700
c++: Hash table iteration for namespace-member spelling suggestions
For 'no such binding' errors, we iterate over binding levels to find a
close match. At the namespace level we were using DECL_ANTICIPATED to
skip undeclared builtins. But (a) there are other unnameable things
there and (b) decl-anticipated is about to go away. This changes the
namespace scanning to iterate over the hash table, and look at
non-hidden bindings. This does mean we look at fewer strings
(hurrarh), but the order we meet them is somewhat 'random'. Our
distance measure is not very fine grained, and a couple of testcases
change their suggestion. I notice for the c/c++ common one, we now
match the output of the C compiler. For the other one we think 'int'
and 'int64_t' have the same distance from 'int64', and now meet the
former first. That's a little unfortunate. If it's too problematic I
suppose we could sort the strings via an intermediate array before
measuring distance.
gcc/cp/
* name-lookup.c (consider_decl): New, broken out of ...
(consider_binding_level): ... here. Iterate the hash table for
namespace bindings.
gcc/testsuite/
* c-c++-common/spellcheck-reserved.c: Adjust diagnostic.
* g++.dg/spellcheck-typenames.C: Adjust diagnostic.
Diff:
---
gcc/cp/name-lookup.c | 126 +++++++++++++++--------
gcc/testsuite/c-c++-common/spellcheck-reserved.c | 2 +-
gcc/testsuite/g++.dg/spellcheck-typenames.C | 4 +-
3 files changed, 87 insertions(+), 45 deletions(-)
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 6204444f3a6..4024ceaa74b 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6106,6 +6106,39 @@ qualified_namespace_lookup (tree scope, name_lookup *lookup)
return found;
}
+static void
+consider_decl (tree decl, best_match <tree, const char *> &bm,
+ bool consider_impl_names)
+{
+ /* Skip compiler-generated variables (e.g. __for_begin/__for_end
+ within range for). */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl))
+ return;
+
+ tree suggestion = DECL_NAME (decl);
+ if (!suggestion)
+ return;
+
+ /* Don't suggest names that are for anonymous aggregate types, as
+ they are an implementation detail generated by the compiler. */
+ if (IDENTIFIER_ANON_P (suggestion))
+ return;
+
+ const char *suggestion_str = IDENTIFIER_POINTER (suggestion);
+
+ /* Ignore internal names with spaces in them. */
+ if (strchr (suggestion_str, ' '))
+ return;
+
+ /* Don't suggest names that are reserved for use by the
+ implementation, unless NAME began with an underscore. */
+ if (!consider_impl_names
+ && name_reserved_for_implementation_p (suggestion_str))
+ return;
+
+ bm.consider (suggestion_str);
+}
+
/* Helper function for lookup_name_fuzzy.
Traverse binding level LVL, looking for good name matches for NAME
(and BM). */
@@ -6129,54 +6162,63 @@ consider_binding_level (tree name, best_match <tree, const char *> &bm,
with an underscore. */
bool consider_implementation_names = (IDENTIFIER_POINTER (name)[0] == '_');
- for (tree t = lvl->names; t; t = TREE_CHAIN (t))
- {
- tree d = t;
-
- /* OVERLOADs or decls from using declaration are wrapped into
- TREE_LIST. */
- if (TREE_CODE (d) == TREE_LIST)
- d = OVL_FIRST (TREE_VALUE (d));
-
- /* Don't use bindings from implicitly declared functions,
- as they were likely misspellings themselves. */
- if (TREE_TYPE (d) == error_mark_node)
- continue;
-
- /* Skip anticipated decls of builtin functions. */
- if (TREE_CODE (d) == FUNCTION_DECL
- && fndecl_built_in_p (d)
- && DECL_ANTICIPATED (d))
- continue;
+ if (lvl->kind != sk_namespace)
+ for (tree t = lvl->names; t; t = TREE_CHAIN (t))
+ {
+ tree d = t;
- /* Skip compiler-generated variables (e.g. __for_begin/__for_end
- within range for). */
- if (TREE_CODE (d) == VAR_DECL
- && DECL_ARTIFICIAL (d))
- continue;
+ /* OVERLOADs or decls from using declaration are wrapped into
+ TREE_LIST. */
+ if (TREE_CODE (d) == TREE_LIST)
+ d = OVL_FIRST (TREE_VALUE (d));
- tree suggestion = DECL_NAME (d);
- if (!suggestion)
- continue;
-
- /* Don't suggest names that are for anonymous aggregate types, as
- they are an implementation detail generated by the compiler. */
- if (IDENTIFIER_ANON_P (suggestion))
- continue;
+ /* Don't use bindings from implicitly declared functions,
+ as they were likely misspellings themselves. */
+ if (TREE_TYPE (d) == error_mark_node)
+ continue;
- const char *suggestion_str = IDENTIFIER_POINTER (suggestion);
+ /* If we want a typename, ignore non-types. */
+ if (kind == FUZZY_LOOKUP_TYPENAME
+ && TREE_CODE (STRIP_TEMPLATE (d)) != TYPE_DECL)
+ continue;
- /* Ignore internal names with spaces in them. */
- if (strchr (suggestion_str, ' '))
- continue;
+ consider_decl (d, bm, consider_implementation_names);
+ }
+ else
+ {
+ /* Iterate over the namespace hash table, that'll have fewer
+ entries than the decl list. */
+ tree ns = lvl->this_entity;
- /* Don't suggest names that are reserved for use by the
- implementation, unless NAME began with an underscore. */
- if (name_reserved_for_implementation_p (suggestion_str)
- && !consider_implementation_names)
- continue;
+ hash_table<named_decl_hash>::iterator end
+ (DECL_NAMESPACE_BINDINGS (ns)->end ());
+ for (hash_table<named_decl_hash>::iterator iter
+ (DECL_NAMESPACE_BINDINGS (ns)->begin ()); iter != end; ++iter)
+ {
+ tree binding = *iter;
+ tree value = NULL_TREE;
- bm.consider (suggestion_str);
+ if (STAT_HACK_P (binding))
+ {
+ if (!STAT_TYPE_HIDDEN_P (binding)
+ && STAT_TYPE (binding))
+ consider_decl (STAT_TYPE (binding), bm,
+ consider_implementation_names);
+ else if (!STAT_DECL_HIDDEN_P (binding))
+ value = STAT_DECL (binding);
+ }
+ else
+ value = binding;
+
+ value = ovl_skip_hidden (value);
+ if (value)
+ {
+ value = OVL_FIRST (value);
+ if (!(kind == FUZZY_LOOKUP_TYPENAME
+ && TREE_CODE (STRIP_TEMPLATE (value)) != TYPE_DECL))
+ consider_decl (value, bm, consider_implementation_names);
+ }
+ }
}
}
diff --git a/gcc/testsuite/c-c++-common/spellcheck-reserved.c b/gcc/testsuite/c-c++-common/spellcheck-reserved.c
index ed292f2bae0..175ba4a2e0f 100644
--- a/gcc/testsuite/c-c++-common/spellcheck-reserved.c
+++ b/gcc/testsuite/c-c++-common/spellcheck-reserved.c
@@ -30,7 +30,7 @@ void test (const char *buf, char ch)
{
__builtin_strtchr (buf, ch); /* { dg-line misspelled_reserved } */
/* { dg-warning "did you mean '__builtin_strchr'" "" { target c } misspelled_reserved } */
- /* { dg-error "'__builtin_strtchr' was not declared in this scope; did you mean '__builtin_strrchr'\\?" "" { target c++ } misspelled_reserved } */
+ /* { dg-error "'__builtin_strtchr' was not declared in this scope; did you mean '__builtin_strchr'\\?" "" { target c++ } misspelled_reserved } */
}
/* Similarly for a name that begins with a single underscore. */
diff --git a/gcc/testsuite/g++.dg/spellcheck-typenames.C b/gcc/testsuite/g++.dg/spellcheck-typenames.C
index 6adf724a3b7..ff53ecc6303 100644
--- a/gcc/testsuite/g++.dg/spellcheck-typenames.C
+++ b/gcc/testsuite/g++.dg/spellcheck-typenames.C
@@ -54,11 +54,11 @@ struct some_thing test_6; // { dg-error "aggregate 'some_thing test_6' has incom
{ dg-end-multiline-output "" } */
typedef long int64_t;
-int64 i; // { dg-error "1: 'int64' does not name a type; did you mean 'int64_t'?" }
+int64 i; // { dg-error "1: 'int64' does not name a type; did you mean 'int'?" }
/* { dg-begin-multiline-output "" }
int64 i;
^~~~~
- int64_t
+ int
{ dg-end-multiline-output "" } */
/* Verify that gcc doesn't offer nonsensical suggestions. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-10-02 18:32 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-02 18:32 [gcc r11-3633] c++: Hash table iteration for namespace-member spelling suggestions Nathan Sidwell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).