]> granicus.if.org Git - clang/commitdiff
Sema: correct typo correction for ivars in @implementation
authorSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 17 Nov 2016 17:10:54 +0000 (17:10 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Thu, 17 Nov 2016 17:10:54 +0000 (17:10 +0000)
The previous typo correction handling assumed that ivars are only declared in
the interface declaration rather than as a private ivar in the implementation.
Adjust the handling to permit both interfaces.  Assert earlier that the
interface has been acquired to ensure that we can identify when both possible
casts have failed.

Addresses PR31040!

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

lib/Sema/SemaExprMember.cpp
test/SemaObjC/typo-correction.m

index 26f52bcd7733392327cbf670ece76e8ec1837d07..1cc76babe08791c5959dba5dc63ffee2e52816ca 100644 (file)
@@ -1394,10 +1394,17 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
 
         // Figure out the class that declares the ivar.
         assert(!ClassDeclared);
+
         Decl *D = cast<Decl>(IV->getDeclContext());
-        if (ObjCCategoryDecl *CAT = dyn_cast<ObjCCategoryDecl>(D))
-          D = CAT->getClassInterface();
-        ClassDeclared = cast<ObjCInterfaceDecl>(D);
+        if (auto *Category = dyn_cast<ObjCCategoryDecl>(D))
+          D = Category->getClassInterface();
+
+        if (auto *Implementation = dyn_cast<ObjCImplementationDecl>(D))
+          ClassDeclared = Implementation->getClassInterface();
+        else if (auto *Interface = dyn_cast<ObjCInterfaceDecl>(D))
+          ClassDeclared = Interface;
+
+        assert(ClassDeclared && "cannot query interface");
       } else {
         if (IsArrow &&
             IDecl->FindPropertyDeclaration(
index 58824e2edbf097dd97e9d0d06650f239725c3091..f19ec1a1fa3cfef9cf40d44d162a23c5c92fad62 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -fobjc-runtime=ios
 
 @protocol P
 -(id)description;
@@ -28,3 +28,26 @@ typedef int super1;
   [self foo:[super description] other:someivar]; // expected-error {{use of undeclared identifier 'someivar'; did you mean '_someivar'?}}
 }
 @end
+
+__attribute__ (( __objc_root_class__ ))
+@interface I {
+  id _interface; // expected-note {{'_interface' declared here}}
+}
+-(void)method;
+@end
+
+@interface I () {
+  id _extension; // expected-note {{'_extension' declared here}}
+}
+@end
+
+@implementation I {
+  id _implementation; // expected-note {{'_implementation' declared here}}
+}
+-(void)method {
+  (void)self->implementation; // expected-error {{'I' does not have a member named 'implementation'; did you mean '_implementation'?}}
+  (void)self->interface; // expected-error {{'I' does not have a member named 'interface'; did you mean '_interface'?}}
+  (void)self->extension; // expected-error {{'I' does not have a member named 'extension'; did you mean '_extension'?}}
+}
+@end
+