]> granicus.if.org Git - clang/commitdiff
Continue parsing an expression list even after an error is encountered.
authorKaelyn Takata <rikka@google.com>
Mon, 14 Jul 2014 22:48:10 +0000 (22:48 +0000)
committerKaelyn Takata <rikka@google.com>
Mon, 14 Jul 2014 22:48:10 +0000 (22:48 +0000)
Otherwise, multiple errors such as having unknown identifiers for two
arguments won't be diagnosed properly (e.g. only the first one would
have a diagnostic message if typo correction fails even though both
would be diagnosed if typo correction suggests a replacement).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213003 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseExpr.cpp
test/Parser/expressions.c
test/SemaCXX/types_compatible_p.cpp
test/SemaObjC/error-missing-getter.m

index 0c231d63ea74a67fa570a74efe2de618fceebee5..4a1742c2c086d41ec156b2c0b400f5f0b19d8c0b 100644 (file)
@@ -2309,6 +2309,7 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr*> &Exprs,
                                                          Expr *Data,
                                                          ArrayRef<Expr *> Args),
                                  Expr *Data) {
+  bool SawError = false;
   while (1) {
     if (Tok.is(tok::code_completion)) {
       if (Completer)
@@ -2328,13 +2329,15 @@ bool Parser::ParseExpressionList(SmallVectorImpl<Expr*> &Exprs,
 
     if (Tok.is(tok::ellipsis))
       Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());    
-    if (Expr.isInvalid())
-      return true;
-
-    Exprs.push_back(Expr.get());
+    if (Expr.isInvalid()) {
+      SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
+      SawError = true;
+    } else {
+      Exprs.push_back(Expr.get());
+    }
 
     if (Tok.isNot(tok::comma))
-      return false;
+      return SawError;
     // Move to the next argument, remember where the comma was.
     CommaLocs.push_back(ConsumeToken());
   }
index 95d6fb354f3ff17f852dd0abf60c58094fefeda5..64b44470f7e745598d92cac9394b9d645d2a3826 100644 (file)
@@ -67,3 +67,9 @@ void func_16992 () {
   int x3 = __alignof int;         // expected-error {{expected parentheses around type name in __alignof expression}}
   int x4 = _Alignof int;          // expected-error {{expected parentheses around type name in _Alignof expression}}
 }
+
+void callee(double, double);
+void test8() {
+  callee(foobar,   // expected-error {{use of undeclared identifier 'foobar'}}
+         fizbin);  // expected-error {{use of undeclared identifier 'fizbin'}}
+}
index ebff53f7c009205e6c4b10cf16aa24f74bc51a9d..29e06405adeae1fd1cd64d6a68db437a99b76f9a 100644 (file)
@@ -4,5 +4,6 @@
 // Test that GNU C extension __builtin_types_compatible_p() is not available in C++ mode.
 
 int f() {
-  return __builtin_types_compatible_p(int, const int); // expected-error{{}}
+  return __builtin_types_compatible_p(int, const int); // expected-error{{expected '(' for function-style cast or type construction}} \
+                                                       // expected-error{{expected expression}}
 }
index 3dce858837aa96e7fb24e9f5941759bcd5b0103d..13dc8e5bb13fbc6939d8b99a69fb4cf51e40c7bd 100644 (file)
@@ -27,7 +27,8 @@ int func2 (int arg) {
     if (TestClass.setterOnly) { // expected-error {{no getter method for read from property}}
       TestClass.setterOnly = 1;
     }
-    func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}}
+    func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}} \
+                                       // expected-error {{use of undeclared identifier 'x'}}
     int i = TestClass.setterOnly + 1;  // expected-error {{no getter method for read from property}}
     return TestClass.setterOnly + 1;   // expected-error {{no getter method for read from property}}
 }