summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-14 02:46:37 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-14 02:46:37 +0000
commit8aa4ebf0bcf73be3520ee49da0c9ce9cfe66ba31 (patch)
treef6958f307754255f13c15ea299fc7c98fa15933a /clang/lib
parent5f40d349588a5625921be5fb486425ae763e29a8 (diff)
downloadbcm5719-llvm-8aa4ebf0bcf73be3520ee49da0c9ce9cfe66ba31.tar.gz
bcm5719-llvm-8aa4ebf0bcf73be3520ee49da0c9ce9cfe66ba31.zip
Implement typo correction for Objective-C message sends when the
receiver is a mis-typed class name. Previously, we would give a non-specific typo-correction diagnostic from the expression-parsing code, but there was no fix-it because it was too late to recover. Now, we give a nice diagnostic honk.m:6:4: error: unknown receiver 'Hnk'; did you mean 'Honk'? [Hnk method]; ^~~ Honk honk.m:1:1: note: 'Honk' declared here @interface Honk ^ which includes a fix-it. We still need to recover better from mis-typing "super". llvm-svn: 101211
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/Sema.h6
-rw-r--r--clang/lib/Sema/SemaExprObjC.cpp55
2 files changed, 61 insertions, 0 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index c9976302139..9cf12608e7e 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -3863,6 +3863,12 @@ public:
SourceLocation receiverNameLoc,
SourceLocation propertyNameLoc);
+ virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+ IdentifierInfo *&Name,
+ SourceLocation NameLoc,
+ bool IsSuper,
+ bool HasTrailingDot);
+
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
// is obtained from NumArgs.
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index 26d115667c5..cbb49114fec 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -486,6 +486,61 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
<< &propertyName << Context.getObjCInterfaceType(IFace));
}
+Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
+ IdentifierInfo *&Name,
+ SourceLocation NameLoc,
+ bool IsSuper,
+ bool HasTrailingDot) {
+ // If the identifier is "super" and there is no trailing dot, we're
+ // messaging super.
+ if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
+ return ObjCSuperMessage;
+
+ LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupName(Result, S);
+
+ switch (Result.getResultKind()) {
+ case LookupResult::NotFound:
+ // Break out; we'll perform typo correction below.
+ break;
+
+ case LookupResult::NotFoundInCurrentInstantiation:
+ case LookupResult::FoundOverloaded:
+ case LookupResult::FoundUnresolvedValue:
+ case LookupResult::Ambiguous:
+ Result.suppressDiagnostics();
+ return ObjCInstanceMessage;
+
+ case LookupResult::Found: {
+ // We found something. If it's a type, then we have a class
+ // message. Otherwise, it's an instance message.
+ NamedDecl *ND = Result.getFoundDecl();
+ if (isa<ObjCInterfaceDecl>(ND) || isa<TypeDecl>(ND) ||
+ isa<UnresolvedUsingTypenameDecl>(ND))
+ return ObjCClassMessage;
+
+ return ObjCInstanceMessage;
+ }
+ }
+
+ if (CorrectTypo(Result, S, 0) && Result.isSingleResult()) {
+ NamedDecl *ND = Result.getFoundDecl();
+ if (isa<ObjCInterfaceDecl>(ND)) {
+ Diag(NameLoc, diag::err_unknown_receiver_suggest)
+ << Name << Result.getLookupName()
+ << FixItHint::CreateReplacement(SourceRange(NameLoc),
+ ND->getNameAsString());
+ Diag(ND->getLocation(), diag::note_previous_decl)
+ << ND->getDeclName();
+
+ Name = ND->getIdentifier();
+ return ObjCClassMessage;
+ }
+ }
+
+ // Fall back: let the parser try to parse it as an instance message.
+ return ObjCInstanceMessage;
+}
// ActOnClassMessage - used for both unary and keyword messages.
// ArgExprs is optional - if it is present, the number of expressions
OpenPOWER on IntegriCloud