Add support for parsing declarations in blocks. This implements

Parser/statements.c:test4

llvm-svn: 38852
This commit is contained in:
Chris Lattner 2006-08-10 18:26:31 +00:00
parent d2685cf6bb
commit f8afb62ef9
4 changed files with 36 additions and 7 deletions

View File

@ -76,10 +76,23 @@ ParseNextStatement:
// the token to end in a semicolon (in which case SemiError should be set),
// or they directly 'return;' if not.
switch (Tok.getKind()) {
case tok::identifier: // C99 6.8.1: labeled-statement
// identifier ':' statement
// declaration (if !OnlyStatement)
// expression[opt] ';'
return ParseIdentifierStatement(OnlyStatement);
default:
Diag(Tok, OnlyStatement ? diag::err_expected_statement :
diag::err_expected_statement_declaration);
SkipUntil(tok::semi);
if (!OnlyStatement && isDeclarationSpecifier()) {
// TODO: warn/disable if declaration is in the middle of a block and !C99.
ParseDeclaration(Declarator::BlockContext);
return;
} else if (Tok.getKind() == tok::r_brace) {
Diag(Tok, diag::err_expected_statement);
} else {
// expression[opt] ';'
ParseExpression();
}
return;
case tok::kw_case: // C99 6.8.1: labeled-statement
@ -140,8 +153,6 @@ ParseNextStatement:
ParseReturnStatement();
SemiError = "return statement";
break;
// TODO: Handle OnlyStatement..
}
// If we reached this code, the statement must end in a semicolon.
@ -153,6 +164,17 @@ ParseNextStatement:
}
}
/// ParseIdentifierStatement - Because we don't have two-token lookahead, we
/// have a bit of a quandry here. Reading the identifier is necessary to see if
/// there is a ':' after it. If there is, this is a label, regardless of what
/// else the identifier can mean. If not, this is either part of a declaration
/// (if the identifier is a type-name) or part of an expression.
void Parser::ParseIdentifierStatement(bool OnlyStatement) {
assert(0);
}
/// ParseCaseStatement
/// labeled-statement:
/// 'case' constant-expression ':' statement

View File

@ -278,8 +278,6 @@ DIAG(err_expected_after_declarator, ERROR,
"expected '=', ',', ';', 'asm', or '__attribute__' after declarator")
DIAG(err_expected_statement, ERROR,
"expected statement")
DIAG(err_expected_statement_declaration, ERROR,
"expected statement or declaration")
DIAG(err_expected_lparen_after, ERROR,
"expected '(' after '%s'")
DIAG(err_expected_while, ERROR,

View File

@ -160,6 +160,7 @@ private:
// C99 6.8: Statements and Blocks.
void ParseStatement() { ParseStatementOrDeclaration(true); }
void ParseStatementOrDeclaration(bool OnlyStatement = false);
void ParseIdentifierStatement(bool OnlyStatement);
void ParseCaseStatement();
void ParseDefaultStatement();
void ParseCompoundStatement();

View File

@ -29,3 +29,11 @@ int test3() {
;
}
}
int test4() {
if (0);
int X; // declaration in a block.
if (0);
}