[This patch kit is effectively just one patch; I've split it up into 3 parts, in the hope of making it easier to review: the c-family parts, the C parts, and the C++ parts]
This patch adds a hint to the user to various errors generated in the C frontend by: c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>") c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>") etc (where there's a non-NULL msgid), and in the C++ frontend by: cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE) The hint shows the user where the pertinent open paren or open brace is, which ought to be very helpful for complicated nested collections of parentheses, and somewhat helpful even for simple cases; consider e.g.: ...lots of lines of code... extern "C" { ...lots of lines of code... int test (); EOF where the user currently has to hunt through the source file to find the unclosed '{': test.cc:262:12: error: expected '}' at end of input int test (); ^ With this patch we tell them: test.cc:262:12: error: expected '}' at end of input int test (); ^ test.cc:98:12: note: to match this '{' extern "C" { ^ The patch avoids using a note if the tokens are on the same line, highlighting the unclosed open token with an underline: test.c:3:32: error: expected ')' before ';' token return ((b * b) - (4 * a * c); ~ ^ The bulk of the changes in the patch are to the parsers, done using new classes "matching_braces" and "matching_parens", which stash the location of the opening token during parsing, so that e.g.: if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) return; ...do stuff... c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); becomes: matching_parens parens; if (!parens.require_open (parser)) return; ...do stuff... parens.require_close (parser); The exact implementation of these classes varies somewhat between the C and C++ frontends, to deal with implementation differences between them (I tried to keep them as similar as possible). Successfully bootstrapped®rtested on x86_64-pc-linux-gnu; adds 23 PASS results to gcc.sum; adds 99 PASS results to g++.sum. OK for trunk? gcc/c-family/c-common.c | 17 +- gcc/c-family/c-common.h | 3 +- gcc/c/c-parser.c | 647 ++++++++++------ gcc/c/c-parser.h | 8 +- gcc/cp/parser.c | 821 ++++++++++++++------- gcc/testsuite/c-c++-common/missing-close-symbol.c | 33 + gcc/testsuite/c-c++-common/missing-symbol.c | 50 ++ .../g++.dg/diagnostic/unclosed-extern-c.C | 3 + .../g++.dg/diagnostic/unclosed-function.C | 3 + .../g++.dg/diagnostic/unclosed-namespace.C | 2 + gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C | 3 + gcc/testsuite/g++.dg/parse/pragma2.C | 4 +- gcc/testsuite/gcc.dg/unclosed-init.c | 3 + 13 files changed, 1084 insertions(+), 513 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/missing-close-symbol.c create mode 100644 gcc/testsuite/c-c++-common/missing-symbol.c create mode 100644 gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C create mode 100644 gcc/testsuite/g++.dg/diagnostic/unclosed-function.C create mode 100644 gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C create mode 100644 gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C create mode 100644 gcc/testsuite/gcc.dg/unclosed-init.c -- 1.8.5.3