diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-15 16:23:04 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-15 16:23:04 +0000 |
commit | ed0b69dc8163fbae358f99ffc2b1b56a3cad468f (patch) | |
tree | 8c3d0f810f3b3f036f1b3cb07477b2e6def1f852 /clang/lib | |
parent | 0d8971f0d04e802b0357e361523c7b2ac05aa4d5 (diff) | |
download | bcm5719-llvm-ed0b69dc8163fbae358f99ffc2b1b56a3cad468f.tar.gz bcm5719-llvm-ed0b69dc8163fbae358f99ffc2b1b56a3cad468f.zip |
Improve code completion for Objective-C message sends when the opening
'[' is missing. Prior commits improving recovery also improved code
completion beyond the first selector, e.g., at or after the "to" in
calculator add:x to:y
but not after "calculator". We now provide the same completions for
calculator <CC>
that we would for
[calculator <CC>
if "calculator" is an expression whose type is something that can
receive Objective-C messages.
This code completion works for instance and super message sends, but not
class message sends.
llvm-svn: 113976
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCodeComplete.cpp | 23 |
2 files changed, 23 insertions, 19 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 0f9154827e9..26563de2b25 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -664,12 +664,14 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, } // In an Objective-C method, if we have "super" followed by an identifier, - // the token sequence is ill-fomed. However, if there's a ':' or ']' after + // the token sequence is ill-formed. However, if there's a ':' or ']' after // that identifier, this is probably a message send with a missing open - // bracket. Treat it as such. - if (getLang().ObjC1 && &II == Ident_super && Tok.is(tok::identifier) && + // bracket. Treat it as such. + if (getLang().ObjC1 && &II == Ident_super && !InMessageExpression && getCurScope()->isInObjcMethodScope() && - (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) { + ((Tok.is(tok::identifier) && + (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) || + Tok.is(tok::code_completion))) { Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, ParsedType(), 0); break; @@ -991,6 +993,15 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { SourceLocation Loc; while (1) { switch (Tok.getKind()) { + case tok::code_completion: + if (InMessageExpression) + return move(LHS); + + Actions.CodeCompletePostfixExpression(getCurScope(), LHS.take()); + ConsumeCodeCompletionToken(); + LHS = ExprError(); + break; + case tok::identifier: // If we see identifier: after an expression, and we're not already in a // message send, then this is probably a message send with a missing diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 7dc2cb3609d..fd6b5518d70 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -2728,6 +2728,10 @@ void Sema::CodeCompleteExpression(Scope *S, Results.data(),Results.size()); } +void Sema::CodeCompletePostfixExpression(Scope *S, Expr *E) { + if (getLangOptions().ObjC1) + CodeCompleteObjCInstanceMessage(S, E, 0, 0, false); +} static void AddObjCProperties(ObjCContainerDecl *Container, bool AllowCategories, @@ -4014,7 +4018,7 @@ void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) { /// common uses of Objective-C. This routine returns that class type, /// or NULL if no better result could be determined. static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) { - ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E); + ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E); if (!Msg) return 0; @@ -4280,12 +4284,6 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc, void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, IdentifierInfo **SelIdents, - unsigned NumSelIdents) { - CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false); -} - -void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, - IdentifierInfo **SelIdents, unsigned NumSelIdents, bool IsSuper) { typedef CodeCompletionResult Result; @@ -4364,12 +4362,6 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver, void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, IdentifierInfo **SelIdents, - unsigned NumSelIdents) { - CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false); -} - -void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, - IdentifierInfo **SelIdents, unsigned NumSelIdents, bool IsSuper) { typedef CodeCompletionResult Result; @@ -4378,8 +4370,9 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver, // If necessary, apply function/array conversion to the receiver. // C99 6.7.5.3p[7,8]. - DefaultFunctionArrayLvalueConversion(RecExpr); - QualType ReceiverType = RecExpr->getType(); + if (RecExpr) + DefaultFunctionArrayLvalueConversion(RecExpr); + QualType ReceiverType = RecExpr? RecExpr->getType() : Context.getObjCIdType(); // Build the set of methods we can see. ResultBuilder Results(*this); |