aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2017-10-12 17:49:35 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2017-10-12 17:49:35 +0000
commit62e1c6780d7794bd000a15b2fdbfa65dd63a223c (patch)
tree6c49c1da19c243f1bf486dfc0d725c89243b26c5 /gcc/cp/parser.c
parent7a866e7e316df13b04a84a8d5426b43d016573ea (diff)
downloadgcc-62e1c6780d7794bd000a15b2fdbfa65dd63a223c.zip
gcc-62e1c6780d7794bd000a15b2fdbfa65dd63a223c.tar.gz
gcc-62e1c6780d7794bd000a15b2fdbfa65dd63a223c.tar.bz2
C/C++: add fix-it hints for various missing symbols
The patch improves our C/C++ frontends' handling of missing symbols, by making c_parser_require and cp_parser_require use "better" locations for the diagnostic, and insert fix-it hints, under certain circumstances (see the comments in the patch for full details). For example, for this code with a missing semicolon: $ cat test.c int missing_semicolon (void) { return 42 } trunk currently emits: test.c:4:1: error: expected ';' before '}' token } ^ This patch adds a fix-it hint for the missing semicolon, and puts the error at the location of the missing semicolon, printing the followup token as a secondary location: test.c:3:12: error: expected ';' before '}' token return 42 ^ ; } ~ More examples can be seen in the test cases. gcc/c-family/ChangeLog: * c-common.c (enum missing_token_insertion_kind): New enum. (get_missing_token_insertion_kind): New function. (maybe_suggest_missing_token_insertion): New function. * c-common.h (maybe_suggest_missing_token_insertion): New decl. gcc/c/ChangeLog: * c-parser.c (c_parser_require): Add "type_is_unique" param and use it to guard calls to maybe_suggest_missing_token_insertion. (c_parser_parms_list_declarator): Override default value of new "type_is_unique" param to c_parser_require. (c_parser_asm_statement): Likewise. * c-parser.h (c_parser_require): Add "type_is_unique" param, defaulting to true. gcc/cp/ChangeLog: * parser.c (get_required_cpp_ttype): New function. (cp_parser_error_1): Call it, using the result to call maybe_suggest_missing_token_insertion. gcc/testsuite/ChangeLog: * c-c++-common/cilk-plus/AN/parser_errors.c: Update expected output to reflect changes to reported locations of missing symbols. * c-c++-common/cilk-plus/AN/parser_errors2.c: Likewise. * c-c++-common/cilk-plus/AN/parser_errors3.c: Likewise. * c-c++-common/cilk-plus/AN/pr61191.c: Likewise. * c-c++-common/gomp/pr63326.c: Likewise. * c-c++-common/missing-close-symbol.c: Likewise, also update for new fix-it hints. * c-c++-common/missing-symbol.c: Likewise, also add test coverage for missing colon in ternary operator. * g++.dg/cpp1y/digit-sep-neg.C: Likewise. * g++.dg/cpp1y/pr65202.C: Likewise. * g++.dg/missing-symbol-2.C: New test case. * g++.dg/other/do1.C: Update expected output to reflect changes to reported locations of missing symbols. * g++.dg/parse/error11.C: Likewise. * g++.dg/template/error11.C: Likewise. * gcc.dg/missing-symbol-2.c: New test case. * gcc.dg/missing-symbol-3.c: New test case. * gcc.dg/noncompile/940112-1.c: Update expected output to reflect changes to reported locations of missing symbols. * gcc.dg/noncompile/971104-1.c: Likewise. * obj-c++.dg/exceptions-6.mm: Likewise. * obj-c++.dg/pr48187.mm: Likewise. * objc.dg/exceptions-6.m: Likewise. From-SVN: r253690
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b668b59..810e2b7 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2788,6 +2788,40 @@ get_matching_symbol (required_token token_desc)
}
}
+/* Attempt to convert TOKEN_DESC from a required_token to an
+ enum cpp_ttype, returning CPP_EOF if there is no good conversion. */
+
+static enum cpp_ttype
+get_required_cpp_ttype (required_token token_desc)
+{
+ switch (token_desc)
+ {
+ case RT_SEMICOLON:
+ return CPP_SEMICOLON;
+ case RT_OPEN_PAREN:
+ return CPP_OPEN_PAREN;
+ case RT_CLOSE_BRACE:
+ return CPP_CLOSE_BRACE;
+ case RT_OPEN_BRACE:
+ return CPP_OPEN_BRACE;
+ case RT_CLOSE_SQUARE:
+ return CPP_CLOSE_SQUARE;
+ case RT_OPEN_SQUARE:
+ return CPP_OPEN_SQUARE;
+ case RT_COMMA:
+ return CPP_COMMA;
+ case RT_COLON:
+ return CPP_COLON;
+ case RT_CLOSE_PAREN:
+ return CPP_CLOSE_PAREN;
+
+ default:
+ /* Use CPP_EOF as a "no completions possible" code. */
+ return CPP_EOF;
+ }
+}
+
+
/* Subroutine of cp_parser_error and cp_parser_required_error.
Issue a diagnostic of the form
@@ -2799,9 +2833,12 @@ get_matching_symbol (required_token token_desc)
This bypasses the check for tentative passing, and potentially
adds material needed by cp_parser_required_error.
- If MISSING_TOKEN_DESC is not RT_NONE, and MATCHING_LOCATION is not
- UNKNOWN_LOCATION, then we have an unmatched symbol at
- MATCHING_LOCATION; highlight this secondary location. */
+ If MISSING_TOKEN_DESC is not RT_NONE, then potentially add fix-it hints
+ suggesting insertion of the missing token.
+
+ Additionally, if MATCHING_LOCATION is not UNKNOWN_LOCATION, then we
+ have an unmatched symbol at MATCHING_LOCATION; highlight this secondary
+ location. */
static void
cp_parser_error_1 (cp_parser* parser, const char* gmsgid,
@@ -2840,6 +2877,14 @@ cp_parser_error_1 (cp_parser* parser, const char* gmsgid,
if (missing_token_desc != RT_NONE)
{
+ /* Potentially supply a fix-it hint, suggesting to add the
+ missing token immediately after the *previous* token.
+ This may move the primary location within richloc. */
+ enum cpp_ttype ttype = get_required_cpp_ttype (missing_token_desc);
+ location_t prev_token_loc
+ = cp_lexer_previous_token (parser->lexer)->location;
+ maybe_suggest_missing_token_insertion (&richloc, ttype, prev_token_loc);
+
/* If matching_location != UNKNOWN_LOCATION, highlight it.
Attempt to consolidate diagnostics by printing it as a
secondary range within the main diagnostic. */