diff options
author | John McCall <rjmccall@apple.com> | 2010-03-12 01:19:31 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-03-12 01:19:31 +0000 |
commit | d60e22e601852ae1345f01514318a0951dc09f89 (patch) | |
tree | 96d5f68f1e7be5c6142fae6ef878844107355495 /lib/Sema/SemaAccess.cpp | |
parent | 2d2f9368d35b3628c7e3b4563f74849a0f901a00 (diff) |
Implement basic support for friend types and functions in non-dependent
contexts.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98321 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaAccess.cpp')
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index eca8bb4c2a..85c4662846 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -16,6 +16,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/ExprCXX.h" using namespace clang; @@ -55,7 +56,7 @@ struct EffectiveContext { explicit EffectiveContext(DeclContext *DC) { if (isa<FunctionDecl>(DC)) { - Function = cast<FunctionDecl>(DC); + Function = cast<FunctionDecl>(DC)->getCanonicalDecl(); DC = Function->getDeclContext(); } else Function = 0; @@ -85,10 +86,34 @@ static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) { static Sema::AccessResult GetFriendKind(Sema &S, const EffectiveContext &EC, const CXXRecordDecl *Class) { + // A class always has access to its own members. if (EC.isClass(Class)) return Sema::AR_accessible; - // FIXME: implement + // Okay, check friends. + for (CXXRecordDecl::friend_iterator I = Class->friend_begin(), + E = Class->friend_end(); I != E; ++I) { + FriendDecl *Friend = *I; + + if (Type *T = Friend->getFriendType()) { + if (EC.Record && + S.Context.hasSameType(QualType(T, 0), + S.Context.getTypeDeclType(EC.Record))) + return Sema::AR_accessible; + } else { + NamedDecl *D + = cast<NamedDecl>(Friend->getFriendDecl()->getCanonicalDecl()); + + // The decl pointers in EC have been canonicalized, so pointer + // equality is sufficient. + if (D == EC.Function || D == EC.Record) + return Sema::AR_accessible; + } + + // FIXME: templates! templated contexts! dependent delay! + } + + // That's it, give up. return Sema::AR_inaccessible; } |