diff options
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 86 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 12 | ||||
-rw-r--r-- | clang/test/FixIt/fixit-objc-message.m | 1 | ||||
-rw-r--r-- | clang/test/Index/complete-objc-message.m | 2 |
4 files changed, 57 insertions, 44 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); diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index ebeed130e30..caa2762d7fc 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -786,12 +786,12 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, // ArgExprs is optional - if it is present, the number of expressions // is obtained from Sel.getNumArgs(). ExprResult Sema::ActOnClassMessage(Scope *S, - ParsedType Receiver, - Selector Sel, - SourceLocation LBracLoc, - SourceLocation SelectorLoc, - SourceLocation RBracLoc, - MultiExprArg Args) { + ParsedType Receiver, + Selector Sel, + SourceLocation LBracLoc, + SourceLocation SelectorLoc, + SourceLocation RBracLoc, + MultiExprArg Args) { TypeSourceInfo *ReceiverTypeInfo; QualType ReceiverType = GetTypeFromParser(Receiver, &ReceiverTypeInfo); if (ReceiverType.isNull()) diff --git a/clang/test/FixIt/fixit-objc-message.m b/clang/test/FixIt/fixit-objc-message.m index 72728d20adc..1969faab3b8 100644 --- a/clang/test/FixIt/fixit-objc-message.m +++ b/clang/test/FixIt/fixit-objc-message.m @@ -21,6 +21,7 @@ void f(A *a, int i, int j) { int array[17]; (void)array[a method1:5+2 second:+(3.14159)]]; + (A method2:5+2 second:3.14159]) } @interface B : A diff --git a/clang/test/Index/complete-objc-message.m b/clang/test/Index/complete-objc-message.m index d6abd4bd83f..02d7f2140cf 100644 --- a/clang/test/Index/complete-objc-message.m +++ b/clang/test/Index/complete-objc-message.m @@ -135,7 +135,7 @@ void test_ranking(B *b) { b method1]; } -void test_overload_2(Overload *ovl) { +void test_overload3(Overload *ovl) { ovl Method:1 Arg1:1 OtherArg:ovl]; } |