[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