From 26c5578d849a5f9cdc3044ae67e2857bbe038215 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 15 Oct 2010 16:49:56 +0000 Subject: [PATCH] When performing typo correction, keep track of whether the last lookup we did was an acceptable lookup. If it is, then we can re-use that lookup result. If it isn't, we have to perform the lookup again. This is almost surely the cause behind the mysterious typo.m failures on some builders; we were getting the wrong lookup results returned. llvm-svn: 116586 --- clang/lib/Sema/SemaLookup.cpp | 38 ++++++++++++++++++- clang/test/FixIt/typo.m | 3 -- clang/test/SemaObjC/synth-provisional-ivars.m | 2 +- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 9056e79574ed..6cd0207c8005 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3051,6 +3051,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, return DeclarationName(); // Weed out any names that could not be found by name lookup. + bool LastLookupWasAccepted = false; for (TypoCorrectionConsumer::iterator I = Consumer.begin(), IEnd = Consumer.end(); I != IEnd; /* Increment in loop. */) { @@ -3103,12 +3104,14 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, Consumer.erase(I); I = Next; } + LastLookupWasAccepted = false; break; case LookupResult::Found: case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: ++I; + LastLookupWasAccepted = false; break; } @@ -3121,8 +3124,41 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS, } // If only a single name remains, return that result. - if (Consumer.size() == 1) + if (Consumer.size() == 1) { + IdentifierInfo *Name = &Context.Idents.get(Consumer.begin()->getKey()); + if (!LastLookupWasAccepted) { + // Perform name lookup on this name. + Res.suppressDiagnostics(); + Res.clear(); + Res.setLookupName(Name); + if (MemberContext) + LookupQualifiedName(Res, MemberContext); + else { + LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, + EnteringContext); + + // Fake ivar lookup; this should really be part of + // LookupParsedName. + if (ObjCMethodDecl *Method = getCurMethodDecl()) { + if (Method->isInstanceMethod() && Method->getClassInterface() && + (Res.empty() || + (Res.isSingleResult() && + Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) { + ObjCInterfaceDecl *ClassDeclared = 0; + if (ObjCIvarDecl *IV + = Method->getClassInterface()->lookupInstanceVariable(Name, + ClassDeclared)) { + Res.clear(); + Res.addDecl(IV); + Res.resolveKind(); + } + } + } + } + } + return &Context.Idents.get(Consumer.begin()->getKey()); + } else if (Consumer.size() > 1 && CTC == CTC_ObjCMessageReceiver && Consumer["super"]) { // Prefix 'super' when we're completing in a message-receiver diff --git a/clang/test/FixIt/typo.m b/clang/test/FixIt/typo.m index 0be21a0fe2e3..b8c57e46e3b8 100644 --- a/clang/test/FixIt/typo.m +++ b/clang/test/FixIt/typo.m @@ -2,9 +2,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c -E -P %s -o %t // RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fixit %t || true // RUN: %clang_cc1 -x objective-c -fsyntax-only -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -pedantic -Werror %t -// -// FIXME: Disabled while we investigate failure. -// REQUIRES: disabled @interface NSString // expected-note{{'NSString' declared here}} + (int)method:(int)x; diff --git a/clang/test/SemaObjC/synth-provisional-ivars.m b/clang/test/SemaObjC/synth-provisional-ivars.m index 8ad2233ba4a8..10fdbdccb23b 100644 --- a/clang/test/SemaObjC/synth-provisional-ivars.m +++ b/clang/test/SemaObjC/synth-provisional-ivars.m @@ -18,7 +18,7 @@ int bar; @end @implementation I -- (int) Meth { return PROP; } +- (int) Meth { return PROP; } // expected-note{{'PROP' declared here}} @dynamic PROP1; - (int) Meth1 { return PROP1; } // expected-error {{use of undeclared identifier 'PROP1'}}