diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-15 23:19:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-15 23:19:31 +0000 |
commit | 77328d1bb92c2c46bc3e4badc4b4b97c517903b7 (patch) | |
tree | 1179630096ff97f14009b3be5b68b03337fcf2ec /lib/Parse/ParseExpr.cpp | |
parent | 58277b57f9492d0234748be89bcad48b322c5cf7 (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.cpp | 86 |
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); |