/// [OBC] '@' 'throw' expression ';'
/// [OBC] '@' 'throw' ';'
///
-Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
+Parser::OwningStmtResult
+Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
const char *SemiError = 0;
OwningStmtResult Res(Actions);
case tok::at: // May be a @try or @throw statement
{
AtLoc = ConsumeToken(); // consume @
- return ParseObjCAtStatement(AtLoc);
+ return Owned(ParseObjCAtStatement(AtLoc));
}
case tok::identifier:
SourceLocation DeclStart = Tok.getLocation();
DeclTy *Decl = ParseDeclaration(Declarator::BlockContext);
// FIXME: Pass in the right location for the end of the declstmt.
- return Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart);
+ return Owned(Actions.ActOnDeclStmt(Decl, DeclStart, DeclStart));
} else if (Tok.is(tok::r_brace)) {
Diag(Tok, diag::err_expected_statement);
- return true;
+ return StmtError();
} else {
// expression[opt] ';'
OwningExprResult Expr(Actions, ParseExpression());
// doing this opens us up to the possibility of infinite loops if
// ParseExpression does not consume any tokens.
SkipUntil(tok::semi);
- return true;
+ return StmtError();
}
// Otherwise, eat the semicolon.
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
- return Actions.ActOnExprStmt(Expr.release());
+ return Owned(Actions.ActOnExprStmt(Expr.release()));
}
-
+
case tok::kw_case: // C99 6.8.1: labeled-statement
return ParseCaseStatement();
case tok::kw_default: // C99 6.8.1: labeled-statement
return ParseDefaultStatement();
-
+
case tok::l_brace: // C99 6.8.2: compound-statement
return ParseCompoundStatement();
case tok::semi: // C99 6.8.3p3: expression[opt] ';'
- return Actions.ActOnNullStmt(ConsumeToken());
-
+ return Owned(Actions.ActOnNullStmt(ConsumeToken()));
+
case tok::kw_if: // C99 6.8.4.1: if-statement
return ParseIfStatement();
case tok::kw_switch: // C99 6.8.4.2: switch-statement
- return ParseSwitchStatement();
-
+ return Owned(ParseSwitchStatement());
+
case tok::kw_while: // C99 6.8.5.1: while-statement
- return ParseWhileStatement();
+ return Owned(ParseWhileStatement());
case tok::kw_do: // C99 6.8.5.2: do-statement
Res = ParseDoStatement();
SemiError = "do/while loop";
break;
case tok::kw_for: // C99 6.8.5.3: for-statement
- return ParseForStatement();
+ return Owned(ParseForStatement());
case tok::kw_goto: // C99 6.8.6.1: goto-statement
Res = ParseGotoStatement();
Res = ParseReturnStatement();
SemiError = "return statement";
break;
-
+
case tok::kw_asm:
bool msAsm = false;
Res = ParseAsmStatement(msAsm);
- if (msAsm) return Res.result();
+ if (msAsm) return move(Res);
SemiError = "asm statement";
break;
}
-
+
// If we reached this code, the statement must end in a semicolon.
if (Tok.is(tok::semi)) {
ConsumeToken();
// Skip until we see a } or ;, but don't eat it.
SkipUntil(tok::r_brace, true, true);
}
- return Res.result();
+ return move(Res);
}
/// ParseLabeledStatement - We have an identifier and a ':' after it.
/// identifier ':' statement
/// [GNU] identifier ':' attributes[opt] statement
///
-Parser::StmtResult Parser::ParseLabeledStatement() {
+Parser::OwningStmtResult Parser::ParseLabeledStatement() {
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
"Not an identifier!");
ConsumeToken(); // eat the identifier.
assert(Tok.is(tok::colon) && "Not a label!");
-
+
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
// TODO: save these somewhere.
AttrList = ParseAttributes();
- OwningStmtResult SubStmt(Actions, ParseStatement());
+ OwningStmtResult SubStmt(ParseStatement());
// Broken substmt shouldn't prevent the label from being added to the AST.
if (SubStmt.isInvalid())
SubStmt = Actions.ActOnNullStmt(ColonLoc);
- return Actions.ActOnLabelStmt(IdentTok.getLocation(),
- IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.release());
+ return Owned(Actions.ActOnLabelStmt(IdentTok.getLocation(),
+ IdentTok.getIdentifierInfo(),
+ ColonLoc, SubStmt.release()));
}
/// ParseCaseStatement
///
/// Note that this does not parse the 'statement' at the end.
///
-Parser::StmtResult Parser::ParseCaseStatement() {
+Parser::OwningStmtResult Parser::ParseCaseStatement() {
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
SourceLocation CaseLoc = ConsumeToken(); // eat the 'case'.
OwningExprResult LHS(Actions, ParseConstantExpression());
if (LHS.isInvalid()) {
SkipUntil(tok::colon);
- return true;
+ return StmtError();
}
// GNU case range extension.
RHS = ParseConstantExpression();
if (RHS.isInvalid()) {
SkipUntil(tok::colon);
- return true;
+ return StmtError();
}
}
if (Tok.isNot(tok::colon)) {
Diag(Tok, diag::err_expected_colon_after) << "'case'";
SkipUntil(tok::colon);
- return true;
+ return StmtError();
}
-
+
SourceLocation ColonLoc = ConsumeToken();
-
+
// Diagnose the common error "switch (X) { case 4: }", which is not valid.
if (Tok.is(tok::r_brace)) {
Diag(Tok, diag::err_label_end_of_compound_statement);
- return true;
+ return StmtError();
}
-
- OwningStmtResult SubStmt(Actions, ParseStatement());
+
+ OwningStmtResult SubStmt(ParseStatement());
// Broken substmt shouldn't prevent the case from being added to the AST.
if (SubStmt.isInvalid())
SubStmt = Actions.ActOnNullStmt(ColonLoc);
-
- return Actions.ActOnCaseStmt(CaseLoc, LHS.release(), DotDotDotLoc,
- RHS.release(), ColonLoc, SubStmt.release());
+
+ return Owned(Actions.ActOnCaseStmt(CaseLoc, LHS.release(), DotDotDotLoc,
+ RHS.release(), ColonLoc,
+ SubStmt.release()));
}
/// ParseDefaultStatement
/// 'default' ':' statement
/// Note that this does not parse the 'statement' at the end.
///
-Parser::StmtResult Parser::ParseDefaultStatement() {
+Parser::OwningStmtResult Parser::ParseDefaultStatement() {
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
if (Tok.isNot(tok::colon)) {
Diag(Tok, diag::err_expected_colon_after) << "'default'";
SkipUntil(tok::colon);
- return true;
+ return StmtError();
}
-
+
SourceLocation ColonLoc = ConsumeToken();
-
+
// Diagnose the common error "switch (X) {... default: }", which is not valid.
if (Tok.is(tok::r_brace)) {
Diag(Tok, diag::err_label_end_of_compound_statement);
- return true;
+ return StmtError();
}
- OwningStmtResult SubStmt(Actions, ParseStatement());
+ OwningStmtResult SubStmt(ParseStatement());
if (SubStmt.isInvalid())
- return true;
-
- return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
- SubStmt.release(), CurScope);
+ return StmtError();
+
+ return Owned(Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
+ SubStmt.release(), CurScope));
}
/// [OMP] barrier-directive
/// [OMP] flush-directive
///
-Parser::StmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
+Parser::OwningStmtResult Parser::ParseCompoundStatement(bool isStmtExpr) {
assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
-
+
// Enter a scope to hold everything within the compound stmt. Compound
// statements can always hold declarations.
ParseScope CompoundScope(this, Scope::DeclScope);
// Parse the statements in the body.
- OwningStmtResult Body(Actions, ParseCompoundStatementBody(isStmtExpr));
- return Body.result();
+ return ParseCompoundStatementBody(isStmtExpr);
}
/// ActOnCompoundStmt action. This expects the '{' to be the current token, and
/// consume the '}' at the end of the block. It does not manipulate the scope
/// stack.
-Parser::StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
+Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
SourceLocation LBraceLoc = ConsumeBrace(); // eat the '{'.
// TODO: "__label__ X, Y, Z;" is the GNU "Local Label" extension. These are
R = Actions.ActOnExprStmt(Res.release());
}
}
-
+
if (R.isUsable())
Stmts.push_back(R.release());
}
-
+
// We broke out of the while loop because we found a '}' or EOF.
if (Tok.isNot(tok::r_brace)) {
Diag(Tok, diag::err_expected_rbrace);
- return true;
+ return StmtError();
}
-
+
SourceLocation RBraceLoc = ConsumeBrace();
- return Actions.ActOnCompoundStmt(LBraceLoc, RBraceLoc,
- Stmts.take(), Stmts.size(), isStmtExpr);
+ return Owned(Actions.ActOnCompoundStmt(LBraceLoc, RBraceLoc, Stmts.take(),
+ Stmts.size(), isStmtExpr));
}
/// ParseIfStatement
/// [C++] 'if' '(' condition ')' statement
/// [C++] 'if' '(' condition ')' statement 'else' statement
///
-Parser::StmtResult Parser::ParseIfStatement() {
+Parser::OwningStmtResult Parser::ParseIfStatement() {
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
SourceLocation IfLoc = ConsumeToken(); // eat the 'if'.
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after) << "if";
SkipUntil(tok::semi);
- return true;
+ return StmtError();
}
bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
if (CondExp.isInvalid()) {
SkipUntil(tok::semi);
- return true;
+ return StmtError();
}
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// Read the 'then' stmt.
SourceLocation ThenStmtLoc = Tok.getLocation();
- OwningStmtResult ThenStmt(Actions, ParseStatement());
+ OwningStmtResult ThenStmt(ParseStatement());
// Pop the 'if' scope if needed.
InnerScope.Exit();
-
+
// If it has an else, parse it.
SourceLocation ElseLoc;
SourceLocation ElseStmtLoc;
if (Tok.is(tok::kw_else)) {
ElseLoc = ConsumeToken();
-
+
// C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if
// there is no compound stmt. C90 does not have this clause. We only do
// this if the body isn't a compound statement to avoid push/pop in common
// The substatement in a selection-statement (each substatement, in the else
// form of the if statement) implicitly defines a local scope.
//
- ParseScope InnerScope(this, Scope::DeclScope,
+ ParseScope InnerScope(this, Scope::DeclScope,
C99orCXX && Tok.isNot(tok::l_brace));
bool WithinElse = CurScope->isWithinElse();
// Pop the 'else' scope if needed.
InnerScope.Exit();
}
-
+
IfScope.Exit();
// If the then or else stmt is invalid and the other is valid (and present),
(ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
(ThenStmt.get() == 0 && ElseStmt.isInvalid())) {
// Both invalid, or one is invalid and other is non-present: return error.
- return true;
+ return StmtError();
}
// Now if either are invalid, replace with a ';'.
if (ElseStmt.isInvalid())
ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);
- return Actions.ActOnIfStmt(IfLoc, CondExp.release(), ThenStmt.release(),
- ElseLoc, ElseStmt.release());
+ return Owned(Actions.ActOnIfStmt(IfLoc, CondExp.release(), ThenStmt.release(),
+ ElseLoc, ElseStmt.release()));
}
/// ParseSwitchStatement
//
ParseScope InnerScope(this, Scope::DeclScope,
C99orCXX && Tok.isNot(tok::l_brace));
-
+
// Read the body statement.
- OwningStmtResult Body(Actions, ParseStatement());
+ OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed.
InnerScope.Exit();
}
SwitchScope.Exit();
-
+
return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.release(),
Body.release());
}
C99orCXX && Tok.isNot(tok::l_brace));
// Read the body statement.
- OwningStmtResult Body(Actions, ParseStatement());
+ OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed.
InnerScope.Exit();
Tok.isNot(tok::l_brace));
// Read the body statement.
- OwningStmtResult Body(Actions, ParseStatement());
+ OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed.
InnerScope.Exit();
C99orCXX && Tok.isNot(tok::l_brace));
// Read the body statement.
- OwningStmtResult Body(Actions, ParseStatement());
+ OwningStmtResult Body(ParseStatement());
// Pop the body scope if needed.
InnerScope.Exit();
// Do not enter a scope for the brace, as the arguments are in the same scope
// (the function body) as the body itself. Instead, just read the statement
// list and put it into a CompoundStmt for safe keeping.
- OwningStmtResult FnBody(Actions, ParseCompoundStatementBody());
-
+ OwningStmtResult FnBody(ParseCompoundStatementBody());
+
// If the function body could not be parsed, make a bogus compoundstmt.
if (FnBody.isInvalid())
- FnBody = Actions.ActOnCompoundStmt(L, R, 0, 0, false);
-
+ FnBody = Owned(Actions.ActOnCompoundStmt(L, R, 0, 0, false));
+
return Actions.ActOnFinishFunctionBody(Decl, FnBody.release());
}