From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100397 invoked by alias); 11 Jul 2017 14:51:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 99149 invoked by uid 89); 11 Jul 2017 14:50:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.9 required=5.0 tests=BAYES_00,GIT_PATCH_2,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=varies, pertinent, hunt X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Jul 2017 14:50:58 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CD70E3B74E for ; Tue, 11 Jul 2017 14:50:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com CD70E3B74E Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=dmalcolm@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com CD70E3B74E Received: from c64.redhat.com (ovpn-112-25.phx2.redhat.com [10.3.112.25]) by smtp.corp.redhat.com (Postfix) with ESMTP id D5E55757CE; Tue, 11 Jul 2017 14:50:55 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 0/3] C/C++: show pertinent open token when missing a close token Date: Tue, 11 Jul 2017 14:51:00 -0000 Message-Id: <1499786685-37297-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes X-SW-Source: 2017-07/txt/msg00534.txt.bz2 [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