aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2016-07-20 18:42:11 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2016-07-20 18:42:11 +0000
commit52ed68f71a750260fd926479e41e3f7ad7cd9aa2 (patch)
treeb49c604effb64ec60ec0f92309badfd3781fc6c4 /gcc/cp/parser.c
parent1397e163014843fa6803b3959adfc0011d75bc6a (diff)
downloadgcc-52ed68f71a750260fd926479e41e3f7ad7cd9aa2.zip
gcc-52ed68f71a750260fd926479e41e3f7ad7cd9aa2.tar.gz
gcc-52ed68f71a750260fd926479e41e3f7ad7cd9aa2.tar.bz2
C++ FE: handle misspelled identifiers and typenames
gcc/cp/ChangeLog: PR c/70339 PR c/71858 * name-lookup.c: Include gcc-rich-location.h, spellcheck-tree.h, and parser.h. (suggest_alternatives_for): If no candidates are found, try lookup_name_fuzzy and report if if finds a suggestion. (consider_binding_level): New function. (lookup_name_fuzzy) New function. * parser.c: Include gcc-rich-location.h. (cp_lexer_next_token_is_decl_specifier_keyword): Move most of logic into... (cp_keyword_starts_decl_specifier_p): ...this new function. (cp_parser_diagnose_invalid_type_name): When issuing "does not name a type" errors, attempt to make a suggestion using lookup_name_fuzzy. * parser.h (cp_keyword_starts_decl_specifier_p): New prototype. * search.c (lookup_field_fuzzy_info::fuzzy_lookup_field): Reject types that are not CLASS_TYPE_P, rather than rejecting individual tree codes. gcc/testsuite/ChangeLog: PR c/70339 PR c/71858 * g++.dg/spellcheck-identifiers.C: New test case, based on gcc.dg/spellcheck-identifiers.c. * g++.dg/spellcheck-identifiers-2.C: New test case, based on gcc.dg/spellcheck-identifiers-2.c. * g++.dg/spellcheck-typenames.C: New test case, based on gcc.dg/spellcheck-typenames.c From-SVN: r238538
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c43
1 files changed, 32 insertions, 11 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 84dad48..8fceaed 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-indentation.h"
#include "context.h"
#include "cp-cilkplus.h"
+#include "gcc-rich-location.h"
/* The lexer. */
@@ -937,15 +938,12 @@ cp_lexer_next_token_is_not_keyword (cp_lexer* lexer, enum rid keyword)
return cp_lexer_peek_token (lexer)->keyword != keyword;
}
-/* Return true if the next token is a keyword for a decl-specifier. */
+/* Return true if KEYWORD can start a decl-specifier. */
-static bool
-cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
+bool
+cp_keyword_starts_decl_specifier_p (enum rid keyword)
{
- cp_token *token;
-
- token = cp_lexer_peek_token (lexer);
- switch (token->keyword)
+ switch (keyword)
{
/* auto specifier: storage-class-specifier in C++,
simple-type-specifier in C++0x. */
@@ -985,14 +983,25 @@ cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
return true;
default:
- if (token->keyword >= RID_FIRST_INT_N
- && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
- && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
+ if (keyword >= RID_FIRST_INT_N
+ && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
+ && int_n_enabled_p[keyword - RID_FIRST_INT_N])
return true;
return false;
}
}
+/* Return true if the next token is a keyword for a decl-specifier. */
+
+static bool
+cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (lexer);
+ return cp_keyword_starts_decl_specifier_p (token->keyword);
+}
+
/* Returns TRUE iff the token T begins a decltype type. */
static bool
@@ -3154,7 +3163,19 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
else if (!parser->scope)
{
/* Issue an error message. */
- error_at (location, "%qE does not name a type", id);
+ const char *suggestion = NULL;
+ if (TREE_CODE (id) == IDENTIFIER_NODE)
+ suggestion = lookup_name_fuzzy (id, FUZZY_LOOKUP_TYPENAME);
+ if (suggestion)
+ {
+ gcc_rich_location richloc (location);
+ richloc.add_fixit_misspelled_id (location, suggestion);
+ error_at_rich_loc (&richloc,
+ "%qE does not name a type; did you mean %qs?",
+ id, suggestion);
+ }
+ else
+ error_at (location, "%qE does not name a type", id);
/* If we're in a template class, it's possible that the user was
referring to a type from a base class. For example: