summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseObjc.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-07-27 21:50:02 +0000
committerJohn McCall <rjmccall@apple.com>2011-07-27 21:50:02 +0000
commitd9bb743e0d343b3a199e218368b33f52f4886a72 (patch)
treef5328f00546cc49004c1f10f5d5a71e97bd1b0d4 /clang/lib/Parse/ParseObjc.cpp
parenta94a1544d8d0ae7b54b5a78300e46e81b267e2f9 (diff)
downloadbcm5719-llvm-d9bb743e0d343b3a199e218368b33f52f4886a72.tar.gz
bcm5719-llvm-d9bb743e0d343b3a199e218368b33f52f4886a72.zip
The lock operand to an @synchronized statement is also
supposed to be a full-expression; make it so. In ARC, make sure we retain the lock for the entire protected block. llvm-svn: 136271
Diffstat (limited to 'clang/lib/Parse/ParseObjc.cpp')
-rw-r--r--clang/lib/Parse/ParseObjc.cpp51
1 files changed, 33 insertions, 18 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index ff9e20504ba..c8b2a09d5ea 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -1560,31 +1560,46 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) {
Diag(Tok, diag::err_expected_lparen_after) << "@synchronized";
return StmtError();
}
+
+ // The operand is surrounded with parentheses.
ConsumeParen(); // '('
- ExprResult Res(ParseExpression());
- if (Res.isInvalid()) {
- SkipUntil(tok::semi);
- return StmtError();
- }
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok, diag::err_expected_lbrace);
- return StmtError();
+ ExprResult operand(ParseExpression());
+
+ if (Tok.is(tok::r_paren)) {
+ ConsumeParen(); // ')'
+ } else {
+ if (!operand.isInvalid())
+ Diag(Tok, diag::err_expected_rparen);
+
+ // Skip forward until we see a left brace, but don't consume it.
+ SkipUntil(tok::l_brace, true, true);
}
- ConsumeParen(); // ')'
+
+ // Require a compound statement.
if (Tok.isNot(tok::l_brace)) {
- Diag(Tok, diag::err_expected_lbrace);
+ if (!operand.isInvalid())
+ Diag(Tok, diag::err_expected_lbrace);
return StmtError();
}
- // Enter a scope to hold everything within the compound stmt. Compound
- // statements can always hold declarations.
- ParseScope BodyScope(this, Scope::DeclScope);
- StmtResult SynchBody(ParseCompoundStatementBody());
+ // Check the @synchronized operand now.
+ if (!operand.isInvalid())
+ operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.take());
- BodyScope.Exit();
- if (SynchBody.isInvalid())
- SynchBody = Actions.ActOnNullStmt(Tok.getLocation());
- return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.take(), SynchBody.take());
+ // Parse the compound statement within a new scope.
+ ParseScope bodyScope(this, Scope::DeclScope);
+ StmtResult body(ParseCompoundStatementBody());
+ bodyScope.Exit();
+
+ // If there was a semantic or parse error earlier with the
+ // operand, fail now.
+ if (operand.isInvalid())
+ return StmtError();
+
+ if (body.isInvalid())
+ body = Actions.ActOnNullStmt(Tok.getLocation());
+
+ return Actions.ActOnObjCAtSynchronizedStmt(atLoc, operand.get(), body.get());
}
/// objc-try-catch-statement:
OpenPOWER on IntegriCloud