From: John McCall Date: Tue, 7 Sep 2010 18:31:03 +0000 (+0000) Subject: Improve error recovery when we see ':' and expect a ';'. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=837b1a37116cf4e64f8bb7db34982dee1fba7647;p=clang Improve error recovery when we see ':' and expect a ';'. I, at least, make this typo all the time. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113243 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index ca06ba72f6..02802773a0 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -133,6 +133,13 @@ SourceLocation Parser::MatchRHSPunctuation(tok::TokenKind RHSTok, return R; } +static bool IsCommonTypo(tok::TokenKind ExpectedTok, const Token &Tok) { + switch (ExpectedTok) { + case tok::semi: return Tok.is(tok::colon); // : for ; + default: return false; + } +} + /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the /// input. If so, it is consumed and false is returned. /// @@ -146,6 +153,19 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID, return false; } + // Detect common single-character typos and resume. + if (IsCommonTypo(ExpectedTok, Tok)) { + SourceLocation Loc = Tok.getLocation(); + Diag(Loc, DiagID) + << Msg + << FixItHint::CreateReplacement(SourceRange(Loc), + getTokenSimpleSpelling(ExpectedTok)); + ConsumeAnyToken(); + + // Pretend there wasn't a problem. + return false; + } + const char *Spelling = 0; SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); if (EndLoc.isValid() && diff --git a/test/Parser/objc-interfaces.m b/test/Parser/objc-interfaces.m index aac3faa435..0ae17f15ee 100644 --- a/test/Parser/objc-interfaces.m +++ b/test/Parser/objc-interfaces.m @@ -3,6 +3,6 @@ // Test features and error recovery for objc interfaces. @interface INTF -- (int*) foo2 __attribute__((deprecated)) : (int) x1 __attribute__((deprecated)); // expected-error {{expected ';' after method prototype}} +- (int*) foo2 __attribute__((deprecated)) : (int) x1 __attribute__((deprecated)); // expected-error {{expected ';' after method prototype}} expected-error {{method type specifier must start with '-' or '+'}} @end diff --git a/test/Parser/recovery.c b/test/Parser/recovery.c index 6cd95da878..1b33f0225b 100644 --- a/test/Parser/recovery.c +++ b/test/Parser/recovery.c @@ -78,3 +78,9 @@ void foo() { // rdar://7980651 typedef int intptr_t; // expected-note {{'intptr_t' declared here}} void bar(intptr y); // expected-error {{unknown type name 'intptr'; did you mean 'intptr_t'?}} + +void test1(void) { + int x = 2: // expected-error {{expected ';' at end of declaration}} + int y = x; + int z = y; +}