]> granicus.if.org Git - clang/commitdiff
Fix handling of property and ivar lookup in typo correction; the two
authorDouglas Gregor <dgregor@apple.com>
Wed, 20 Oct 2010 03:06:34 +0000 (03:06 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 20 Oct 2010 03:06:34 +0000 (03:06 +0000)
kinds of lookup into Objective-C classes were tangled together, a
situation that was compounded by automatically synthesized ivars.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116907 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaLookup.cpp
test/FixIt/typo.cpp
test/FixIt/typo.m
test/SemaObjC/super.m
test/SemaObjC/synth-provisional-ivars.m

index 5e6497fe1be13bbcc583fda3efcf70282a31d16d..108353f53b0053fba35994cd77c2deca68f73c7f 100644 (file)
@@ -1310,6 +1310,10 @@ public:
     CTC_CXXCasts,
     /// \brief A member lookup context.
     CTC_MemberLookup,
+    /// \brief An Objective-C ivar lookup context (e.g., self->ivar).
+    CTC_ObjCIvarLookup,
+    /// \brief An Objective-C property lookup context (e.g., self.prop).
+    CTC_ObjCPropertyLookup,
     /// \brief The receiver of an Objective-C message send within an
     /// Objective-C method where 'super' is a valid keyword.
     CTC_ObjCMessageReceiver
index 50f023abc8e0248a53fac35b4bfa1ee4aba6de0d..587a76ed089515aafe348e8a3d6dfea4f8832adf 100644 (file)
@@ -3231,7 +3231,9 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
         // Attempt to correct for typos in ivar names.
         LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
                          LookupMemberName);
-        if (CorrectTypo(Res, 0, 0, IDecl, false, CTC_MemberLookup) &&
+        if (CorrectTypo(Res, 0, 0, IDecl, false, 
+                        IsArrow? CTC_ObjCIvarLookup
+                               : CTC_ObjCPropertyLookup) &&
             (IV = Res.getAsSingle<ObjCIvarDecl>())) {
           Diag(R.getNameLoc(),
                diag::err_typecheck_member_reference_ivar_suggest)
index 1294f4f0133c37193a17ccb0c2eed467da478793..29df503910978a8b7a7842f854059779963b11a5 100644 (file)
@@ -2785,6 +2785,57 @@ void TypoCorrectionConsumer::addKeywordResult(ASTContext &Context,
   BestResults[Keyword] = true;
 }
 
+/// \brief Perform name lookup for a possible result for typo correction.
+static void LookupPotentialTypoResult(Sema &SemaRef,
+                                      LookupResult &Res,
+                                      IdentifierInfo *Name,
+                                      Scope *S, CXXScopeSpec *SS,
+                                      DeclContext *MemberContext,
+                                      bool EnteringContext,
+                                      Sema::CorrectTypoContext CTC) {
+  Res.suppressDiagnostics();
+  Res.clear();
+  Res.setLookupName(Name);
+  if (MemberContext) {    
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(MemberContext)) {
+      if (CTC == Sema::CTC_ObjCIvarLookup) {
+        if (ObjCIvarDecl *Ivar = Class->lookupInstanceVariable(Name)) {
+          Res.addDecl(Ivar);
+          Res.resolveKind();
+          return;
+        }
+      }
+      
+      if (ObjCPropertyDecl *Prop = Class->FindPropertyDeclaration(Name)) {
+        Res.addDecl(Prop);
+        Res.resolveKind();
+        return;
+      }
+    }
+        
+    SemaRef.LookupQualifiedName(Res, MemberContext);
+    return;
+  }
+  
+  SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, 
+                           EnteringContext);
+  
+  // Fake ivar lookup; this should really be part of
+  // LookupParsedName.
+  if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
+    if (Method->isInstanceMethod() && Method->getClassInterface() &&
+        (Res.empty() || 
+         (Res.isSingleResult() &&
+          Res.getFoundDecl()->isDefinedOutsideFunctionOrMethod()))) {
+       if (ObjCIvarDecl *IV 
+             = Method->getClassInterface()->lookupInstanceVariable(Name)) {
+         Res.addDecl(IV);
+         Res.resolveKind();
+       }
+     }
+  }
+}
+
 /// \brief Try to "correct" a typo in the source code by finding
 /// visible declarations whose names are similar to the name that was
 /// present in the source code.
@@ -2946,10 +2997,17 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
       WantCXXNamedCasts = true;
       break;
       
+    case CTC_ObjCPropertyLookup:
+      // FIXME: Add "isa"?
+      break;
+      
     case CTC_MemberLookup:
       if (getLangOptions().CPlusPlus)
         Consumer.addKeywordResult(Context, "template");
       break;
+      
+    case CTC_ObjCIvarLookup:
+      break;
   }
 
   if (WantTypeSpecifiers) {
@@ -3104,33 +3162,8 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
     
     // Perform name lookup on this name.
     IdentifierInfo *Name = &Context.Idents.get(I->getKey());
-    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();
-          }
-        }
-      }
-    }
+    LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext, 
+                              EnteringContext, CTC);
     
     switch (Res.getResultKind()) {
     case LookupResult::NotFound:
@@ -3152,7 +3185,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
     case LookupResult::FoundOverloaded:
     case LookupResult::FoundUnresolvedValue:
       ++I;
-      LastLookupWasAccepted = false;
+      LastLookupWasAccepted = true;
       break;
     }
     
@@ -3172,39 +3205,14 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
       Res.clear();
     } else 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();
-            }
-          }
-        }
-      }
+      LookupPotentialTypoResult(*this, Res, Name, S, SS, MemberContext, 
+                                EnteringContext, CTC);
     }
 
     // Record the correction for unqualified lookup.
     if (IsUnqualifiedLookup)
       UnqualifiedTyposCorrected[Typo] 
-        = std::make_pair(Consumer.begin()->getKey(), Consumer.begin()->second);
+        = std::make_pair(Name->getName(), Consumer.begin()->second);
       
     return &Context.Idents.get(Consumer.begin()->getKey());  
   }
@@ -3218,7 +3226,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
     // Record the correction for unqualified lookup.
     if (IsUnqualifiedLookup)
       UnqualifiedTyposCorrected[Typo]
-        = std::make_pair(Consumer.begin()->getKey(), Consumer.begin()->second);
+        = std::make_pair("super", Consumer.begin()->second);
     
     return &Context.Idents.get("super");
   }
index 35666efe47529bb565a46dc74012c394503f363c..d1e732fd1dba828dddb4fd57b2f90fd529558d7e 100644 (file)
@@ -2,9 +2,7 @@
 // RUN: cp %s %t
 // RUN: %clang_cc1 -fsyntax-only -fixit -x c++ %t || true
 // RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -x c++ %t
-//
-// FIXME: Disabled while we investigate failure.
-// REQUIRES: disabled
+
 namespace std {
   template<typename T> class basic_string { // expected-note 2{{'basic_string' declared here}}
   public:
index 0be21a0fe2e3ed22476370ad3cedcdf670cef5ee..b8c57e46e3b89bbf46e6165a0d1d09f7b6ed0024 100644 (file)
@@ -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;
index c15df26f34b06bd9eb9e56ba8ca28ed76d7ddd44..0c42e99d715dfbdb8d2b4603b4d30ac218242e97 100644 (file)
@@ -54,7 +54,7 @@ void f0(int super) {
   [super m]; // expected-warning{{receiver type 'int' is not 'id'}} \
                 expected-warning {{method '-m' not found (return type defaults to 'id')}}
 }
-void f1(id puper) {
+void f1(id puper) {  // expected-note {{'puper' declared here}}
   [super m]; // expected-error{{use of undeclared identifier 'super'}}
 }
 
index 10fdbdccb23b6894ba302115e46ee971544888fc..1fb1abb7ce0831df2208bb4c3d36002e84e0a6b4 100644 (file)
@@ -18,7 +18,7 @@ int bar;
 @end
 
 @implementation I
-- (int) Meth { return PROP; } // expected-note{{'PROP' declared here}}
+- (int) Meth { return PROP; } // expected-note 2{{'PROP' declared here}}
 
 @dynamic PROP1;
 - (int) Meth1 { return PROP1; }  // expected-error {{use of undeclared identifier 'PROP1'}}