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 | 3e972009fb4f93d34f3968e82e0141a3715e1259 (patch) | |
tree | 59d6ba1726f848ea0928da9749f7e81d097dc1f2 /clang/lib/Parse/ParseExpr.cpp | |
parent | d3ac0c1e9cb78dcea5e925cb413771d8cd8658fd (diff) | |
download | bcm5719-llvm-3e972009fb4f93d34f3968e82e0141a3715e1259.tar.gz bcm5719-llvm-3e972009fb4f93d34f3968e82e0141a3715e1259.zip |
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.
llvm-svn: 114039
Diffstat (limited to 'clang/lib/Parse/ParseExpr.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 86 |
1 files changed, 49 insertions, 37 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 26563de2b25..33c7d67ce14 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/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); |