]> granicus.if.org Git - clang/commitdiff
hoist some code for handling objc foreach construct out of Declaration processing
authorChris Lattner <sabre@nondot.org>
Sun, 29 Mar 2009 17:27:48 +0000 (17:27 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 29 Mar 2009 17:27:48 +0000 (17:27 +0000)
into ParseForStatement.  Merge two tests into one.

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

include/clang/Parse/Parser.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseStmt.cpp
test/Parser/objc-foreach-error-1.m [deleted file]
test/Parser/objc-foreach-syntax.m

index eb820570b969fd24d47394f2a23cc97e0d084ab3..ca2d706f23a23174439a69e4e2b298089d6738f1 100644 (file)
@@ -809,7 +809,8 @@ private:
   // C99 6.7: Declarations.
   
   DeclGroupPtrTy ParseDeclaration(unsigned Context);
-  DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context);
+  DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
+                                        bool RequireSemi = true);
   DeclGroupPtrTy ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   DeclPtrTy ParseFunctionStatementBody(DeclPtrTy Decl);
   void ParseDeclarationSpecifiers(DeclSpec &DS, 
index 5de4dd4a7c600eaf0b7d45bf218c5273c1102f7c..f80afe3f4b13bf341274cc096673ff3430e870d2 100644 (file)
@@ -257,7 +257,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context) {
 ///         declaration-specifiers init-declarator-list[opt] ';'
 ///[C90/C++]init-declarator-list ';'                             [TODO]
 /// [OMP]   threadprivate-directive                              [TODO]
-Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
+///
+/// If RequireSemi is false, this does not check for a ';' at the end of the
+/// declaration.
+Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
+                                                      bool RequireSemi) {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
   ParseDeclarationSpecifiers(DS);
@@ -275,22 +279,16 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context) {
   
   DeclGroupPtrTy DG =
     ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+
+  // If the client wants to check what comes after the declaration, just return
+  // immediately without checking anything!
+  if (!RequireSemi) return DG;
   
   if (Tok.is(tok::semi)) {
     ConsumeToken();
-    // for(is key; in keys) is error.
-    if (Context == Declarator::ForContext && isTokIdentifier_in())
-      Diag(Tok, diag::err_parse_error);
-    
     return DG;
   }
   
-  // If this is an ObjC2 for-each loop, this is a successful declarator
-  // parse.  The syntax for these looks like:
-  // 'for' '(' declaration 'in' expr ')' statement
-  if (Context == Declarator::ForContext && isTokIdentifier_in())
-    return DG;
-  
   Diag(Tok, diag::err_expected_semi_declation);
   // Skip to end of block or statement
   SkipUntil(tok::r_brace, true, true);
index b1a32decffcf6e0d056fb8f5302ce2f8331d040c..3ca2f02b52bff2ea4532c25e3315413bbb92eea6 100644 (file)
@@ -912,12 +912,18 @@ Parser::OwningStmtResult Parser::ParseForStatement() {
       Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
 
     SourceLocation DeclStart = Tok.getLocation();
-    DeclGroupPtrTy VarDecls = ParseSimpleDeclaration(Declarator::ForContext);
-    // FIXME: Pass in the right location for the end of the declstmt.
-    FirstPart = Actions.ActOnDeclStmt(VarDecls, DeclStart, DeclStart);
-    if ((ForEach = isTokIdentifier_in())) {
+    DeclGroupPtrTy DG = ParseSimpleDeclaration(Declarator::ForContext, false);
+    FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
+    
+    if (Tok.is(tok::semi)) {  // for (int x = 4;
+      ConsumeToken();
+    } else if ((ForEach = isTokIdentifier_in())) {
+      // ObjC: for (id x in expr) 
       ConsumeToken(); // consume 'in'
       SecondPart = ParseExpression();
+    } else {
+      Diag(Tok, diag::err_expected_semi_for);
+      SkipUntil(tok::semi);
     }
   } else {
     Value = ParseExpression();
diff --git a/test/Parser/objc-foreach-error-1.m b/test/Parser/objc-foreach-error-1.m
deleted file mode 100644 (file)
index 16a7ea8..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// RUN: clang-cc -fsyntax-only -verify %s
-
-ce MyList // expected-error {{invalid token after top level declarator}}
-@end
-
-
-@implementation MyList
-- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
-{
-     return 0;
-}
-@end
-
-
-int LOOP();
-
-@implementation MyList (BasicTest)  // expected-error {{cannot find interface declaration for 'MyList'}}
-- (void)compilerTestAgainst {
-MyList * el;  // expected-error {{use of undeclared identifier 'MyList'}}
-     for (el in @"foo")    // expected-error {{use of undeclared identifier 'el'}}
-         { LOOP(); }
-}
-@end
-
index 950fc2f114a33f1da7233dfece7ec1b5d93c2e7e..e6e3ccf12d1a5cde80bd94e3f94d6ac408d99e74 100644 (file)
@@ -1,7 +1,28 @@
 // RUN: clang-cc -fsyntax-only -verify %s
 
-static int test_NSURLGetResourceValueForKey( id keys )
+ce MyList // expected-error {{invalid token after top level declarator}}
+@end
+
+
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
 {
- for ( id key; in keys) {  // expected-error {{parse error}}
-  } 
+     return 0;
+}
+@end
+
+
+int LOOP();
+
+@implementation MyList (BasicTest)  // expected-error {{cannot find interface declaration for 'MyList'}}
+- (void)compilerTestAgainst {
+MyList * el;  // expected-error {{use of undeclared identifier 'MyList'}}
+     for (el in @"foo")    // expected-error {{use of undeclared identifier 'el'}}
+         { LOOP(); }
+}
+@end
+
+
+static int test7(id keys) {
+  for (id key; in keys) ;  // expected-error {{use of undeclared identifier 'in'}}
 }