[cfe-commits] r38847 - in /cfe/cfe/trunk: Parse/ParseDecl.cpp Parse/ParseStmt.cpp Parse/Parser.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h test/Parser/statements.c

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:25:09 PDT 2007


Author: sabre
Date: Wed Jul 11 11:25:08 2007
New Revision: 38847

URL: http://llvm.org/viewvc/llvm-project?rev=38847&view=rev
Log:
Refactor init-declarator-list parsing code to allow for-statements to have
initializers in them.

Modified:
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Parse/ParseStmt.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Parser.h
    cfe/cfe/trunk/test/Parser/statements.c

Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:08 2007
@@ -20,6 +20,60 @@
 // C99 6.7: Declarations.
 //===----------------------------------------------------------------------===//
 
+/// ParseDeclaration - Parse a full 'declaration', which consists of
+/// declaration-specifiers, some number of declarators, and a semicolon.
+/// 'Context' should be a Declarator::TheContext value.
+void Parser::ParseDeclaration(unsigned Context) {
+  // Parse the common declaration-specifiers piece.
+  DeclSpec DS;
+  ParseDeclarationSpecifiers(DS);
+  
+  Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context);
+  ParseDeclarator(DeclaratorInfo);
+  
+  ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+}
+
+void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
+  // At this point, we know that it is not a function definition.  Parse the
+  // rest of the init-declarator-list.
+  while (1) {
+    // must be: decl-spec[opt] declarator init-declarator-list
+    // Parse declarator '=' initializer.
+    if (Tok.getKind() == tok::equal) {
+      ConsumeToken();
+      // FIXME: THIS IS WRONG!!
+      ParseExpression();
+    }
+    
+    
+    // TODO: install declarator.
+    
+    // If we don't have a comma, it is either the end of the list (a ';') or an
+    // error, bail out.
+    if (Tok.getKind() != tok::comma)
+      break;
+    
+    // Consume the comma.
+    ConsumeToken();
+    
+    // Parse the next declarator.
+    D.clear();
+    ParseDeclarator(D);
+  }
+  
+  if (Tok.getKind() == tok::semi) {
+    ConsumeToken();
+  } else {
+    Diag(Tok, diag::err_parse_error);
+    // Skip to end of block or statement
+    SkipUntil(tok::r_brace, true);
+    if (Tok.getKind() == tok::semi)
+      ConsumeToken();
+  }
+}
+
+
 /// ParseDeclarationSpecifiers
 ///       declaration-specifiers: [C99 6.7]
 ///         storage-class-specifier declaration-specifiers [opt]

Modified: cfe/cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseStmt.cpp?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:08 2007
@@ -14,6 +14,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Parse/Declarations.h"
 using namespace llvm;
 using namespace clang;
 
@@ -262,20 +263,21 @@
   
   // Parse the first part of the for specifier.
   if (Tok.getKind() == tok::semi) {  // for (;
-    // no first part.
+    // no first part, eat the ';'.
+    ConsumeToken();
   } else if (isDeclarationSpecifier()) {  // for (int X = 4;
-    // FIXME: Parse declaration.
-    assert(0);
+    // Parse declaration, which eats the ';'.
+    ParseDeclaration(Declarator::ForContext);
   } else {
     ParseExpression();
-  }
   
-  if (Tok.getKind() == tok::semi) {
-    ConsumeToken();
-  } else {
-    Diag(Tok, diag::err_expected_semi_for);
-    Diag(ForLoc, diag::err_matching);
-    SkipUntil(tok::semi);
+    if (Tok.getKind() == tok::semi) {
+      ConsumeToken();
+    } else {
+      Diag(Tok, diag::err_expected_semi_for);
+      Diag(ForLoc, diag::err_matching);
+      SkipUntil(tok::semi);
+    }
   }
   
   // Parse the second part of the for specifier.

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:08 2007
@@ -191,6 +191,7 @@
   ParseDeclarationSpecifiers(DS);
 
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
+  // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.getKind() == tok::semi)
     assert(0 && "Unimp!");
   
@@ -230,39 +231,8 @@
     return;
   }
 
-  // At this point, we know that it is not a function definition.  Parse the
-  // rest of the init-declarator-list.
-  while (1) {
-    // must be: decl-spec[opt] declarator init-declarator-list
-    // Parse declarator '=' initializer.
-    if (Tok.getKind() == tok::equal)
-      assert(0 && "cannot handle initializer yet!");
-
-    
-    // TODO: install declarator.
-    
-    // If we don't have a comma, it is either the end of the list (a ';') or an
-    // error, bail out.
-    if (Tok.getKind() != tok::comma)
-      break;
-
-    // Consume the comma.
-    ConsumeToken();
-    
-    // Parse the next declarator.
-    DeclaratorInfo.clear();
-    ParseDeclarator(DeclaratorInfo);
-  }
-  
-  if (Tok.getKind() == tok::semi) {
-    ConsumeToken();
-  } else {
-    Diag(Tok, diag::err_parse_error);
-    // Skip to end of block or statement
-    SkipUntil(tok::r_brace, true);
-    if (Tok.getKind() == tok::semi)
-      ConsumeToken();
-  }
+  // Parse the init-declarator-list for a normal declaration.
+  ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
 }
 
 /// ParseFunctionDefinition - We parsed and verified that the specified
@@ -282,33 +252,8 @@
   // int foo(a,b) int a; float b; {}
   if (!FnTypeInfo.Fun.hasPrototype && !FnTypeInfo.Fun.isEmpty) {
     // Read all the argument declarations.
-    while (isDeclarationSpecifier()) {
-      // Parse the common declaration-specifiers piece.
-      DeclSpec DS;
-      ParseDeclarationSpecifiers(DS);
-      
-      Declarator DeclaratorInfo(DS, Declarator::FileContext);
-      ParseDeclarator(DeclaratorInfo);
-
-      while (Tok.getKind() == tok::comma) {
-        // Consume the comma.
-        ConsumeToken();
-      
-        // Parse the next declarator.
-        DeclaratorInfo.clear();
-        ParseDeclarator(DeclaratorInfo);
-      }
-      
-      if (Tok.getKind() == tok::semi) {
-        ConsumeToken();
-      } else {
-        Diag(Tok, diag::err_expected_semi_knr_fn_body);
-        // Skip to end of block or statement
-        SkipUntil(tok::l_brace, true);
-        if (Tok.getKind() == tok::semi)
-          ConsumeToken();
-      }
-    }
+    while (isDeclarationSpecifier())
+      ParseDeclaration(Declarator::KNRTypeListContext);
     
     // Note, check that we got them all.
   } else {

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:08 2007
@@ -266,8 +266,8 @@
      "expected ')'")
 DIAG(err_expected_rbrace, ERROR,
      "expected '}' to end compound statement ('{}' block)")
-DIAG(err_expected_semi_knr_fn_body, ERROR,
-     "expected ';' at end of K&R-style function argument declaration list")
+DIAG(err_expected_semi_decl_list, ERROR,
+     "expected ';' at end of declaration list")
 DIAG(err_expected_fn_body, ERROR,
      "expected function body after function declarator")
 DIAG(err_expected_after_declarator, ERROR,

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:08 2007
@@ -169,6 +169,9 @@
   
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.
+
+  void ParseDeclaration(unsigned Context);
+  void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   void ParseDeclarationSpecifiers(DeclSpec &DS);
   bool isDeclarationSpecifier() const;
   

Modified: cfe/cfe/trunk/test/Parser/statements.c
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/test/Parser/statements.c?rev=38847&r1=38846&r2=38847&view=diff

==============================================================================
--- cfe/cfe/trunk/test/Parser/statements.c (original)
+++ cfe/cfe/trunk/test/Parser/statements.c Wed Jul 11 11:25:08 2007
@@ -15,4 +15,5 @@
     for (;;)
       for (9;0;2)
         ;
+  for (int X = 0; 0; 0);
 }





More information about the cfe-commits mailing list