summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-10-29 23:53:50 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-10-29 23:53:50 +0000
commit7e2de6df10b532be4e66025e318f68a0ebf2c408 (patch)
treead3bc9e9751e07705061fb4f0700df96b7158e4a /include
parentb2bf438c02e885ddcd89e3f372fe88d9c3a58fd9 (diff)
C++: simplify output from suggest_alternatives_for
In the C++ FE, after emitting various errors about unrecognized names, the parser can call suggest_alternatives_for and/or suggest_alternative_in_explicit_scope. These can issue zero or more suggestions for the unrecognized name, or various other "note" diagnostics suggesting how to fix the problem. For example, currently g++ emits: t.cc:12:3: error: 'gtk_widget_showall' was not declared in this scope 12 | gtk_widget_showall (w); | ^~~~~~~~~~~~~~~~~~ t.cc:12:3: note: suggested alternative: 'gtk_widget_show_all' 12 | gtk_widget_showall (w); | ^~~~~~~~~~~~~~~~~~ | gtk_widget_show_all This patch consolidates the common case when there is a single candidate, so that the error can issue a fix-it hint directly. This simplifies the above to: t.cc:12:3: error: 'gtk_widget_showall' was not declared in this scope; did you mean 'gtk_widget_show_all'? 12 | gtk_widget_showall (w); | ^~~~~~~~~~~~~~~~~~ | gtk_widget_show_all omitting the second "note" diagnostic. Doing so requires changing the above "suggest_" functions so that rather than being called after "error" and emitting a note directly, they are called before the "error", and return a name_hint, which can contain a suggestion and/or a deferred diagnostic. The "single candidate" case is handled via a suggestion, and the "multiple candidates" case via a new subclass of deferred_diagnostic. There was some complication due to the fact that we don't always have enough location information to issue a fix-it hint. Specifically, for the case in qualified_name_lookup_error, the location is that of the name, but the location of the qualifier prefix isn't reliably available. For some hints, e.g. spell-corrections, the replacement is of the name, and for others, e.g. parent namespaces, it's for the qualified name. The patch addresses this by splitting this case out into a new "suggest_alternatives_in_other_namespaces" function, for which fix-it hints aren't issued. Another complication is that of emitting a note when --param cxx-max-namespaces-for-diagnostic-help is reached. The patch emulates the existing behavior by emitting the note from a deferred_diagnostic. This potentially needs to co-exist with another deferred_diagnostic, so it works as a decorator around any other such deferred_diagnostic. Doing so requires slightly extending class name_hint. On adding test coverage for the various cases, I discovered that after emitting a "FOO is not a namespace-name" error, we also emit a "expected namespace-name before" error. The patch removes this second error for the case where it's redundant, simplifying this case from e.g.: spellcheck-ns.C:10:24: error: 'inner_ms' is not a namespace-name 10 | using namespace outer::inner_ms; | ^~~~~~~~ spellcheck-ns.C:10:24: note: suggested alternative: 'inner_ns' 10 | using namespace outer::inner_ms; | ^~~~~~~~ | inner_ns spellcheck-ns.C:10:32: error: expected namespace-name before ';' token 10 | using namespace outer::inner_ms; | ^ to: spellcheck-ns.C:10:24: error: 'inner_ms' is not a namespace-name; did you mean 'inner_ns'? 10 | using namespace outer::inner_ms; | ^~~~~~~~ | inner_ns include/ChangeLog: * unique-ptr.h (gnu::move): Generalize so it applies to all lvalue references, rather than just to unique_ptr values. gcc/c-family/ChangeLog: * name-hint.h (name_hint::take_deferred): New member function. gcc/c/ChangeLog: * c-decl.c (implicit_decl_warning): Update "is there a suggestion" logic for change to name_hint::operator bool. (undeclared_variable): Likewise. * c-parser.c (c_parser_declaration_or_fndef): Likewise. (c_parser_parameter_declaration): Likewise. gcc/cp/ChangeLog: * cp-name-hint.h: New file. * cp-tree.h (expr_to_string): New decl. (suggest_alternatives_for): Move to cp-name-hint.h, changing return type from bool to name_hint. (suggest_alternative_in_explicit_scope): Likewise. * error.c: Define INCLUDE_UNIQUE_PTR. Include "cp-name-hint.h". (expr_to_string): Make non-static. (qualified_name_lookup_error): For the non-"::" case, take responsibity for issuing any suggestion from suggest_alternative_in_explicit_scope, as it changes from returning a bool to returning a name_hint. Replace fallback call to suggest_alternatives_for to a call to suggest_alternatives_in_other_namespaces, capturing the fact that we don't have enough location information to issue a fix-it hint for this case. Update the error to support emitting a fix-it hint where appropriate. For the "::" case, take responsibility for issuing any suggestion from suggest_alternatives_for, supporting emitting a fix-it hint. * lex.c: Define INCLUDE_UNIQUE_PTR. Include "gcc-rich-location.h" and "cp-name-hint.h". (unqualified_name_lookup_error): Take responsibility for issuing any suggestion from suggest_alternatives_for, supporting emitting a fix-it hint. * name-lookup.c (class namespace_limit_reached): New subclass of deferred_diagnostic. (class show_candidate_location): Likewise. (class suggest_alternatives): Likewise. (class namespace_hints): New class. (suggest_alternatives_for): Convert return type from bool to name_hint, replacing all direct diagnostic emission by setting suggestions on the return value, or creating deferred diagnostics. Specifically, split out initial traversal of namespaces into namespace_hints' ctor, and maybe_decorate_with_limit, and move the rest of the implementation to namespace_hints::convert_candidates_to_name_hint and suggest_alternatives_for_1. (namespace_hints::namespace_hints): New ctor, adapted from suggest_alternatives_for's initial namespace traversal, storing location and name, and converting locals "candidates", "limited" and "limit" into members. (namespace_hints::convert_candidates_to_name_hint): New member function. (namespace_hints::maybe_decorate_with_limit): New member function. (suggest_alternatives_for_1): New function, based on second half of old implementation of suggest_alternatives_for, converting from immediate emission of suggestions to using name_hint. (suggest_alternatives_in_other_namespaces): New function. (maybe_suggest_missing_std_header): Convert from immediate emission of suggestions to using name_hint, moving emission implementation to... (class missing_std_header): New subclass of deferred_diagnostic. (maybe_suggest_missing_header): Convert return type from bool to name_hint. (suggest_alternative_in_explicit_scope): Convert from immediate emission of suggestions to using name_hint. * parser.c: Replace include of "c-family/name-hint.h" with "cp-name-hint.h". (cp_parser_diagnose_invalid_type_name): Update "is there a suggestion" logic for change to name_hint::operator bool. Take responsibility for emitting fix-it hints from suggest_alternative_in_explicit_scope. (cp_parser_namespace_name): Take responsibility for emitting fix-it hints from suggest_alternative_in_explicit_scope. Don't emit the "expected namespace-name" error if we've already emitted an "is not a namespace-name" error. gcc/testsuite/ChangeLog: * c-c++-common/spellcheck-reserved.c: Update expected output for C++ for merger of "did you mean" suggestions into the error message. * g++.dg/ext/builtin3.C: Update expected output for merger of "did you mean" suggestion into the error. * g++.dg/lookup/error1.C: Likewise. * g++.dg/lookup/pr77549.C: Likewise. * g++.dg/lookup/pr80913.C: Likewise. * g++.dg/lookup/suggestions1.C: Likewise. * g++.dg/lookup/suggestions2.C: New test. * g++.dg/overload/koenig1.C: Update expected output as above. * g++.dg/spellcheck-identifiers-2.C: Likewise. * g++.dg/spellcheck-identifiers.C: Likewise. * g++.dg/spellcheck-ns.C: New test. * g++.dg/spellcheck-pr77829.C: Update expected output as above. * g++.dg/spellcheck-pr78656.C: Likewise. * g++.dg/spellcheck-pr79298.C: Likewise, adding -fdiagnostics-show-caret to options. * g++.dg/spellcheck-pr80177.C: Likewise. * g++.dg/spellcheck-single-vs-multiple.C: New test. * g++.dg/spellcheck-typenames.C: Update expected output as above. * g++.dg/template/static10.C: Likewise. * g++.old-deja/g++.mike/ns5.C: Likewise. * g++.old-deja/g++.mike/ns7.C: Likewise. * g++.old-deja/g++.ns/koenig5.C: Likewise. * g++.old-deja/g++.other/lineno5.C: Likewise. libstdc++-v3/ChangeLog: * testsuite/17_intro/using_namespace_std_exp_neg.cc: Remove "expected namespace-name before" error. * testsuite/17_intro/using_namespace_std_tr1_neg.cc: Likewise. From-SVN: r265610
Diffstat (limited to 'include')
-rw-r--r--include/ChangeLog5
-rw-r--r--include/unique-ptr.h12
2 files changed, 11 insertions, 6 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index e2e115a2eed..4584f7cb8af 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2018-10-29 David Malcolm <dmalcolm@redhat.com>
+
+ * unique-ptr.h (gnu::move): Generalize so it applies to all
+ lvalue references, rather than just to unique_ptr values.
+
2018-07-26 Martin Liska <mliska@suse.cz>
PR lto/86548
diff --git a/include/unique-ptr.h b/include/unique-ptr.h
index a12c2196173..a7255fc5546 100644
--- a/include/unique-ptr.h
+++ b/include/unique-ptr.h
@@ -336,13 +336,13 @@ operator>= (const detail::unique_ptr_base<T, D> &x,
{ return !(x < y); }
/* std::move "emulation". This is as simple as it can be -- no
- attempt is made to emulate rvalue references. Instead relies on
- the fact that gnu::unique_ptr has move semantics like
- std::auto_ptr. I.e., copy/assignment actually moves. */
+ attempt is made to emulate rvalue references. This relies on T
+ having move semantics like std::auto_ptr.
+ I.e., copy/assignment actually moves. */
-template<typename T, typename D>
-unique_ptr<T, D>
-move (unique_ptr<T, D> v)
+template<typename T>
+const T&
+move (T& v)
{
return v;
}