summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaAccess.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-03-27 06:03:27 +0000
committerAnders Carlsson <andersca@mac.com>2009-03-27 06:03:27 +0000
commit733d77f1b4110d6afa16e40a2c4965d635116189 (patch)
tree7615a3e18c9efbf7fdbf04a114cc8ef2cca7bee0 /clang/lib/Sema/SemaAccess.cpp
parent0b08ba44a1ff2b61f5a0c247c4948c830ef31b01 (diff)
downloadbcm5719-llvm-733d77f1b4110d6afa16e40a2c4965d635116189.tar.gz
bcm5719-llvm-733d77f1b4110d6afa16e40a2c4965d635116189.zip
Implement checking for base class access. Right now it's overly conservative but that will change. (Also, protected isn't implemented right now).
llvm-svn: 67827
Diffstat (limited to 'clang/lib/Sema/SemaAccess.cpp')
-rw-r--r--clang/lib/Sema/SemaAccess.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index e44ef5f9ea4..85e1c2ed883 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -11,7 +11,9 @@
//
//===----------------------------------------------------------------------===//
+#include "SemaInherit.h"
#include "Sema.h"
+#include "clang/AST/ASTContext.h"
using namespace clang;
/// SetMemberAccessSpecifier - Set the access specifier of a member.
@@ -45,5 +47,68 @@ bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
/// and report an error if it can't. [class.access.base]
bool Sema::CheckBaseClassAccess(QualType Derived, QualType Base,
BasePaths& Paths, SourceLocation AccessLoc) {
+ Base = Context.getCanonicalType(Base).getUnqualifiedType();
+ assert(!Paths.isAmbiguous(Base) &&
+ "Can't check base class access if set of paths is ambiguous");
+ assert(Paths.isRecordingPaths() &&
+ "Can't check base class access without recorded paths");
+
+ const CXXBaseSpecifier *InacessibleBase = 0;
+
+ for (BasePaths::paths_iterator Path = Paths.begin(), PathsEnd = Paths.end();
+ Path != PathsEnd; ++Path) {
+
+ bool FoundInaccessibleBase = false;
+
+ for (BasePath::const_iterator Element = Path->begin(),
+ ElementEnd = Path->end(); Element != ElementEnd; ++Element) {
+ const CXXBaseSpecifier *Base = Element->Base;
+
+ switch (Base->getAccessSpecifier()) {
+ default:
+ assert(0 && "invalid access specifier");
+ case AS_public:
+ // Nothing to do.
+ break;
+ case AS_private:
+ // FIXME: Check if the current function is a member or friend.
+ FoundInaccessibleBase = true;
+ break;
+ case AS_protected:
+ // FIXME: Implement
+ break;
+ }
+
+ if (FoundInaccessibleBase) {
+ InacessibleBase = Base;
+ break;
+ }
+ }
+
+ if (!FoundInaccessibleBase) {
+ // We found a path to the base, our work here is done.
+ InacessibleBase = 0;
+ break;
+ }
+ }
+
+ if (InacessibleBase) {
+ Diag(AccessLoc, diag::err_conv_to_inaccessible_base)
+ << Derived << Base;
+
+ AccessSpecifier AS = InacessibleBase->getAccessSpecifierAsWritten();
+
+ // If there's no written access specifier, then the inheritance specifier
+ // is implicitly private.
+ if (AS == AS_none)
+ Diag(InacessibleBase->getSourceRange().getBegin(),
+ diag::note_inheritance_implicitly_private_here);
+ else
+ Diag(InacessibleBase->getSourceRange().getBegin(),
+ diag::note_inheritance_specifier_here) << AS;
+
+ return true;
+ }
+
return false;
}
OpenPOWER on IntegriCloud