From: Douglas Gregor Date: Thu, 3 Nov 2011 19:00:24 +0000 (+0000) Subject: Extend IsSimplyAccessible to check for Objective-C instance variable X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3c02869a7a50ebdc963d0456fd075368b5b5a3f;p=clang Extend IsSimplyAccessible to check for Objective-C instance variable accessibility. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143635 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 89538ba905..69fd543082 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -19,6 +19,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/ExprCXX.h" @@ -1667,7 +1668,46 @@ bool Sema::IsSimplyAccessible(NamedDecl *Decl, DeclContext *Ctx) { return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible; } - // FIXME: Check access for Objective-C ivars. + if (ObjCIvarDecl *Ivar = dyn_cast(Decl)) { + // @public and @package ivars are always accessible. + if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public || + Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package) + return true; + + + + // If we are inside a class or category implementation, determine the + // interface we're in. + ObjCInterfaceDecl *ClassOfMethodDecl = 0; + if (ObjCMethodDecl *MD = getCurMethodDecl()) + ClassOfMethodDecl = MD->getClassInterface(); + else if (FunctionDecl *FD = getCurFunctionDecl()) { + if (ObjCImplDecl *Impl + = dyn_cast(FD->getLexicalDeclContext())) { + if (ObjCImplementationDecl *IMPD + = dyn_cast(Impl)) + ClassOfMethodDecl = IMPD->getClassInterface(); + else if (ObjCCategoryImplDecl* CatImplClass + = dyn_cast(Impl)) + ClassOfMethodDecl = CatImplClass->getClassInterface(); + } + } + + // If we're not in an interface, this ivar is inaccessible. + if (!ClassOfMethodDecl) + return false; + + // If we're inside the same interface that owns the ivar, we're fine. + if (ClassOfMethodDecl == Ivar->getContainingInterface()) + return true; + + // If the ivar is private, it's inaccessible. + if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private) + return false; + + return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl); + } + return true; } diff --git a/test/Index/complete-ivar-access.m b/test/Index/complete-ivar-access.m new file mode 100644 index 0000000000..acd3883c72 --- /dev/null +++ b/test/Index/complete-ivar-access.m @@ -0,0 +1,69 @@ +@interface Other { +@private + int other_private; +@protected + int other_protected; +@public + int other_public; +} +@end + +@interface Super { +@private + int super_private; +@protected + int super_protected; +@public + int super_public; +} +@end + +@interface Super () { +@private + int super_ext_private; +@protected + int super_ext_protected; +@public + int super_ext_public; +} +@end + +@interface Sub : Super { +@private + int sub_private; +@protected + int sub_protected; +@public + int sub_public; +} +@end + +@implementation Sub +- (void)method:(Sub *)sub with:(Other *)other { + sub->super_protected = 1; + other->other_public = 1; +} + +void f(Sub *sub, Other *other) { + sub->super_protected = 1; + other->other_public = 1; +} +@end + +// RUN: c-index-test -code-completion-at=%s:43:8 %s | FileCheck -check-prefix=CHECK-SUB %s +// RUN: c-index-test -code-completion-at=%s:48:8 %s | FileCheck -check-prefix=CHECK-SUB %s +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText sub_private} (35) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText sub_protected} (35) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText sub_public} (35) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_ext_private} (35) (inaccessible) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_ext_protected} (35) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_ext_public} (35) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_private} (37) (inaccessible) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_protected} (37) +// CHECK-SUB: ObjCIvarDecl:{ResultType int}{TypedText super_public} (37) + +// RUN: c-index-test -code-completion-at=%s:44:10 %s | FileCheck -check-prefix=CHECK-OTHER %s +// RUN: c-index-test -code-completion-at=%s:49:10 %s | FileCheck -check-prefix=CHECK-OTHER %s +// CHECK-OTHER: ObjCIvarDecl:{ResultType int}{TypedText other_private} (35) (inaccessible) +// CHECK-OTHER: ObjCIvarDecl:{ResultType int}{TypedText other_protected} (35) (inaccessible) +// CHECK-OTHER: ObjCIvarDecl:{ResultType int}{TypedText other_public} (35)