[cfe-commits] r113202 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Parse/Parser.h lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseObjc.cpp lib/Parse/ParseStmt.cpp lib/Parse/Parser.cpp test/FixIt/fixit-objc.m
Douglas Gregor
dgregor at apple.com
Tue Sep 7 08:23:11 PDT 2010
Author: dgregor
Date: Tue Sep 7 10:23:11 2010
New Revision: 113202
URL: http://llvm.org/viewvc/llvm-project?rev=113202&view=rev
Log:
Improve recovery when there is a stray ']' or ')' before the ';' at
the end of a statement. Fixes <rdar://problem/6896493>.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/test/FixIt/fixit-objc.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Sep 7 10:23:11 2010
@@ -124,6 +124,8 @@
def err_expected_semi_after : Error<"expected ';' after %0">;
def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
def err_expected_semi_after_expr : Error<"expected ';' after expression">;
+def err_extraneous_token_before_semi : Error<"extraneous '%0' before ';'">;
+
def err_expected_semi_after_method_proto : Error<
"expected ';' after method prototype">;
def err_expected_semi_after_namespace_name : Error<
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Sep 7 10:23:11 2010
@@ -464,6 +464,13 @@
const char *DiagMsg = "",
tok::TokenKind SkipToTok = tok::unknown);
+ /// \brief The parser expects a semicolon and, if present, will consume it.
+ ///
+ /// If the next token is not a semicolon, this emits the specified diagnostic,
+ /// or, if there's just some closing-delimiter noise (e.g., ')' or ']') prior
+ /// to the semicolon, consumes that extra token.
+ bool ExpectAndConsumeSemi(unsigned DiagID);
+
//===--------------------------------------------------------------------===//
// Scope manipulation
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Sep 7 10:23:11 2010
@@ -313,8 +313,9 @@
// Eat ';'.
DeclEnd = Tok.getLocation();
ExpectAndConsume(tok::semi,
- GNUAttr ? diag::err_expected_semi_after_attribute_list :
- diag::err_expected_semi_after_namespace_name, "", tok::semi);
+ GNUAttr ? diag::err_expected_semi_after_attribute_list
+ : diag::err_expected_semi_after_namespace_name,
+ "", tok::semi);
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
IdentLoc, NamespcName, Attr);
@@ -422,7 +423,7 @@
MatchRHSPunctuation(tok::r_paren, LParenLoc);
DeclEnd = Tok.getLocation();
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
+ ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
AssertExpr.take(),
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Sep 7 10:23:11 2010
@@ -1731,7 +1731,7 @@
}
// Otherwise, eat the semicolon.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+ ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.take()));
}
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Tue Sep 7 10:23:11 2010
@@ -137,7 +137,7 @@
return StmtError();
}
// Otherwise, eat the semicolon.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+ ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get()));
}
@@ -507,7 +507,7 @@
// FIXME: Use attributes?
// Eat the semicolon at the end of stmt and convert the expr into a
// statement.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+ ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.get()));
}
}
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Sep 7 10:23:11 2010
@@ -162,6 +162,25 @@
return true;
}
+bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
+ if (Tok.is(tok::semi) || Tok.is(tok::code_completion)) {
+ ConsumeAnyToken();
+ return false;
+ }
+
+ if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) &&
+ NextToken().is(tok::semi)) {
+ Diag(Tok, diag::err_extraneous_token_before_semi)
+ << PP.getSpelling(Tok)
+ << FixItHint::CreateRemoval(Tok.getLocation());
+ ConsumeAnyToken(); // The ')' or ']'.
+ ConsumeToken(); // The ';'.
+ return false;
+ }
+
+ return ExpectAndConsume(tok::semi, DiagID);
+}
+
//===----------------------------------------------------------------------===//
// Error recovery.
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/test/FixIt/fixit-objc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-objc.m?rev=113202&r1=113201&r2=113202&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-objc.m (original)
+++ cfe/trunk/test/FixIt/fixit-objc.m Tue Sep 7 10:23:11 2010
@@ -1,6 +1,7 @@
+// RUN: %clang_cc1 -pedantic -verify %s
// RUN: cp %s %t
-// RUN: %clang_cc1 -pedantic -fixit -x objective-c %t
-// RUN: %clang_cc1 -pedantic -verify -x objective-c %t
+// RUN: not %clang_cc1 -pedantic -fixit -x objective-c %t
+// RUN: %clang_cc1 -pedantic -Werror -x objective-c %t
/* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
@@ -10,28 +11,31 @@
@protocol X;
void foo() {
- <X> *P; // should be fixed to 'id<X>'.
+ <X> *P; // expected-warning{{protocol qualifiers without 'id' is archaic}}
}
@class A;
@class NSString;
@interface Test
-- (void)test:(NSString *)string;
+- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
@property (copy) NSString *property;
@end
-void g(NSString *a);
-void h(id a);
+void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}}
+void h(id a); // expected-note 2{{passing argument to parameter 'a' here}}
void f(Test *t) {
- NSString *a = "Foo";
- id b = "Foo";
- A* c = "Foo"; // expected-warning {{incompatible pointer types initializing 'A *' with an expression of type 'char [4]'}}
- g("Foo");
- h("Foo");
- h(("Foo"));
- [t test:"Foo"];
- t.property = "Foo";
+ NSString *a = "Foo"; // expected-warning {{incompatible pointer types initializing 'NSString *' with an expression of type 'char [4]'}}
+ id b = "Foo"; // expected-warning {{incompatible pointer types initializing 'id' with an expression of type 'char [4]'}}
+ g("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'NSString *'}}
+ h("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
+ h(("Foo")); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
+ [t test:"Foo"]; // expected-warning{{incompatible pointer types sending 'char [4]' to parameter of type 'NSString *'}}
+ t.property = "Foo"; // expected-warning{{incompatible pointer types assigning to 'NSString *' from 'char [4]'}}
+
+ // <rdar://problem/6896493>
+ [t test:@"Foo"]]; // expected-error{{extraneous ']' before ';'}}
+ g(@"Foo")); // expected-error{{extraneous ')' before ';'}}
}
More information about the cfe-commits
mailing list