aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-10-20 08:15:06 +0000
committerJohn McCall <rjmccall@apple.com>2010-10-20 08:15:06 +0000
commitaa56a66abb61e9f42b48ae88e43328aba10c9148 (patch)
treec1f6c01f26ef2a78c70244b260bb5bdc28e401de /lib/Sema
parent6b40195e035e4b76705126ef53bad446153dd3f8 (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.cpp44
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;
}