diff options
author | John McCall <rjmccall@apple.com> | 2010-10-20 08:15:06 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-20 08:15:06 +0000 |
commit | aa56a66abb61e9f42b48ae88e43328aba10c9148 (patch) | |
tree | c1f6c01f26ef2a78c70244b260bb5bdc28e401de /lib/Sema | |
parent | 6b40195e035e4b76705126ef53bad446153dd3f8 (diff) |
Access control polish: drop the note on the original declaration and
say 'implicitly' when it was implicit. Resolves PR 7930 and my peace of mind.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116916 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index c3a1e75210..2a150d7c03 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1008,9 +1008,51 @@ static void DiagnoseAccessPath(Sema &S, TryDiagnoseProtectedAccess(S, EC, Entity)) return; + // Find an original declaration. + while (D->isOutOfLine()) { + NamedDecl *PrevDecl = 0; + if (isa<VarDecl>(D)) + PrevDecl = cast<VarDecl>(D)->getPreviousDeclaration(); + else if (isa<FunctionDecl>(D)) + PrevDecl = cast<FunctionDecl>(D)->getPreviousDeclaration(); + else if (isa<TypedefDecl>(D)) + PrevDecl = cast<TypedefDecl>(D)->getPreviousDeclaration(); + else if (isa<TagDecl>(D)) { + if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName()) + break; + PrevDecl = cast<TagDecl>(D)->getPreviousDeclaration(); + } + if (!PrevDecl) break; + D = PrevDecl; + } + + CXXRecordDecl *DeclaringClass = FindDeclaringClass(D); + Decl *ImmediateChild; + if (D->getDeclContext() == DeclaringClass) + ImmediateChild = D; + else { + DeclContext *DC = D->getDeclContext(); + while (DC->getParent() != DeclaringClass) + DC = DC->getParent(); + ImmediateChild = cast<Decl>(DC); + } + + // Check whether there's an AccessSpecDecl preceding this in the + // chain of the DeclContext. + bool Implicit = true; + for (CXXRecordDecl::decl_iterator + I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end(); + I != E; ++I) { + if (*I == ImmediateChild) break; + if (isa<AccessSpecDecl>(*I)) { + Implicit = false; + break; + } + } + S.Diag(D->getLocation(), diag::note_access_natural) << (unsigned) (Access == AS_protected) - << /*FIXME: not implicitly*/ 0; + << Implicit; return; } |