diff options
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index a7fd47183a..6bf5f2e3a2 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -24,30 +24,19 @@ using namespace clang; using namespace sema; +typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> BaseSet; +static bool BaseIsNotInSet(const CXXRecordDecl *Base, void *BasesPtr) { + const BaseSet &Bases = *reinterpret_cast<const BaseSet*>(BasesPtr); + return !Bases.count(Base->getCanonicalDecl()); +} + /// Determines if the given class is provably not derived from all of /// the prospective base classes. -static bool IsProvablyNotDerivedFrom(Sema &SemaRef, - CXXRecordDecl *Record, - const llvm::SmallPtrSet<CXXRecordDecl*, 4> &Bases) { - if (Bases.count(Record->getCanonicalDecl())) - return false; - - RecordDecl *RD = Record->getDefinition(); - if (!RD) return false; - Record = cast<CXXRecordDecl>(RD); - - for (CXXRecordDecl::base_class_iterator I = Record->bases_begin(), - E = Record->bases_end(); I != E; ++I) { - CanQualType BaseT = SemaRef.Context.getCanonicalType((*I).getType()); - CanQual<RecordType> BaseRT = BaseT->getAs<RecordType>(); - if (!BaseRT) return false; - - CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl()); - if (!IsProvablyNotDerivedFrom(SemaRef, BaseRecord, Bases)) - return false; - } - - return true; +static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record, + const BaseSet &Bases) { + void *BasesPtr = const_cast<void*>(reinterpret_cast<const void*>(&Bases)); + return BaseIsNotInSet(Record, BasesPtr) && + Record->forallBases(BaseIsNotInSet, BasesPtr); } enum IMAKind { @@ -111,7 +100,7 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, // Collect all the declaring classes of instance members we find. bool hasNonInstance = false; bool isField = false; - llvm::SmallPtrSet<CXXRecordDecl*, 4> Classes; + BaseSet Classes; for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { NamedDecl *D = *I; @@ -169,16 +158,18 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, // is ill-formed. if (R.getNamingClass() && contextClass->getCanonicalDecl() != - R.getNamingClass()->getCanonicalDecl() && - contextClass->isProvablyNotDerivedFrom(R.getNamingClass())) - return hasNonInstance ? IMA_Mixed_Unrelated : - IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context : - IMA_Error_Unrelated; + R.getNamingClass()->getCanonicalDecl()) { + // If the naming class is not the current context, this was a qualified + // member name lookup, and it's sufficient to check that we have the naming + // class as a base class. + Classes.clear(); + Classes.insert(R.getNamingClass()); + } // If we can prove that the current context is unrelated to all the // declaring classes, it can't be an implicit member reference (in // which case it's an error if any of those members are selected). - if (IsProvablyNotDerivedFrom(SemaRef, contextClass, Classes)) + if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes)) return hasNonInstance ? IMA_Mixed_Unrelated : IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context : IMA_Error_Unrelated; @@ -491,14 +482,14 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, const CXXScopeSpec &SS, const LookupResult &R) { - const RecordType *BaseRT = BaseType->getAs<RecordType>(); - if (!BaseRT) { + CXXRecordDecl *BaseRecord = + cast_or_null<CXXRecordDecl>(computeDeclContext(BaseType)); + if (!BaseRecord) { // We can't check this yet because the base type is still // dependent. assert(BaseType->isDependentType()); return false; } - CXXRecordDecl *BaseRecord = cast<CXXRecordDecl>(BaseRT->getDecl()); for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { // If this is an implicit member reference and we find a @@ -513,11 +504,10 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, if (!DC->isRecord()) continue; - - llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord; - MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl()); - if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord)) + CXXRecordDecl *MemberRecord = cast<CXXRecordDecl>(DC)->getCanonicalDecl(); + if (BaseRecord->getCanonicalDecl() == MemberRecord || + !BaseRecord->isProvablyNotDerivedFrom(MemberRecord)) return false; } |