diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:10:26 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-23 11:10:26 +0000 |
commit | 2fce988e86bc01829142e4362d4eff1af0925147 (patch) | |
tree | c69d3f4f13d508570bb5257a6aea735f88bdf09c /lib/AST/CXXInheritance.cpp | |
parent | a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824 (diff) | |
download | FreeBSD-src-2fce988e86bc01829142e4362d4eff1af0925147.zip FreeBSD-src-2fce988e86bc01829142e4362d4eff1af0925147.tar.gz |
Update clang to r94309.
Diffstat (limited to 'lib/AST/CXXInheritance.cpp')
-rw-r--r-- | lib/AST/CXXInheritance.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp index 92a58b7..7208328 100644 --- a/lib/AST/CXXInheritance.cpp +++ b/lib/AST/CXXInheritance.cpp @@ -145,7 +145,11 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData, CXXBasePaths &Paths) const { bool FoundPath = false; - + + // The access of the path down to this record. + AccessSpecifier AccessToHere = Paths.ScratchPath.Access; + bool IsFirstStep = Paths.ScratchPath.empty(); + ASTContext &Context = getASTContext(); for (base_class_const_iterator BaseSpec = bases_begin(), BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) { @@ -189,10 +193,31 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, else Element.SubobjectNumber = Subobjects.second; Paths.ScratchPath.push_back(Element); + + // Calculate the "top-down" access to this base class. + // The spec actually describes this bottom-up, but top-down is + // equivalent because the definition works out as follows: + // 1. Write down the access along each step in the inheritance + // chain, followed by the access of the decl itself. + // For example, in + // class A { public: int foo; }; + // class B : protected A {}; + // class C : public B {}; + // class D : private C {}; + // we would write: + // private public protected public + // 2. If 'private' appears anywhere except far-left, access is denied. + // 3. Otherwise, overall access is determined by the most restrictive + // access in the sequence. + if (IsFirstStep) + Paths.ScratchPath.Access = BaseSpec->getAccessSpecifier(); + else + Paths.ScratchPath.Access + = MergeAccess(AccessToHere, BaseSpec->getAccessSpecifier()); } if (BaseMatches(BaseSpec, Paths.ScratchPath, UserData)) { - // We've found a path that terminates that this base. + // We've found a path that terminates at this base. FoundPath = true; if (Paths.isRecordingPaths()) { // We have a path. Make a copy of it before moving on. @@ -223,13 +248,18 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches, // Pop this base specifier off the current path (if we're // collecting paths). - if (Paths.isRecordingPaths()) + if (Paths.isRecordingPaths()) { Paths.ScratchPath.pop_back(); + } + // If we set a virtual earlier, and this isn't a path, forget it again. if (SetVirtual && !FoundPath) { Paths.DetectedVirtual = 0; } } + + // Reset the scratch path access. + Paths.ScratchPath.Access = AccessToHere; return FoundPath; } |