diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-11-03 19:00:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-11-03 19:00:24 +0000 |
commit | f3c02869a7a50ebdc963d0456fd075368b5b5a3f (patch) | |
tree | 221d6f179ea27fb14f43f4ac318687e0e52fdeb4 /lib/Sema/SemaAccess.cpp | |
parent | 8a0ace669e6a4dbe19dfe0376cb31056c3f6a374 (diff) |
Extend IsSimplyAccessible to check for Objective-C instance variable
accessibility. Fixes <rdar://problem/3727335>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaAccess.cpp')
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
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<ObjCIvarDecl>(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<ObjCImplDecl>(FD->getLexicalDeclContext())) { + if (ObjCImplementationDecl *IMPD + = dyn_cast<ObjCImplementationDecl>(Impl)) + ClassOfMethodDecl = IMPD->getClassInterface(); + else if (ObjCCategoryImplDecl* CatImplClass + = dyn_cast<ObjCCategoryImplDecl>(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; } |