forked from OSchip/llvm-project
Add support for parsing declarations in blocks. This implements
Parser/statements.c:test4 llvm-svn: 38852
This commit is contained in:
parent
d2685cf6bb
commit
f8afb62ef9
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -29,3 +29,11 @@ int test3() {
|
|||
;
|
||||
}
|
||||
}
|
||||
|
||||
int test4() {
|
||||
if (0);
|
||||
|
||||
int X; // declaration in a block.
|
||||
|
||||
if (0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue