aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-15 23:19:31 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-15 23:19:31 +0000
commit77328d1bb92c2c46bc3e4badc4b4b97c517903b7 (patch)
tree1179630096ff97f14009b3be5b68b03337fcf2ec /lib/Parse/ParseExpr.cpp
parent58277b57f9492d0234748be89bcad48b322c5cf7 (diff)
Handle bracket insertion for Objective-C class messages in a very
narrow, almost useless case where we're inside a parenthesized expression, e.g., (NSArray alloc]) The solution to the general case still eludes me. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114039 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExpr.cpp')
-rw-r--r--lib/Parse/ParseExpr.cpp86
1 files changed, 49 insertions, 37 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 26563de2b2..33c7d67ce1 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1529,51 +1529,63 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
Ty = ParseTypeName();
}
- // Match the ')'.
- if (Tok.is(tok::r_paren))
- RParenLoc = ConsumeParen();
- else
- MatchRHSPunctuation(tok::r_paren, OpenLoc);
+ // If our type is followed by an identifier and either ':' or ']', then
+ // this is probably an Objective-C message send where the leading '[' is
+ // missing. Recover as if that were the case.
+ if (!Ty.isInvalid() && Tok.is(tok::identifier) && !InMessageExpression &&
+ getLang().ObjC1 && !Ty.get().get().isNull() &&
+ (NextToken().is(tok::colon) || NextToken().is(tok::r_square)) &&
+ Ty.get().get()->isObjCObjectOrInterfaceType()) {
+ Result = ParseObjCMessageExpressionBody(SourceLocation(),
+ SourceLocation(),
+ Ty.get(), 0);
+ } else {
+ // Match the ')'.
+ if (Tok.is(tok::r_paren))
+ RParenLoc = ConsumeParen();
+ else
+ MatchRHSPunctuation(tok::r_paren, OpenLoc);
+
+ if (Tok.is(tok::l_brace)) {
+ ExprType = CompoundLiteral;
+ return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
+ }
- if (Tok.is(tok::l_brace)) {
- ExprType = CompoundLiteral;
- return ParseCompoundLiteralExpression(Ty.get(), OpenLoc, RParenLoc);
- }
+ if (ExprType == CastExpr) {
+ // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
- if (ExprType == CastExpr) {
- // We parsed '(' type-name ')' and the thing after it wasn't a '{'.
+ if (Ty.isInvalid())
+ return ExprError();
- if (Ty.isInvalid())
- return ExprError();
+ CastTy = Ty.get();
- CastTy = Ty.get();
+ // Note that this doesn't parse the subsequent cast-expression, it just
+ // returns the parsed type to the callee.
+ if (stopIfCastExpr)
+ return ExprResult();
+
+ // Reject the cast of super idiom in ObjC.
+ if (Tok.is(tok::identifier) && getLang().ObjC1 &&
+ Tok.getIdentifierInfo() == Ident_super &&
+ getCurScope()->isInObjcMethodScope() &&
+ GetLookAheadToken(1).isNot(tok::period)) {
+ Diag(Tok.getLocation(), diag::err_illegal_super_cast)
+ << SourceRange(OpenLoc, RParenLoc);
+ return ExprError();
+ }
- // Note that this doesn't parse the subsequent cast-expression, it just
- // returns the parsed type to the callee.
- if (stopIfCastExpr)
- return ExprResult();
-
- // Reject the cast of super idiom in ObjC.
- if (Tok.is(tok::identifier) && getLang().ObjC1 &&
- Tok.getIdentifierInfo() == Ident_super &&
- getCurScope()->isInObjcMethodScope() &&
- GetLookAheadToken(1).isNot(tok::period)) {
- Diag(Tok.getLocation(), diag::err_illegal_super_cast)
- << SourceRange(OpenLoc, RParenLoc);
- return ExprError();
+ // Parse the cast-expression that follows it next.
+ // TODO: For cast expression with CastTy.
+ Result = ParseCastExpression(false, false, CastTy);
+ if (!Result.isInvalid())
+ Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy,
+ RParenLoc, Result.take());
+ return move(Result);
}
- // Parse the cast-expression that follows it next.
- // TODO: For cast expression with CastTy.
- Result = ParseCastExpression(false, false, CastTy);
- if (!Result.isInvalid())
- Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy, RParenLoc,
- Result.take());
- return move(Result);
+ Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
+ return ExprError();
}
-
- Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
- return ExprError();
} else if (TypeOfCast) {
// Parse the expression-list.
InMessageExpressionRAIIObject InMessage(*this, false);