diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-15 14:51:05 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-15 14:51:05 +0000 |
commit | 0fbda68b50ce17d7ad36ef7a5ed77518a5cd272e (patch) | |
tree | f43400e81b5de008eae68c5b64811827d0759775 /lib/Sema/SemaExprObjC.cpp | |
parent | bf3a60b17fa0a12bc7a548e9c659f45684742258 (diff) |
Implement bracket insertion for Objective-C instance message sends as
part of parser recovery. For example, given:
a method1:arg];
we detect after parsing the expression "a" that we have the start of a
message send expression. We pretend we've seen a '[' prior to the a,
then parse the remainder as a message send. We'll then give a
diagnostic+fix-it such as:
fixit-objc-message.m:17:3: error: missing '[' at start of message
send expression
a method1:arg];
^
[
The algorithm here is very simple, and always assumes that the open
bracket goes at the beginning of the message send. It also only works
for non-super instance message sends at this time.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113968 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprObjC.cpp')
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index b56159c453..ebeed130e3 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -626,12 +626,12 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, } ExprResult Sema::ActOnSuperMessage(Scope *S, - SourceLocation SuperLoc, - Selector Sel, - SourceLocation LBracLoc, - SourceLocation SelectorLoc, - SourceLocation RBracLoc, - MultiExprArg Args) { + SourceLocation SuperLoc, + Selector Sel, + SourceLocation LBracLoc, + SourceLocation SelectorLoc, + SourceLocation RBracLoc, + MultiExprArg Args) { // Determine whether we are inside a method or not. ObjCMethodDecl *Method = getCurMethodDecl(); if (!Method) { @@ -702,13 +702,21 @@ ExprResult Sema::ActOnSuperMessage(Scope *S, /// /// \param Args The message arguments. ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, - QualType ReceiverType, - SourceLocation SuperLoc, - Selector Sel, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - SourceLocation RBracLoc, - MultiExprArg ArgsIn) { + QualType ReceiverType, + SourceLocation SuperLoc, + Selector Sel, + ObjCMethodDecl *Method, + SourceLocation LBracLoc, + SourceLocation RBracLoc, + MultiExprArg ArgsIn) { + SourceLocation Loc = SuperLoc.isValid()? SuperLoc + : ReceiverTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(); + if (LBracLoc.isInvalid()) { + Diag(Loc, diag::err_missing_open_square_message_send) + << FixItHint::CreateInsertion(Loc, "["); + LBracLoc = Loc; + } + if (ReceiverType->isDependentType()) { // If the receiver type is dependent, we can't type-check anything // at this point. Build a dependent expression. @@ -720,9 +728,6 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, Args, NumArgs, RBracLoc)); } - SourceLocation Loc = SuperLoc.isValid()? SuperLoc - : ReceiverTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(); - // Find the class to which we are sending this message. ObjCInterfaceDecl *Class = 0; const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>(); @@ -837,6 +842,15 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, SourceLocation LBracLoc, SourceLocation RBracLoc, MultiExprArg ArgsIn) { + // The location of the receiver. + SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart(); + + if (LBracLoc.isInvalid()) { + Diag(Loc, diag::err_missing_open_square_message_send) + << FixItHint::CreateInsertion(Loc, "["); + LBracLoc = Loc; + } + // If we have a receiver expression, perform appropriate promotions // and determine receiver type. if (Receiver) { @@ -858,9 +872,6 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, ReceiverType = Receiver->getType(); } - // The location of the receiver. - SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart(); - if (!Method) { // Handle messages to id. bool receiverIsId = ReceiverType->isObjCIdType(); |