[cfe-commits] r38849 - in /cfe/cfe/trunk: Parse/ParseStmt.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h

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


Author: sabre
Date: Wed Jul 11 11:25:09 2007
New Revision: 38849

URL: http://llvm.org/viewvc/llvm-project?rev=38849&view=rev
Log:
Parse jump-statement: goto, continue, break, return.

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

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseStmt.cpp Wed Jul 11 11:25:09 2007
@@ -62,43 +62,77 @@
 ///         'continue' ';'
 ///         'break' ';'
 ///         'return' expression[opt] ';'
-/// [GNU]   'goto' '*' expression ';'     [TODO]
+/// [GNU]   'goto' '*' expression ';'
 ///
 /// [OBC] objc-throw-statement:           [TODO]
 /// [OBC]   '@' 'throw' expression ';'    [TODO]
 /// [OBC]   '@' 'throw' ';'               [TODO]
 /// 
 void Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
+  const char *SemiError = 0;
+  
+  // Cases in this switch statement should fall through if the parser expects
+  // the token to end in a semicolon (in which case SemiError should be set),
+  // or they directly 'return;' if not.
   switch (Tok.getKind()) {
   default:
     Diag(Tok, diag::err_expected_statement_declaration);
     SkipUntil(tok::semi);
-    break;
+    return;
     
     
   case tok::l_brace:                // C99 6.8.2: compound-statement
     ParseCompoundStatement();
-    break;
+    return;
   case tok::semi:                   // C99 6.8.3: expression[opt] ';'
     ConsumeToken();
-    break;
+    return;
+    
   case tok::kw_if:                  // C99 6.8.4.1: if-statement
     ParseIfStatement();
-    break;
+    return;
   case tok::kw_switch:              // C99 6.8.4.2: switch-statement
     ParseSwitchStatement();
-    break;
+    return;
+    
   case tok::kw_while:               // C99 6.8.5.1: while-statement
     ParseWhileStatement();
-    break;
+    return;
   case tok::kw_do:                  // C99 6.8.5.2: do-statement
     ParseDoStatement();
+    SemiError = "do/while loop";
     break;
   case tok::kw_for:                 // C99 6.8.5.3: for-statement
     ParseForStatement();
+    return;
+
+  case tok::kw_goto:                // C99 6.8.6.1: goto-statement
+    ParseGotoStatement();
+    SemiError = "goto statement";
     break;
+  case tok::kw_continue:            // C99 6.8.6.2: continue-statement
+    ConsumeToken();  // eat the 'continue'.
+    SemiError = "continue statement";
+    break;
+  case tok::kw_break:               // C99 6.8.6.3: break-statement
+    ConsumeToken();  // eat the 'break'.
+    SemiError = "break statement";
+    break;
+  case tok::kw_return:              // C99 6.8.6.4: return-statement
+    ParseReturnStatement();
+    SemiError = "return statement";
+    break;
+    
     // TODO: Handle OnlyStatement..
   }
+  
+  // If we reached this code, the statement must end in a semicolon.
+  if (Tok.getKind() == tok::semi) {
+    ConsumeToken();
+  } else {
+    Diag(Tok, diag::err_expected_semi_after, SemiError);
+    SkipUntil(tok::semi);
+  }
 }
 
 /// ParseCompoundStatement - Parse a "{}" block.
@@ -211,6 +245,7 @@
 /// ParseDoStatement
 ///       do-statement: [C99 6.8.5.2]
 ///         'do' statement 'while' '(' expression ')' ';'
+/// Note: this lets the caller parse the end ';'.
 void Parser::ParseDoStatement() {
   assert(Tok.getKind() == tok::kw_do && "Not a do stmt!");
   SourceLocation DoLoc = Tok.getLocation();
@@ -235,12 +270,6 @@
   
   // Parse the condition.
   ParseParenExpression();
-  
-  if (Tok.getKind() != tok::semi) {
-    Diag(Tok, diag::err_expected_semi_do_while);
-    SkipUntil(tok::semi);
-    return;
-  }
 }
 
 /// ParseForStatement
@@ -317,3 +346,34 @@
   ParseStatement();
 }
 
+/// ParseGotoStatement
+///       jump-statement:
+///         'goto' identifier ';'
+/// [GNU]   'goto' '*' expression ';'
+///
+/// Note: this lets the caller parse the end ';'.
+///
+void Parser::ParseGotoStatement() {
+  assert(Tok.getKind() == tok::kw_goto && "Not a goto stmt!");
+  ConsumeToken();  // eat the 'goto'.
+  
+  if (Tok.getKind() == tok::identifier) {
+    ConsumeToken();
+  } else if (Tok.getKind() == tok::star && !getLang().NoExtensions) {
+    // GNU indirect goto extension.
+    Diag(Tok, diag::ext_gnu_indirect_goto);
+    ConsumeToken();
+    ParseExpression();
+  }
+}
+
+/// ParseReturnStatement
+///       jump-statement:
+///         'return' expression[opt] ';'
+void Parser::ParseReturnStatement() {
+  assert(Tok.getKind() == tok::kw_return && "Not a return stmt!");
+  ConsumeToken();  // eat the 'return'.
+  
+  if (Tok.getKind() != tok::semi)
+    ParseExpression();
+}

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=38849&r1=38848&r2=38849&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:09 2007
@@ -256,6 +256,8 @@
      "use of c99-specific array features")
 DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION,
      "variable declaration in for loop is a c99-specific feature")
+DIAG(ext_gnu_indirect_goto, EXTENSION,
+     "use of GNU indirect-goto extension")
 
 // Generic errors.
 DIAG(err_parse_error, ERROR,
@@ -280,8 +282,8 @@
      "expected '(' after '%s'")
 DIAG(err_expected_while, ERROR,
      "expected 'while' in do/while loop")
-DIAG(err_expected_semi_do_while, ERROR,
-     "expected ';' at end of do/while loop")
+DIAG(err_expected_semi_after, ERROR,
+     "expected ';' after %s")
 DIAG(err_expected_semi_for, ERROR,
      "expected ';' in 'for' statement specifier")
 

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=38849&r1=38848&r2=38849&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:25:09 2007
@@ -166,7 +166,9 @@
   void ParseWhileStatement();
   void ParseDoStatement();
   void ParseForStatement();
-  
+  void ParseGotoStatement();
+  void ParseReturnStatement();
+
   //===--------------------------------------------------------------------===//
   // C99 6.7: Declarations.
 





More information about the cfe-commits mailing list